这次记录一个云上 K8s GPU 节点的问题。业务侧提交了一个模型评测 Job,Pod 已经被分配到 GPU 节点,但一直没有进入 Running,事件显示 ImagePullBackOff。
环境特征:
- Kubernetes v1.36 测试集群
- containerd 运行时
- GPU 节点池
- Job 里包含 vLLM worker 和监控 sidecar
1. 先看事件
kubectl get pod -n ai-lab -owide
kubectl describe pod -n ai-lab eval-worker-0
kubectl get events -n ai-lab --sort-by=.lastTimestamp
如果 Pod 已经有目标节点,并且事件是镜像拉取失败,就先不要改 DRA 或 GPU 资源声明。这里是节点运行时没有把镜像准备好。
2. 在目标节点用 crictl 验证
sudo crictl ps -a | grep eval-worker
sudo crictl pull docker.1ms.run/vllm/vllm-openai:latest
sudo crictl pull nvcr.1ms.run/nvidia/cuda:12.4.1-runtime-ubuntu22.04
sudo crictl pull quay.1ms.run/prometheus/node-exporter:v1.8.2
如果这里也失败,说明不是 Kubernetes YAML 的问题。继续查节点 DNS、出网策略、containerd mirror 配置和镜像前缀。
3. 检查 containerd 日志
sudo journalctl -u containerd --since "20 min ago" --no-pager
sudo crictl info | jq '.config'
sudo ctr -n k8s.io images ls | grep -E 'vllm|cuda|node-exporter'
我会重点看三类信息:
- 是否有 DNS 解析失败。
- 是否有连接超时。
- 是否镜像已经存在但 tag 引用不一致。
4. 再看 DRA 和 PodGroup
如果镜像已经拉通,但 Pod 仍然没有进入运行阶段,再回到资源层:
kubectl get podgroup -n ai-lab
kubectl describe podgroup -n ai-lab eval-workers-pg
kubectl describe pod -n ai-lab eval-worker-0 | grep -A20 Events
Kubernetes v1.36 里工作负载感知调度和 DRA 的组合更适合 AI/ML 任务,但测试时要把两类问题分开:资源分配问题看 PodGroup、ResourceClaim、拓扑约束;镜像问题看 containerd 和目标节点。
5. 验证容器内设备和模型目录
镜像问题排掉后,再进入业务启动:
kubectl exec -n ai-lab eval-worker-0 -- nvidia-smi
kubectl exec -n ai-lab eval-worker-0 -- ls -lh /models
kubectl logs -n ai-lab eval-worker-0 --tail=100
如果 GPU 不可见,再检查 GPU Operator、驱动、runtime class。
如果模型目录不可见,再检查 PVC、挂载路径和权限。
如果探针失败,再检查服务端口和 readinessProbe。
复盘
这类问题最容易混在一起:K8s 版本升级、DRA、GPU 节点、模型服务、大镜像,全部都在同一个故障现场。但真正排查时要分层:
- Pod 没分配节点,查调度。
- Pod 分配了节点但拉不下镜像,查运行时和镜像入口。
- 镜像拉通但容器启动失败,查设备、模型目录和业务日志。
对云上 GPU 节点来说,发布前做一轮 crictl pull 预检很有价值。它不能替代调度和业务测试,但能提前排掉很多启动前的变量。