Kubernetes GPU 节点排查:从调度失败到显存泄漏

设备插件、驱动与容器运行时决定 GPU 工作负载能否运行。按节点资源、插件日志、驱动状态与显存占用逐层定位调度失败和显存泄漏。

文章目录 · 6 节

GPU Pod 起不来,最常见的原因不是调度器,而是节点上的设备插件、驱动或显存状态出了问题。先确认节点是否「看得到」GPU,再往下查插件、驱动和运行时。

先看节点与调度

kubectl describe node gpu-node-01 | grep -A 12 'Allocatable'
kubectl get ds -n kube-system nvidia-device-plugin
kubectl logs -n kube-system ds/nvidia-device-plugin --tail=50

节点 Allocatable 里没有 nvidia.com/gpu,说明设备插件没有成功注册资源。检查 DaemonSet 是否 Running、日志里是否有驱动或设备枚举错误。Pod 一直 Pending 时,先看事件是 Insufficient nvidia.com/gpu(资源不足)还是 node(s) didn't match(污点/标签),方向完全不同。

驱动与容器运行时

nvidia-smi                              # 节点上直接验证驱动与设备
cat /proc/driver/nvidia/version         # 驱动版本
nvidia-container-cli info               # 容器运行时是否识别 GPU

驱动未加载、容器运行时缺少 nvidia-container-toolkit 配置,都会让容器内 nvidia-smi 无输出或设备枚举失败。确认宿主驱动版本与镜像 CUDA 版本兼容,并检查 containerd/CRI 的 runtime 配置中是否启用了 NVIDIA 运行时。

显存问题与泄漏

nvidia-smi                              # 查看整体显存与利用率
nvidia-smi --query-compute-apps=pid,used_memory --format=csv
nvidia-smi dmon -c 30                   # 周期性监控利用率与温度

Pod 反复 OOMKilled 而节点显存显示已用,可能是残留进程未释放显存。找到占用显存的进程后确认归属,必要时重启节点上的 GPU 工作负载;长期泄漏要回到应用侧排查(如 PyTorch 的缓存未释放),并给推理服务设置显存上限。

常见调度失败原因

  • 显存碎片化:单卡显存足够但无法分配连续块,考虑按卡分配而不是按百分比
  • 资源超卖:多个 Pod 声明同一块 GPU 的显存份额,超出物理容量
  • 节点标签与污点:调度器找不到满足 GPU 标签的节点
  • 插件与 kubelet 版本不一致:设备插件上报的资源未被 kubelet 采纳

新路径:DRA

从 Kubernetes 1.34 起,Dynamic Resource Allocation(DRA)正式 GA,官方推荐新 GPU 工作负载评估 DRA 方式:通过 ResourceClaim 声明设备,由 DRA 驱动完成分配,语义更精确。现有 device plugin 模式仍可继续使用,但只维护不演进。

收尾清单

把节点 GPU 数量、显存使用率、插件重启次数纳入监控;对 nvidia.com/gpu 剩余量不足设告警;记录每个 GPU Pod 的显存基线,便于区分正常占用与泄漏。GPU 排障的顺序永远是:节点资源 → 插件 → 驱动 → 运行时 → 应用。