4. GPU节点部署与验证

在 Kubernetes 集群中成功接入 GPU 算力,需要完成三个关键步骤:节点标记(让调度器识别 GPU 节点)、设备插件部署(将 GPU 资源注册到 kubelet)、可调度性验证(确认 Pod 能正确申请并使用 GPU)。本章将按照生产环境标准,逐步演示完整流程。

4.1 节点打标:为 GPU 节点添加专用标签

Kubernetes 调度器默认不会将 GPU 工作负载分配到非 GPU 节点。通过为 GPU 节点添加 node-label 和 taint,可以实现精准调度与资源隔离。

4.1.1 添加节点标签

使用 kubectl label 命令为 GPU 节点打上标识标签,推荐使用 accelerator 作为通用键名:

# 为节点 gpu-node-1 添加标签
kubectl label node gpu-node-1 accelerator=nvidia

# 验证标签是否生效
kubectl get node gpu-node-1 --show-labels

4.1.2 设置节点污点(Taint)

为防止非 GPU 工作负载被错误调度到 GPU 节点,建议添加污点:

# 添加污点,效果为 NoSchedule
kubectl taint node gpu-node-1 nvidia.com/gpu=present:NoSchedule

# 查看节点污点状态
kubectl describe node gpu-node-1 | grep Taints
最佳实践:标签与污点配合使用。标签用于调度器选择,污点用于强制隔离。工作负载需在 Pod Spec 中设置对应的 tolerations 才能调度到 GPU 节点。

4.2 部署 NVIDIA Device Plugin

NVIDIA Device Plugin 是 Kubernetes 与 GPU 硬件之间的桥梁。它作为 DaemonSet 运行在每个 GPU 节点上,负责将 GPU 资源注册到 kubelet 的节点状态中。

4.2.1 前置条件检查

在部署 Device Plugin 之前,请确认以下条件已满足:

检查项 验证命令 预期结果
NVIDIA 驱动已安装 nvidia-smi 显示 GPU 型号、驱动版本、显存信息
nvidia-container-toolkit 已安装 which nvidia-container-runtime 返回可执行文件路径
容器运行时已配置 cat /etc/docker/daemon.json 包含 "default-runtime": "nvidia"
kubelet 已启用 DevicePlugins 特性 ps aux | grep kubelet 参数中包含 --feature-gates=DevicePlugins=true

4.2.2 部署 Device Plugin DaemonSet

NVIDIA 官方提供了稳定的 YAML 部署文件。推荐使用 v0.14.0 及以上版本:

# 创建资源对象
kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.14.0/nvidia-device-plugin.yml

# 检查 DaemonSet 运行状态
kubectl get daemonset -n kube-system | grep nvidia

# 查看 Pod 日志,确认注册成功
kubectl logs -n kube-system -l name=nvidia-device-plugin
关键日志输出示例:
2024/01/15 10:23:45 'Starting NVIDIA Device Plugin'
2024/01/15 10:23:46 'Registered device plugin for resource nvidia.com/gpu with kubelet'

4.2.3 验证资源注册

Device Plugin 启动后,kubelet 会更新节点状态。通过以下命令确认 GPU 资源已注册:

# 查看节点可分配资源
kubectl describe node gpu-node-1 | grep -A 5 "Capacity"

# 预期输出示例
Capacity:
  cpu:                32
  memory:             131934848Ki
  nvidia.com/gpu:     4
  pods:               110

4.3 验证 GPU 可调度性

完成节点标记和设备插件部署后,需要通过实际工作负载验证 GPU 能否被正确调度和使用。

4.3.1 创建测试 Pod

使用 NVIDIA 官方提供的 CUDA 示例镜像,申请 1 个 GPU 资源:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: gpu-test-pod
spec:
  nodeSelector:
    accelerator: nvidia
  tolerations:
  - key: nvidia.com/gpu
    operator: Exists
    effect: NoSchedule
  containers:
  - name: cuda-container
    image: nvidia/cuda:12.2.0-base-ubuntu22.04
    command: ["nvidia-smi"]
    resources:
      limits:
        nvidia.com/gpu: 1
EOF

4.3.2 检查 Pod 运行结果

# 查看 Pod 状态
kubectl get pod gpu-test-pod

# 查看 Pod 日志(应包含 nvidia-smi 输出)
kubectl logs gpu-test-pod
常见问题排查:
  • Pod 处于 Pending 状态:检查节点标签、污点容忍、资源是否充足。
  • Pod 处于 CrashLoopBackOff 状态:检查驱动版本与 CUDA 镜像是否兼容。
  • 日志显示 No devices were found:确认 Device Plugin 已正确注册资源。

4.3.3 多 GPU 分配验证

对于需要多 GPU 的工作负载,可以通过调整 nvidia.com/gpu 的 limits 值进行测试:

# 申请 2 个 GPU 的测试 Pod
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: gpu-test-pod-2gpu
spec:
  nodeSelector:
    accelerator: nvidia
  tolerations:
  - key: nvidia.com/gpu
    operator: Exists
    effect: NoSchedule
  containers:
  - name: cuda-container
    image: nvidia/cuda:12.2.0-base-ubuntu22.04
    command: ["nvidia-smi", "--query-gpu=index,name", "--format=csv"]
    resources:
      limits:
        nvidia.com/gpu: 2
EOF

4.4 整体部署流程示意图

下图展示了从节点打标到 GPU 可调度验证的完整流程:

GPU 节点部署与验证流程 步骤 1:节点打标 kubectl label / taint 步骤 2:前置检查 驱动 / 运行时 / 特性门控 步骤 3:部署 Device Plugin kubectl create -f YAML 步骤 4:验证资源注册 kubectl describe node 步骤 5:创建测试 Pod nvidia.com/gpu: 1 步骤 6:检查日志 kubectl logs 判定:GPU 可调度性验证通过 Pod 运行成功,nvidia-smi 输出正常 失败:排查节点标签 / 污点 / 驱动 / 插件 参考常见问题排查清单

4.5 验证清单总结

完成 GPU 节点部署后,建议使用以下清单进行最终确认:

验证项 验证方法 通过标准
节点标签 kubectl get node --show-labels GPU 节点包含 accelerator=nvidia
节点污点 kubectl describe node 存在 nvidia.com/gpu=present:NoSchedule
Device Plugin 运行 kubectl get pods -n kube-system nvidia-device-plugin Pod 状态为 Running
GPU 资源注册 kubectl describe node Capacity 中包含 nvidia.com/gpu
GPU 工作负载调度 创建测试 Pod 并查看日志 Pod 运行成功,nvidia-smi 输出 GPU 信息
生产环境建议:将节点打标和 Device Plugin 部署纳入自动化流程(如 Ansible 或 Terraform),避免手动操作引入配置漂移。同时建议为 GPU 节点配置独立的 PriorityClass,确保 GPU 工作负载在资源竞争时优先调度。