安装 NVIDIA GPU Operator#
前提条件#
您已在客户端计算机上安装了
kubectl
和helm
CLI。您可以运行以下命令来安装 Helm CLI
$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 \ && chmod 700 get_helm.sh \ && ./get_helm.sh
Kubernetes 集群中运行 GPU 工作负载的所有工作节点或节点组必须运行相同的操作系统版本才能使用 NVIDIA GPU 驱动程序容器。或者,如果您在节点上预安装了 NVIDIA GPU 驱动程序,则可以运行不同的操作系统。
对于仅运行 CPU 工作负载的工作节点或节点组,节点可以运行任何操作系统,因为 GPU Operator 不会对仅用于 CPU 工作负载的节点执行任何配置或管理。
节点必须配置容器引擎,例如 CRI-O 或 containerd。
如果您的集群使用 Pod 安全准入 (PSA) 来限制 Pod 的行为,请标记 Operator 的命名空间以将强制执行策略设置为特权
$ kubectl create ns gpu-operator $ kubectl label --overwrite ns gpu-operator pod-security.kubernetes.io/enforce=privileged
节点功能发现 (NFD) 是每个节点上 Operator 的依赖项。默认情况下,NFD master 和 worker 由 Operator 自动部署。如果 NFD 已经在集群中运行,则在安装 Operator 时必须禁用部署 NFD。
确定 NFD 是否已在集群中运行的一种方法是检查节点上是否有 NFD 标签
$ kubectl get nodes -o json | jq '.items[].metadata.labels | keys | any(startswith("feature.node.kubernetes.io"))'
如果命令输出为
true
,则 NFD 已在集群中运行。
步骤#
提示
有关在 Red Hat OpenShift Container Platform 上安装的信息,请参阅 OpenShift 上的安装和升级概述。
添加 NVIDIA Helm 存储库
$ helm repo add nvidia https://helm.ngc.nvidia.com/nvidia \ && helm repo update
安装 GPU Operator。
使用默认配置安装 Operator
$ helm install --wait --generate-name \ -n gpu-operator --create-namespace \ nvidia/gpu-operator \ --version=v24.9.2
安装 Operator 并指定配置选项
$ helm install --wait --generate-name \ -n gpu-operator --create-namespace \ nvidia/gpu-operator \ --version=v24.9.2 \ --set <option-name>=<option-value>
常用图表自定义选项#
使用 Helm 图表时,可以使用以下选项。这些选项可以与 --set
一起使用,以便通过 Helm 进行安装。
下表标识了最常用的选项。要查看所有选项,请运行 helm show values nvidia/gpu-operator
。
参数 |
描述 |
默认值 |
---|---|---|
|
设置为 |
|
|
设置为 Pod 可以将 |
|
|
设置为 |
|
|
要添加到所有 GPU Operator 管理的 Pod 的自定义注释映射。 |
|
|
要添加到所有 GPU Operator 管理的 Pod 的自定义标签映射。 |
|
|
将 NVIDIA 设备插件的配置指定为 ConfigMap。 在大多数情况下,此字段是在安装 Operator 后配置的,例如配置 Kubernetes 中的 GPU 时间分片。 |
|
|
默认情况下,Operator 将 NVIDIA 驱动程序作为容器部署在系统上。当在具有预安装驱动程序的系统上使用 Operator 时,将此值设置为 |
|
|
镜像从 NGC 下载。当使用自定义驱动程序镜像时,指定另一个镜像仓库。 |
|
|
控制驱动程序 DaemonSet 是否构建和加载旧版 您可能能够在不启用此选项的情况下使用 GPUDirect RDMA。有关您是否可以使用 DMA-BUF 或是否需要使用旧版 |
|
|
指示 MLNX_OFED (MOFED) 驱动程序是否预安装在主机上。 |
|
|
默认情况下,驱动程序容器在启动活动性探测之前有 |
|
|
设置为 |
|
|
设置为 |
|
|
Operator 支持的 NVIDIA 数据中心驱动程序的版本。 如果您将 |
取决于 Operator 的版本。有关支持的驱动程序的更多信息,请参阅组件矩阵。 |
|
启用对 GDRCopy 的支持。设置为 如果您使用 NVIDIA GPU 驱动程序自定义资源定义,则可以启用 GDRCopy。 |
|
|
当此字段为 |
|
|
控制在受支持的 NVIDIA GPU 上与 MIG 一起使用的策略。选项为 |
|
|
MIG 管理器监视 MIG 几何结构的变化,并根据需要应用重新配置。默认情况下,MIG 管理器仅在具有支持 MIG 的 GPU 的节点上运行(例如 A100)。 |
|
|
将节点功能发现插件部署为 DaemonSet。如果 NFD 已经在集群中运行,请将此变量设置为 |
|
|
安装与保密计算相关的节点功能规则。NFD 使用这些规则来检测 CPU 和 NVIDIA GPU 中的安全功能。当您为保密容器配置 Operator 时,将此变量设置为 |
|
|
将添加到所有 GPU Operator 管理的 Pod 的自定义标签映射。 |
|
|
如果启用,GPU Operator 将部署 |
|
|
指定集群的默认工作负载类型,可以是 如果您计划在集群中运行所有或大多数虚拟机,则设置 |
|
|
默认情况下,Operator 将 NVIDIA 容器工具包( |
|
常用部署场景#
以下常用部署场景和示例命令最适用于裸机主机或具有 GPU 直通的虚拟机。
指定 Operator 命名空间#
Operator 和操作数都安装在同一命名空间中。命名空间是可配置的,并在安装期间指定。例如,要在 nvidia-gpu-operator
命名空间中安装 GPU Operator
$ helm install --wait --generate-name \
-n nvidia-gpu-operator --create-namespace \
nvidia/gpu-operator \
--version=v24.9.2 \
如果您在安装期间未指定命名空间,则所有 GPU Operator 组件都将安装在 default
命名空间中。
阻止在某些节点上安装操作数#
默认情况下,GPU Operator 操作数部署在集群中的所有 GPU 工作节点上。GPU 工作节点通过标签 feature.node.kubernetes.io/pci-10de.present=true
的存在来标识。值 0x10de
是分配给 NVIDIA 的 PCI 供应商 ID。
要禁用操作数部署到 GPU 工作节点,请使用 nvidia.com/gpu.deploy.operands=false
标记节点。
$ kubectl label nodes $NODE nvidia.com/gpu.deploy.operands=false
阻止在某些节点上安装 NVIDIA GPU 驱动程序#
默认情况下,GPU Operator 会在集群中的所有 GPU 工作节点上部署驱动程序。要阻止在 GPU 工作节点上安装驱动程序,请像以下示例命令一样标记节点。
$ kubectl label nodes $NODE nvidia.com/gpu.deploy.driver=false
在 Red Hat Enterprise Linux 上安装#
在这种情况下,请使用在 UBI 8 上构建的 NVIDIA 容器工具包镜像
$ helm install --wait --generate-name \
-n gpu-operator --create-namespace \
nvidia/gpu-operator \
--version=v24.9.2 \
--set toolkit.version=v1.16.1-ubi8
将上述命令中的 v1.16.1
值替换为 NVIDIA GPU Operator 支持的版本。请参阅平台支持页面上的 GPU Operator 组件矩阵。
当在 Kubernetes 中使用 RHEL8 时,SELinux 必须在 permissive 或 enforcing 模式下启用才能与 GPU Operator 一起使用。此外,不支持网络受限环境。
预安装的 NVIDIA GPU 驱动程序#
在这种情况下,NVIDIA GPU 驱动程序已安装在具有 GPU 的工作节点上
$ helm install --wait --generate-name \
-n gpu-operator --create-namespace \
nvidia/gpu-operator \
--version=v24.9.2 \
--set driver.enabled=false
前面的命令阻止 Operator 在集群中的任何节点上安装 GPU 驱动程序。
如果您未指定 driver.enabled=false
参数,并且集群中的节点具有预安装的 GPU 驱动程序,则驱动程序 Pod 中的 init 容器会检测到驱动程序已预安装并标记节点,以便驱动程序 Pod 终止并且不会重新调度到该节点上。Operator 继续启动其他 Pod,例如容器工具包 Pod。
预安装的 NVIDIA GPU 驱动程序和 NVIDIA 容器工具包#
在这种情况下,NVIDIA GPU 驱动程序和 NVIDIA 容器工具包已安装在具有 GPU 的工作节点上。
提示
这种情况适用于运行 NVIDIA Base OS 的 NVIDIA DGX 系统。
在安装 Operator 之前,请确保默认运行时设置为 nvidia
。有关更多信息,请参阅 NVIDIA 容器工具包文档中的 配置。
使用以下选项安装 Operator
$ helm install --wait --generate-name \
-n gpu-operator --create-namespace \
nvidia/gpu-operator \
--version=v24.9.2 \
--set driver.enabled=false \
--set toolkit.enabled=false
预安装的 NVIDIA 容器工具包(但没有驱动程序)#
在这种情况下,NVIDIA 容器工具包已安装在具有 GPU 的工作节点上。
配置工具包以使用驱动程序安装的
root
目录作为/run/nvidia/driver
,因为这是驱动程序容器挂载的路径。$ sudo sed -i 's/^#root/root/' /etc/nvidia-container-runtime/config.toml
使用以下选项安装 Operator(这将 provision 驱动程序)
$ helm install --wait --generate-name \ -n gpu-operator --create-namespace \ nvidia/gpu-operator \ --version=v24.9.2 \ --set toolkit.enabled=false
运行自定义驱动程序镜像#
如果您想使用自定义驱动程序容器镜像,例如 465.27 版本,则可以构建自定义驱动程序容器镜像。请按照以下步骤操作
通过在构建 Docker 镜像时指定
$DRIVER_VERSION
参数来重建驱动程序容器。作为参考,驱动程序容器 Dockerfile 可在 Git 存储库 nvidia/container-images/driver 上找到。使用相应的 Dockerfile 构建容器。例如
$ docker build --pull -t \ --build-arg DRIVER_VERSION=455.28 \ nvidia/driver:455.28-ubuntu20.04 \ --file Dockerfile .
确保驱动程序容器按示例所示进行标记,方法是使用
driver:<version>-<os>
模式。通过覆盖 Helm 安装命令中的默认值来指定新的驱动程序镜像和仓库。例如
$ helm install --wait --generate-name \ -n gpu-operator --create-namespace \ nvidia/gpu-operator \ --version=v24.9.2 \ --set driver.repository=docker.io/nvidia \ --set driver.version="465.27"
提供这些说明仅供参考和评估。不使用 NVIDIA 提供的 GPU Operator 标准版本意味着对此类自定义配置的支持有限。
指定 containerd 的配置选项#
当您使用 containerd 作为容器运行时时,以下配置选项与通过 GPU Operator 部署的容器工具包一起使用
toolkit:
env:
- name: CONTAINERD_CONFIG
value: /etc/containerd/config.toml
- name: CONTAINERD_SOCKET
value: /run/containerd/containerd.sock
- name: CONTAINERD_RUNTIME_CLASS
value: nvidia
- name: CONTAINERD_SET_AS_DEFAULT
value: true
如果您需要指定自定义值,请参阅以下示例命令以了解语法
helm install gpu-operator -n gpu-operator --create-namespace \
nvidia/gpu-operator $HELM_OPTIONS \
--version=v24.9.2 \
--set toolkit.env[0].name=CONTAINERD_CONFIG \
--set toolkit.env[0].value=/etc/containerd/config.toml \
--set toolkit.env[1].name=CONTAINERD_SOCKET \
--set toolkit.env[1].value=/run/containerd/containerd.sock \
--set toolkit.env[2].name=CONTAINERD_RUNTIME_CLASS \
--set toolkit.env[2].value=nvidia \
--set toolkit.env[3].name=CONTAINERD_SET_AS_DEFAULT \
--set-string toolkit.env[3].value=true
这些选项定义如下
- CONTAINERD_CONFIG
主机上
containerd
配置的路径,您希望使用对nvidia-container-runtime
的支持进行更新。默认情况下,这将指向/etc/containerd/config.toml
(containerd
的默认位置)。如果您的containerd
安装不在默认位置,则应自定义它。- CONTAINERD_SOCKET
主机上用于与
containerd
通信的套接字文件的路径。Operator 将使用它向containerd
守护程序发送SIGHUP
信号以重新加载其配置。默认情况下,这将指向/run/containerd/containerd.sock
(containerd
的默认位置)。如果您的containerd
安装不在默认位置,则应自定义它。- CONTAINERD_RUNTIME_CLASS
您希望与
nvidia-container-runtime
关联的 运行时类 的名称。使用runtimeClassName
等于 CONTAINERD_RUNTIME_CLASS 启动的 Pod 将始终使用nvidia-container-runtime
运行。默认的 CONTAINERD_RUNTIME_CLASS 是nvidia
。- CONTAINERD_SET_AS_DEFAULT
一个标志,指示您是否要将
nvidia-container-runtime
设置为用于启动所有容器的默认运行时。设置为 false 时,只有runtimeClassName
等于 CONTAINERD_RUNTIME_CLASS 的 Pod 中的容器才会使用nvidia-container-runtime
运行。默认值为true
。
Rancher Kubernetes Engine 2#
对于 Rancher Kubernetes Engine 2 (RKE2),请参阅 RKE2 文档中的 部署 NVIDIA Operator。
请参阅 已知限制。
MicroK8s#
对于 MicroK8s,请在 ClusterPolicy
中设置以下内容。
toolkit:
env:
- name: CONTAINERD_CONFIG
value: /var/snap/microk8s/current/args/containerd-template.toml
- name: CONTAINERD_SOCKET
value: /var/snap/microk8s/common/run/containerd.sock
- name: CONTAINERD_RUNTIME_CLASS
value: nvidia
- name: CONTAINERD_SET_AS_DEFAULT
value: "true"
这些选项可以在安装时传递给 GPU Operator,如下所示。
helm install gpu-operator -n gpu-operator --create-namespace \
nvidia/gpu-operator $HELM_OPTIONS \
--version=v24.9.2 \
--set toolkit.env[0].name=CONTAINERD_CONFIG \
--set toolkit.env[0].value=/var/snap/microk8s/current/args/containerd-template.toml \
--set toolkit.env[1].name=CONTAINERD_SOCKET \
--set toolkit.env[1].value=/var/snap/microk8s/common/run/containerd.sock \
--set toolkit.env[2].name=CONTAINERD_RUNTIME_CLASS \
--set toolkit.env[2].value=nvidia \
--set toolkit.env[3].name=CONTAINERD_SET_AS_DEFAULT \
--set-string toolkit.env[3].value=true
验证:运行示例 GPU 应用程序#
CUDA VectorAdd#
在第一个示例中,让我们运行一个简单的 CUDA 示例,它将两个向量相加
创建一个文件,例如
cuda-vectoradd.yaml
,内容如下apiVersion: v1 kind: Pod metadata: name: cuda-vectoradd spec: restartPolicy: OnFailure containers: - name: cuda-vectoradd image: "nvcr.io/nvidia/k8s/cuda-sample:vectoradd-cuda11.7.1-ubuntu20.04" resources: limits: nvidia.com/gpu: 1
运行 Pod
$ kubectl apply -f cuda-vectoradd.yaml
Pod 启动,运行
vectorAdd
命令,然后退出。查看容器的日志
$ kubectl logs pod/cuda-vectoradd
示例输出
[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
删除已停止的 Pod
$ kubectl delete -f cuda-vectoradd.yaml
示例输出
pod "cuda-vectoradd" deleted
Jupyter Notebook#
您可以执行以下步骤在集群中部署 Jupyter Notebook
创建一个文件,例如
tf-notebook.yaml
,内容如下例所示--- apiVersion: v1 kind: Service metadata: name: tf-notebook labels: app: tf-notebook spec: type: NodePort ports: - port: 80 name: http targetPort: 8888 nodePort: 30001 selector: app: tf-notebook --- apiVersion: v1 kind: Pod metadata: name: tf-notebook labels: app: tf-notebook spec: securityContext: fsGroup: 0 containers: - name: tf-notebook image: tensorflow/tensorflow:latest-gpu-jupyter resources: limits: nvidia.com/gpu: 1 ports: - containerPort: 8888 name: notebook
应用清单以部署 Pod 并启动服务
$ kubectl apply -f tf-notebook.yaml
检查 Pod 状态
$ kubectl get pod tf-notebook
示例输出
NAMESPACE NAME READY STATUS RESTARTS AGE default tf-notebook 1/1 Running 0 3m45s
由于清单包含服务,请获取 Notebook 的外部端口
$ kubectl get svc tf-notebook
示例输出
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE tf-notebook NodePort 10.106.229.20 <none> 80:30001/TCP 4m41s
获取 Jupyter Notebook 的令牌
$ kubectl logs tf-notebook
示例输出
[I 21:50:23.188 NotebookApp] Writing notebook server cookie secret to /root/.local/share/jupyter/runtime/notebook_cookie_secret [I 21:50:23.390 NotebookApp] Serving notebooks from local directory: /tf [I 21:50:23.391 NotebookApp] The Jupyter Notebook is running at: [I 21:50:23.391 NotebookApp] http://tf-notebook:8888/?token=3660c9ee9b225458faaf853200bc512ff2206f635ab2b1d9 [I 21:50:23.391 NotebookApp] or http://127.0.0.1:8888/?token=3660c9ee9b225458faaf853200bc512ff2206f635ab2b1d9 [I 21:50:23.391 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation). [C 21:50:23.394 NotebookApp] To access the notebook, open this file in a browser: file:///root/.local/share/jupyter/runtime/nbserver-1-open.html Or copy and paste one of these URLs: http://tf-notebook:8888/?token=3660c9ee9b225458faaf853200bc512ff2206f635ab2b1d9 or http://127.0.0.1:8888/?token=3660c9ee9b225458faaf853200bc512ff2206f635ab2b1d9
现在应该可以从您的浏览器通过此 URL 访问 Notebook:http://your-machine-ip:30001/?token=3660c9ee9b225458faaf853200bc512ff2206f635ab2b1d9。
在商业支持的 Kubernetes 平台上安装#
产品 |
文档 |
---|---|
Red Hat OpenShift 4
使用 RHCOS 工作节点
|
|
VMware vSphere with Tanzu
和 NVIDIA AI 企业版
|
|
Google Cloud Anthos |