3、NVIDIA GPU Operator部署:Operator架构、安装步骤、验证GPU节点可用性

好,咱们进入第三章。GPU Operator,这玩意儿说白了就是K8s管理GPU的「总开关」。没有它,你就算把NVIDIA驱动装好了,K8s也认不出GPU。我刚开始接触K8s GPU集群时,就踩过这个坑——驱动装得妥妥的,Pod就是调度不上去,查了半天才发现是Operator没部署。

这一章,我会带你从架构到实战,把GPU Operator的部署讲透。你跟着走一遍,就能让集群里的GPU节点真正「活」起来。

3.1 Operator架构:它到底干了什么?

GPU Operator不是一个大单体,而是一组组件的集合。它的核心思路,是用K8s的Operator模式,把GPU相关的所有底层操作自动化。

核心组件一览:

  • NVIDIA Driver DaemonSet:在每个GPU节点上安装驱动。嗯,你没看错,Operator能帮你自动装驱动。
  • CUDA DaemonSet:提供CUDA运行时环境,容器化部署。
  • MIG Manager:管理MIG(多实例GPU)的分区和配置。
  • DCGM Exporter:采集GPU监控指标,比如温度、显存使用率。
  • GPU Feature Discovery:自动检测节点上的GPU型号、驱动版本、MIG能力。
  • Node Feature Discovery:检测节点硬件特性,给节点打上标签。
  • K8s Device Plugin:这是最关键的,它让K8s知道「这个节点有GPU可用」。

我画了一张架构图,帮你理清这些组件的关系:

GPU Operator 核心架构 GPU Operator Driver DaemonSet CUDA DaemonSet MIG Manager DCGM Exporter GPU Feature Discovery Node Feature Discovery K8s Device Plugin NVIDIA GPU 硬件 Operator 通过 Helm Chart 统一部署,自动编排所有组件 每个组件以 DaemonSet 或 Deployment 形式运行在集群中 Device Plugin 是连接 K8s 与 GPU 硬件的桥梁

你看,这个架构其实很清晰。Operator在最上层统筹全局,中间层是各种功能组件,底层是Device Plugin负责跟K8s调度器通信。我个人习惯把Device Plugin比作「翻译官」——它把GPU的硬件能力翻译成K8s能理解的资源单位。

3.2 安装步骤:从零到一

安装GPU Operator,最推荐的方式是用Helm。为什么?因为Helm Chart把所有的依赖、配置、版本都打包好了,你只需要填几个参数就行。我曾经试过手动部署每个组件,折腾了大半天,后来发现用Helm十分钟搞定。

好,开始动手。

3.2.1 前置条件

  • 一个运行中的K8s集群(版本1.20以上,我建议用1.24+)
  • 节点上有NVIDIA GPU(T4、V100、A100都行)
  • Helm 3已安装
  • 节点上已安装nvidia-docker2或containerd的GPU支持

注意:如果你用的是containerd,记得在配置文件中加上nvidia的runtime。我遇到过好几次,Operator部署成功了,但Pod就是起不来,最后发现是containerd没配置GPU runtime。这个坑,你一定要注意。

3.2.2 添加Helm仓库并安装

# 添加NVIDIA的Helm仓库
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
helm repo update

# 创建命名空间
kubectl create namespace gpu-operator

# 安装GPU Operator
helm install gpu-operator nvidia/gpu-operator \
  --namespace gpu-operator \
  --version v24.3.0 \
  --set driver.enabled=true \
  --set driver.version=535.154.05

这里有几个参数我解释一下:

  • driver.enabled=true:让Operator自动安装驱动。如果你的节点已经装了驱动,可以设为false。
  • driver.version:指定驱动版本。我建议跟你的CUDA版本匹配,不然可能会有兼容性问题。

小技巧:如果你不确定驱动版本,可以先不指定,让Operator自动选择。它会根据节点上的GPU型号和CUDA版本,选一个最合适的。不过我个人习惯手动指定,这样心里有数。

3.2.3 验证安装状态

# 查看Pod状态
kubectl get pods -n gpu-operator

# 你应该会看到类似这样的输出:
# NAME                                       READY   STATUS    RESTARTS   AGE
# gpu-operator-7d8f6b9c4f-abcde              1/1     Running   0          5m
# nvidia-driver-daemonset-xxxxx               1/1     Running   0          5m
# nvidia-container-toolkit-daemonset-yyyy     1/1     Running   0          5m
# nvidia-device-plugin-daemonset-zzzz         1/1     Running   0          5m
# nvidia-dcgm-exporter-xxxx                   1/1     Running   0          5m
# nvidia-mig-manager-xxxx                     1/1     Running   0          5m

嗯,看到所有Pod都是Running状态,说明Operator已经部署成功了。但别急,这还不够,我们还需要验证GPU节点是否真的可用。

3.3 验证GPU节点可用性

这一步很关键。Operator部署成功 ≠ GPU节点可用。我见过太多人卡在这一步——Pod跑起来了,但调度不到GPU。

3.3.1 检查节点标签

# 查看节点是否有GPU相关标签
kubectl describe node <your-gpu-node> | grep -i gpu

# 你应该能看到类似这样的标签:
# nvidia.com/gpu.present=true
# nvidia.com/gpu.count=1
# nvidia.com/gpu.memory=16160
# nvidia.com/gpu.product=Tesla-T4

这些标签是GPU Feature Discovery组件自动打上去的。如果看不到,说明组件没正常工作。我曾经遇到过一种情况:节点上有GPU,但标签就是不出来,最后发现是节点上的OS内核版本太老,跟驱动不兼容。

3.3.2 检查可分配资源

# 查看节点的可分配资源
kubectl describe node <your-gpu-node> | grep -A5 "Capacity"

# 重点关注这一行:
# nvidia.com/gpu:  1

如果看到nvidia.com/gpu出现在Capacity和Allocatable中,说明Device Plugin已经成功注册了GPU资源。这是最直接的验证方式。

3.3.3 运行测试Pod

理论验证完了,咱们跑个实际Pod试试:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: gpu-test-pod
spec:
  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

然后查看日志:

kubectl logs gpu-test-pod

如果看到类似这样的输出,恭喜你,GPU节点验证通过:

+-----------------------------------------------------------------------------+
| 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 / 16160MiB |      0%      Default |
|-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+

避坑指南:如果Pod一直处于Pending状态,用kubectl describe pod gpu-test-pod查看事件。最常见的原因是节点资源不足,或者GPU资源被其他Pod占用了。我曾经遇到过一个问题:节点上有4张GPU,但只有1张被注册到了K8s中,查了半天发现是Device Plugin的配置文件中resourceName写错了。

3.3.4 清理测试Pod

kubectl delete pod gpu-test-pod

3.4 常见问题与排查思路

问题现象 可能原因 排查命令
Pod调度不到GPU节点 节点标签缺失或Device Plugin未注册 kubectl describe node | grep nvidia
Pod启动报错「CUDA driver version insufficient」 驱动版本与CUDA镜像不匹配 nvidia-smi 检查驱动版本
Operator Pod CrashLoopBackOff Helm配置参数错误或节点不满足条件 kubectl logs -n gpu-operator <pod-name>
GPU显存显示为0 MIG模式配置问题 nvidia-smi -q | grep "MIG"

说实话,GPU Operator的部署其实不复杂,但细节很多。你只要按照上面的步骤走一遍,基本不会出大问题。如果真遇到了,也别慌——先看日志,再看事件,最后查配置。我这些年排查GPU相关问题的经验告诉我,90%的问题都出在驱动版本不匹配和配置参数错误上。

好,这一章就到这里。你现在应该能独立部署GPU Operator,并且验证GPU节点的可用性了。下一章,我们会深入vLLM的部署配置,看看怎么让大模型真正跑在GPU上。


专注资料整理