在過去的幾年里, NVIDIA 以各種方式利用 GPU 容器來測試、開發(fā)和大規(guī)模運(yùn)行生產(chǎn)中的 AI 工作負(fù)載。為 NVIDIA GPUs 優(yōu)化的容器和 DGX 和 OEM NGC Ready 服務(wù)器等系統(tǒng)可作為 NGC 的一部分提供。
但是用 GPUs 可靠地提供服務(wù)器并擴(kuò)展人工智能應(yīng)用程序可能會很棘手。 Kubernetes 憑借其豐富的應(yīng)用程序可擴(kuò)展性和高性能特性迅速構(gòu)建在其平臺上。
Kubernetes 通過設(shè)備插件 框架 提供對特殊硬件資源的訪問,如 NVIDIA GPUs 、 NICs 、 Infiniband 適配器和其他設(shè)備。但是,使用這些硬件資源配置和管理節(jié)點(diǎn)需要配置多個軟件組件,例如驅(qū)動程序、容器運(yùn)行時或其他庫,這些組件很難并且容易出錯。
Kubernetes 中的 運(yùn)營商框架 采用操作業(yè)務(wù)邏輯,并允許使用標(biāo)準(zhǔn)的 Kubernetes API 和 kubectl 創(chuàng)建用于在 Kubernetes 內(nèi)部署應(yīng)用程序的自動化框架。這里介紹的 NVIDIA GPU 操作程序基于操作員框架,并自動管理所有 NVIDIA 軟件在 Kubernetes 中提供 GPUs 所需的組件。 NVIDIA 、 redhat 和社區(qū)中的其他人合作創(chuàng)建了 GPU 操作符。 GPU 運(yùn)營商是 NVIDIA EGX 軟件定義平臺的一個重要組成部分,該平臺旨在使大規(guī)模混合云和邊緣操作成為可能和高效。
NVIDIA GPU 操作員
要在 Kubernetes 集群中配置 GPU 個工作節(jié)點(diǎn),需要以下 NVIDIA 軟件組件 – 驅(qū)動程序、容器運(yùn)行時、設(shè)備插件和監(jiān)控。如圖 1 所示,這些組件需要在集群可用的 GPU 資源之前手動配置,并且在集群運(yùn)行期間也需要進(jìn)行管理。 GPU 運(yùn)營商通過將所有組件打包并使用標(biāo)準(zhǔn) Kubernetes api 自動化和管理這些組件(包括版本控制和升級),簡化了組件的初始部署和管理。 GPU 操作符是完全開源的,可以在我們的 GitHub 庫 上使用。
圖 1 手動安裝(某些組件需要安裝在裸金屬上)與 GPU 操作員使用全集裝箱化組件進(jìn)行自動化的對比
操作員狀態(tài)機(jī)
GPU 運(yùn)算符基于 Kubernetes 中的 運(yùn)營商框架 。操作符被構(gòu)建為一個新的自定義資源定義( CRD ) API ,并帶有相應(yīng)的控制器。該操作符在自己的命名空間(稱為“ GPU -operator ”)中運(yùn)行,底層的 NVIDIA 組件在單獨(dú)的命名空間中編排(稱為“ GPU -operator resources ”)。與 Kubernetes 中的任何標(biāo)準(zhǔn)操作符一樣,控制器監(jiān)視名稱空間的更改,并使用協(xié)調(diào)循環(huán)(通過 reconcile ()函數(shù))來實(shí)現(xiàn)一個簡單的狀態(tài)機(jī)來啟動每個 NVIDIA 組件。狀態(tài)機(jī)在每個狀態(tài)下都包含一個驗(yàn)證步驟,如果失敗,協(xié)調(diào)循環(huán)將退出并返回錯誤。如圖 2 所示。
圖 2 GPU 操作員狀態(tài)機(jī)
GPU 運(yùn)算符應(yīng)該在配備了 GPUs 的節(jié)點(diǎn)上運(yùn)行。為了確定哪些節(jié)點(diǎn)具有 GPUs ,操作符依賴于 Kubernetes 中的 節(jié)點(diǎn)功能發(fā)現(xiàn) ( NFD )。 NFD worker 檢測節(jié)點(diǎn)上的各種硬件功能–例如, PCIe 設(shè)備標(biāo)識、內(nèi)核版本、內(nèi)存和其他屬性。然后它使用節(jié)點(diǎn)標(biāo)簽向 Kubernetes 發(fā)布這些特性。然后, GPU 操作員使用這些節(jié)點(diǎn)標(biāo)簽(通過檢查 PCIe 設(shè)備 id )來確定是否應(yīng)在節(jié)點(diǎn)上配置 NVIDIA 軟件組件。在這個初始版本中, GPU 操作員當(dāng)前部署了 NVIDIA 容器運(yùn)行時 、 NVIDIA 集裝箱驅(qū)動程序 和 NVIDIA 調(diào)速器設(shè)備插件 。未來,運(yùn)營商還將管理其他組件,如 基于 DCGM 監(jiān)控。
讓我們簡單地看一下不同的狀態(tài)。
狀態(tài)容器工具包
此狀態(tài)將部署一個守護(hù)進(jìn)程,該守護(hù)進(jìn)程通過 容器 在主機(jī)系統(tǒng)上安裝 NVIDIA 容器運(yùn)行時。守護(hù)進(jìn)程使用 NFD 標(biāo)簽中的 PCIe 設(shè)備 id ,僅在具有 GPU 資源的節(jié)點(diǎn)上安裝運(yùn)行時。 PCIe 設(shè)備 id 0x10DE 是 NVIDIA 的供應(yīng)商 id 。
nodeSelector: feature.node.kubernetes.io/pci-10de.present: “true”
狀態(tài)驅(qū)動程序
此狀態(tài)將部署一個帶有容器化的 NVIDIA 驅(qū)動程序的守護(hù)進(jìn)程。您可以閱讀有關(guān)驅(qū)動程序容器 在這里 的更多信息。在啟動時,驅(qū)動程序容器可以構(gòu)建最終的 NVIDIA 內(nèi)核模塊,并將它們加載到主機(jī)上的 Linux 內(nèi)核中,以準(zhǔn)備運(yùn)行 CUDA 應(yīng)用程序并在后臺運(yùn)行。驅(qū)動程序容器包括應(yīng)用程序所需的驅(qū)動程序的用戶模式組件。同樣,守護(hù)進(jìn)程使用 NFD 標(biāo)簽來選擇要在其上部署驅(qū)動程序容器的節(jié)點(diǎn)。
狀態(tài)驅(qū)動程序驗(yàn)證
如上所述,操作員狀態(tài)機(jī)包括驗(yàn)證步驟,以確保組件已成功啟動。操作員調(diào)度一個簡單的 CUDA 工作負(fù)載(在本例中是一個 vectorAdd 示例)。如果應(yīng)用程序運(yùn)行時沒有任何錯誤,則容器狀態(tài)為“成功”。
狀態(tài)設(shè)備插件
此狀態(tài)為 NVIDIA Kubernetes 設(shè)備插件部署守護(hù)進(jìn)程。它將節(jié)點(diǎn)上的 GPUs 列表注冊到 kubelet 中,這樣就可以將 GPUs 分配給 CUDA 個工作負(fù)載。
狀態(tài)設(shè)備插件驗(yàn)證
在這種狀態(tài)下,驗(yàn)證容器請求 Kubernetes 分配 GPU ,并運(yùn)行一個簡單的 CUDA 工作負(fù)載(如上所述),以檢查設(shè)備插件是否注冊了資源列表以及工作負(fù)載是否成功運(yùn)行(即容器狀態(tài)為“ Success ”)。
為了簡化 GPU 操作員本身的部署, NVIDIA 提供了一個舵圖。用戶可以使用驅(qū)動程序自定義的插件版本(值。 yaml )在舵圖上。然后,操作員使用模板值在節(jié)點(diǎn)上提供所需的軟件版本。這為用戶提供了一個參數(shù)化級別。
運(yùn)行 GPU 運(yùn)算符
讓我們快速了解一下如何部署 GPU 操作符并運(yùn)行 CUDA 工作負(fù)載。在這一點(diǎn)上,我們假設(shè)您有一個 Kubernetes 集群在運(yùn)行(即主控制平面可用,工作節(jié)點(diǎn)已經(jīng)加入集群)。為了讓這篇博文更簡單,我們將使用一個運(yùn)行 ubuntu18.04 。 3lts 的 NVIDIA Tesla T4GPU 的單節(jié)點(diǎn) Kubernetes 集群。
GPU 操作符本身并沒有解決 Kubernetes 集群的設(shè)置問題,目前有很多解決方案 可獲得的 可以用于此目的。 NVIDIA 正在與不同的合作伙伴合作,將 GPU 運(yùn)營商整合到他們管理 GPUs 的解決方案中。
讓我們驗(yàn)證一下我們的 Kubernetes 集群(以及帶有 Tiller 的 Helm 設(shè)置)是否可以運(yùn)行。請注意,雖然節(jié)點(diǎn)有一個 GPU ,但節(jié)點(diǎn)上沒有部署 NVIDIA 軟件組件–我們將使用 GPU 操作符來配置組件。
$ sudo kubectl get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-system calico-kube-controllers-6fcc7d5fd6-n2dnt 1/1 Running 0 6m45s kube-system calico-node-77hjv 1/1 Running 0 6m45s kube-system coredns-5c98db65d4-cg6st 1/1 Running 0 7m10s kube-system coredns-5c98db65d4-kfl6v 1/1 Running 0 7m10s kube-system etcd-ip-172-31-5-174 1/1 Running 0 6m5s kube-system kube-apiserver-ip-172-31-5-174 1/1 Running 0 6m11s kube-system kube-controller-manager-ip-172-31-5-174 1/1 Running 0 6m26s kube-system kube-proxy-mbnsg 1/1 Running 0 7m10s kube-system kube-scheduler-ip-172-31-5-174 1/1 Running 0 6m18s kube-system tiller-deploy-8557598fbc-hrrhd 1/1 Running 0 21s
一個單節(jié)點(diǎn) Kubernetes 集群(主節(jié)點(diǎn)未被污染,因此可以運(yùn)行工作負(fù)載)
$ kubectl get nodes NAME STATUS ROLES AGE VERSION ip-172-31-5-174 Ready master 3m2s v1.15.3
我們可以看到節(jié)點(diǎn)有一個 NVIDIA GPU ,但沒有安裝驅(qū)動程序或其他軟件工具。
$ lspci | grep -i nvidia 00:1e.0 3D controller: NVIDIA Corporation Device 1eb8 (rev a1) $ nvidia-smi nvidia-smi: command not found
作為先決條件,讓我們確保在系統(tǒng)上設(shè)置了一些內(nèi)核模塊。這些模塊的 NVIDIA 依賴于某些驅(qū)動程序。
$ sudo modprobe -a i2c_core ipmi_msghandler
現(xiàn)在,讓我們繼續(xù)部署 GPU 操作符。為此,我們將使用 NGC 提供的舵面圖。首先,添加 Helm 回購:
$ helm repo add nvidia https://helm.ngc.nvidia.com/nvidia "nvidia" has been added to your repositories $ helm repo update Hang tight while we grab the latest from your chart repositories... ...Skip local chart repository ...Successfully got an update from the "nvidia" chart repository ...Successfully got an update from the "stable" chart repository Update Complete.
然后用圖表部署操作員
$ helm install --devel nvidia/gpu-operator -n test-operator --wait $ kubectl apply -f https://raw.githubusercontent.com/NVIDIA/gpu-operator/master/manifests/cr/sro_cr_sched_none.yaml specialresource.sro.openshift.io/gpu created
我們可以驗(yàn)證 GPU 操作符是否在它自己的命名空間中運(yùn)行,并且正在監(jiān)視另一個命名空間中的組件。
$ kubectl get pods -n gpu-operator NAME READY STATUS RESTARTS AGE special-resource-operator-7654cd5d88-w5jbf 1/1 Running 0 98s
幾分鐘后, GPU 操作員將部署所有 NVIDIA 軟件組件。輸出還顯示了作為 GPU 操作符狀態(tài)機(jī)一部分運(yùn)行的驗(yàn)證容器。示例 CUDA 容器( vectorAdd )已作為狀態(tài)機(jī)的一部分成功完成。
$ kubectl get pods -n gpu-operator-resources NAME READY STATUS RESTARTS AGE nvidia-container-toolkit-daemonset-wwzfn 1/1 Running 0 3m36s nvidia-device-plugin-daemonset-pwfq7 1/1 Running 0 101s nvidia-device-plugin-validation 0/1 Completed 0 92s nvidia-driver-daemonset-skpn7 1/1 Running 0 3m27s nvidia-driver-validation 0/1 Completed 0 3m $ kubectl -n gpu-operator-resources logs -f nvidia-device-plugin-validation [Vector addition of 50000 elements] Copy input data from the host memory to the CUDA device CUDA kernel launch with 196 blocks of 256 threads Copy output data from the CUDA device to the host memory Test PASSED Done
我們還可以看到 NFD 用不同的屬性標(biāo)記了節(jié)點(diǎn)。已為 NVIDIA GPU 設(shè)置了具有 PCIe 設(shè)備 id 0x10DE 的節(jié)點(diǎn)標(biāo)簽。
$ kubectl -n node-feature-discovery logs -f nfd-worker-zsjsp 2019/10/21 00:46:25 cpu-cpuid.AVX512F = true 2019/10/21 00:46:25 cpu-hardware_multithreading = true 2019/10/21 00:46:25 cpu-cpuid.AVX = true 2019/10/21 00:46:25 cpu-cpuid.AVX512VL = true 2019/10/21 00:46:25 cpu-cpuid.AVX512CD = true 2019/10/21 00:46:25 cpu-cpuid.AVX2 = true 2019/10/21 00:46:25 cpu-cpuid.FMA3 = true 2019/10/21 00:46:25 cpu-cpuid.ADX = true 2019/10/21 00:46:25 cpu-cpuid.AVX512DQ = true 2019/10/21 00:46:25 cpu-cpuid.AESNI = true 2019/10/21 00:46:25 cpu-cpuid.AVX512BW = true 2019/10/21 00:46:25 cpu-cpuid.MPX = true 2019/10/21 00:46:25 kernel-config.NO_HZ = true 2019/10/21 00:46:25 kernel-config.NO_HZ_IDLE = true 2019/10/21 00:46:25 kernel-version.full = 4.15.0-1051-aws 2019/10/21 00:46:25 kernel-version.major = 4 2019/10/21 00:46:25 kernel-version.minor = 15 2019/10/21 00:46:25 kernel-version.revision = 0 2019/10/21 00:46:25 pci-10de.present = true 2019/10/21 00:46:25 pci-1d0f.present = true 2019/10/21 00:46:25 storage-nonrotationaldisk = true 2019/10/21 00:46:25 system-os_release.ID = ubuntu 2019/10/21 00:46:25 system-os_release.VERSION_ID = 18.04 2019/10/21 00:46:25 system-os_release.VERSION_ID.major = 18 2019/10/21 00:46:25 system-os_release.VERSION_ID.minor = 04
讓我們啟動一個 TensorFlow 筆記本。 GitHub repo 上有一個示例清單,讓我們使用它
$ kubectl apply -f https://nvidia.github.io/gpu-operator/notebook-example.yml
一旦 pod 被創(chuàng)建,我們就可以使用令牌在瀏覽器窗口中查看筆記本。
$ kubectl logs -f tf-notebook [C 02:52:44.849 NotebookApp] Copy/paste this URL into your browser when you connect for the first time, to login with a token: http://localhost:8888/?token=b7881f90dfb6c8c5892cff7e8232684f201c846c48da81c9
我們可以使用端口轉(zhuǎn)發(fā)或使用節(jié)點(diǎn)端口 30001 到達(dá)容器。使用上面日志中的 URL 在瀏覽器中打開 Jupyter 筆記本。
$ kubectl port-forward tf-notebook 8888:8888
現(xiàn)在您可以看到 Jupyter 主頁并繼續(xù)您的工作流 – 所有這些都在 Kubernetes 中運(yùn)行,并通過 GPUs 加速!
結(jié)論
如果您有任何問題或意見,請在下面的評論部分留下。對于有關(guān)安裝和使用的技術(shù)問題,我們建議在 GitHub 上提交一個問題。
關(guān)于作者
Pramod Ramarao 是 NVIDIA 加速計算的產(chǎn)品經(jīng)理。他領(lǐng)導(dǎo) CUDA 平臺和數(shù)據(jù)中心軟件的產(chǎn)品管理,包括容器技術(shù)。
審核編輯:郭婷
-
NVIDIA
+關(guān)注
關(guān)注
14文章
4994瀏覽量
103195 -
gpu
+關(guān)注
關(guān)注
28文章
4743瀏覽量
129008 -
CUDA
+關(guān)注
關(guān)注
0文章
121瀏覽量
13641
發(fā)布評論請先 登錄
相關(guān)推薦
評論