3. NVIDIA GPU Operator部署:安装、配置RuntimeClass与验证可调度性
好,咱们进入实战环节。
上一章我们把Kubernetes集群搭好了,GPU驱动也装上了。但说实话,那只是万里长征第一步。你想想看,如果每次部署一个需要GPU的Pod,都得手动去配驱动版本、配容器运行时、配设备插件……那运维同学怕是要疯掉。
NVIDIA GPU Operator就是来解决这个问题的。它把GPU相关的所有组件——驱动、运行时、设备插件、监控——全都打包成Kubernetes原生资源,一键部署,自动管理。
我个人习惯在生产环境里优先用Operator,而不是手动拼凑组件。为什么?因为升级、回滚、扩缩容,Operator都能帮你搞定,省心太多。
3.1 什么是NVIDIA GPU Operator
说白了,GPU Operator就是一个Kubernetes的Operator,它负责管理GPU集群的整个生命周期。
它包含以下几个核心组件:
- GPU Driver:自动在节点上安装NVIDIA驱动
- CUDA Runtime:提供容器内CUDA运行环境
- NVIDIA Container Toolkit:让容器能访问GPU设备
- Kubernetes Device Plugin:向Kubelet注册GPU资源
- DCGM Exporter:采集GPU监控指标
- MIG Manager:管理MIG(多实例GPU)配置
嗯,这里要注意:GPU Operator不是必须的。你可以手动装驱动、配运行时、部署Device Plugin。但如果你有10台、100台GPU节点,手动维护就是噩梦。Operator的价值就在这里。
核心思路:GPU Operator把GPU资源抽象成Kubernetes的扩展资源,让Pod像申请CPU一样申请GPU。
3.2 安装GPU Operator
安装之前,先确认几个前提条件:
- Kubernetes集群已正常运行(上一章我们搞定了)
- 节点上有NVIDIA GPU(检查一下:
nvidia-smi能跑通) - 节点上不要预装NVIDIA驱动(Operator会帮你装)
- Helm 3已安装(我们用Helm部署Operator)
我曾经踩过一个坑:节点上提前装了驱动,结果Operator检测到驱动版本不一致,直接报错。所以建议让Operator全权管理驱动。
好,开始安装。先添加Helm仓库:
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
helm repo update
然后创建一个命名空间:
kubectl create namespace gpu-operator
接下来,安装GPU Operator。我个人习惯把配置参数写进values文件,方便后续管理:
cat << EOF > gpu-operator-values.yaml
operator:
defaultRuntime: containerd
use_ocp_driver_toolkit: false
driver:
enabled: true
version: "535.154.05"
repoConfig:
configMapName: nvidia-driver-repo-config
toolkit:
enabled: true
devicePlugin:
enabled: true
version: "v0.14.1"
dcgmExporter:
enabled: true
migManager:
enabled: false
EOF
这里有几个关键点:
defaultRuntime: containerd:指定容器运行时。Kubernetes 1.24+默认用containerd,别选错了。driver.version:指定驱动版本。建议选一个经过验证的稳定版本,别追新。migManager.enabled: false:MIG功能默认关掉,需要时再开。
执行安装:
helm install gpu-operator nvidia/gpu-operator \
--namespace gpu-operator \
--values gpu-operator-values.yaml
等几分钟,检查Pod状态:
kubectl get pods -n gpu-operator
你应该能看到类似这样的输出:
NAME READY STATUS RESTARTS AGE
gpu-operator-7f8b9c6d4b-abcde 1/1 Running 0 5m
nvidia-container-toolkit-daemonset-xxxxx 1/1 Running 0 4m
nvidia-dcgm-exporter-xxxxx 1/1 Running 0 4m
nvidia-device-plugin-daemonset-xxxxx 1/1 Running 0 4m
nvidia-driver-daemonset-xxxxx 1/1 Running 0 5m
所有DaemonSet都处于Running状态,说明安装成功。
小技巧:如果驱动安装失败,检查节点上的操作系统版本和内核版本。Operator会下载对应版本的驱动包,如果源里没有,就会卡住。我遇到过CentOS 7.9内核太老,驱动编译不过去的情况。解决办法是升级内核,或者手动指定驱动版本。
3.3 配置RuntimeClass
GPU Operator装好了,但Pod怎么知道要用GPU呢?
这里就需要RuntimeClass了。RuntimeClass告诉容器运行时:这个Pod需要特殊处理,比如挂载GPU设备、设置CUDA环境变量。
检查一下Operator是否自动创建了RuntimeClass:
kubectl get runtimeclass
输出应该包含:
NAME HANDLER AGE
nvidia nvidia 10m
如果没有,可以手动创建。我个人习惯用YAML定义,清晰明了:
cat << EOF | kubectl apply -f -
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: nvidia
handler: nvidia
EOF
这个RuntimeClass的handler名字是nvidia,对应容器运行时里的配置。Operator安装时已经帮我们把containerd的配置改好了,所以直接用就行。
注意:RuntimeClass的名字必须和容器运行时里的handler名字一致。如果你改了handler名字,Pod就找不到对应的运行时了。我曾经手贱改过一次,结果Pod一直Pending,查了半天才发现是名字没对上。
3.4 验证GPU可调度性
组件都就位了,我们来验证一下GPU能不能被调度。
先看看节点上的GPU资源:
kubectl describe node <node-name> | grep -A 10 "Capacity"
你应该能看到类似:
nvidia.com/gpu: 1
nvidia.com/gpu.memory: 8192
nvidia.com/gpu.family: ampere
这说明Device Plugin已经成功注册了GPU资源。
接下来,跑一个测试Pod:
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: gpu-test
spec:
runtimeClassName: nvidia
containers:
- name: cuda-container
image: nvidia/cuda:12.2.0-base-ubuntu22.04
command: ["nvidia-smi"]
resources:
limits:
nvidia.com/gpu: 1
restartPolicy: Never
EOF
注意几个关键点:
runtimeClassName: nvidia:指定使用NVIDIA RuntimeClassresources.limits.nvidia.com/gpu: 1:申请1个GPU- 镜像用
nvidia/cuda,里面自带nvidia-smi
查看Pod日志:
kubectl logs gpu-test
如果输出类似:
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 535.154.05 Driver Version: 535.154.05 CUDA Version: 12.2 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 Tesla T4 Off | 00000000:00:1E.0 Off | 0 |
| N/A 45C P0 28W / 70W | 0MiB / 15360MiB | 0% Default |
|+-------------------------------+----------------------+----------------------+
恭喜!GPU已经可以被Kubernetes调度了。
验证要点:Pod能跑nvidia-smi,说明GPU设备挂载成功、驱动正常、CUDA运行时可用。这是最直接的验证方式。
3.5 常见问题与排查
部署过程中,我遇到过几个典型问题,分享出来供你参考:
| 问题现象 | 可能原因 | 解决办法 |
|---|---|---|
| Pod一直Pending | 节点没有GPU资源,或RuntimeClass未配置 | 检查kubectl describe node是否有nvidia.com/gpu;检查RuntimeClass是否存在 |
| Pod启动报错"cannot find device" | 容器运行时未正确配置NVIDIA runtime | 检查containerd配置中是否包含nvidia runtime;重启containerd |
| nvidia-smi报错"driver not loaded" | 驱动安装失败或版本不匹配 | 查看nvidia-driver-daemonset日志;检查内核版本 |
| GPU Operator Pod CrashLoopBackOff | 配置参数错误或依赖组件缺失 | 查看Operator日志;检查values文件中的参数 |
嗯,这里要特别提一下:如果你用的是Kubernetes 1.27及以上版本,注意检查kubelet的--runtime-request-timeout参数。默认是2分钟,如果驱动安装时间较长,可能会超时。我建议调大到5分钟。
3.6 本章小结
这一章我们完成了三件事:
- 用Helm部署了NVIDIA GPU Operator
- 配置了RuntimeClass,让Pod能使用GPU
- 跑了一个测试Pod,验证了GPU可调度性
说白了,现在你的Kubernetes集群已经具备了GPU调度能力。接下来,我们就可以在这个基础上部署NVSHMEM应用了。
不过,在进入下一章之前,我建议你多做几个实验:试试申请多个GPU、试试不同镜像、试试MIG配置。只有亲手踩过坑,才能真正理解这些组件的工作原理。
个人建议:把GPU Operator的values文件保存到Git仓库里,方便版本管理和回滚。我每次升级Operator之前,都会先备份当前配置,万一出问题能快速恢复。
公众号:蓝海资料掘金营,微信deep3321