Skip to content

2026-05-07 学习日志

主线:TCE + qGPU 工作负载从 0 到跑通

花了一上午 + 中午时间,打通了 TCE(腾讯私有云)上用 qGPU 切片跑 PyTorch 工作负载的完整链路。全程踩了一堆坑,收获不小。

知识点

  • [K8s / GPU] TCE + qGPU 工作负载全流程 —— 涵盖 qGPU 资源声明、namespace label 前置、NVML Unknown Error、Pod 诊断、容器内 GPU 验证、后台运行方案
  • [K8s / Pod] Pod 未就绪三板斧 —— kubectl get po -A | grep -vE "Running\|Completed" + describe + logs
  • [K8s / Node] 污点与容忍度 —— TAINTS: <none> 不需要 tolerations;NoSchedule vs NoExecute vs PreferNoSchedule
  • [K8s / Node] 查看节点 GPU 资源分布 —— describe nodes | grep qgpu,SSH 到 Pod 所在节点才能看到负载

问题与解决

问题 1:Python 脚本跑 Killed

  • 现象python py3-torch-gpu.py 直接返回 Killed,没有任何错误栈
  • 根因:不是语法/GPU 问题,是 OOM Killer 把进程杀了。CPU 模式下 PyTorch + benchmark 峰值内存超过容器 memory limit
  • 诊断dmesg | tailOut of memory: Killed process ...
  • 解决:换用 GPU 模式(GPU 上这模型几乎不吃内存)、或调大容器内存

问题 2:容器内 nvidia-smiFailed to initialize NVML: Unknown Error

  • 现象/dev/nvidia* 设备节点存在、驱动信息能读,但 NVML 初始化失败
  • 根因:NVIDIA Container Toolkit + cgroup 设备白名单被清(宿主机 docker 重启 / daemon-reload 的副作用)
  • 修复优先级
    1. kubectl delete pod <x> 让它重建(最快)
    2. 宿主机 /etc/nvidia-container-runtime/config.tomlno-cgroups = true(根治)
    3. 容器 --privileged 绕过(兜底)

问题 3:Pod 创建出来一直未就绪(0/2)

  • 现象:Deployment 2 desired | 0 available | 2 unavailable,Deployment events 又看不到任何 Warning
  • 根因:namespace test-qwh-gpu 只有默认 label kubernetes.io/metadata.name,TCE 把它识别为 System 类型;qGPU 调度器只对 Tenant ns 生效,所以 Pod 调度通过了但运行时拒绝启动
  • 诊断:对比 gpu-ns(能跑通的)的 yaml,看缺哪些 label
  • 解决
    bash
    kubectl label namespace test-qwh-gpu \
      tke.cloud.tencent.com/qgpu-schedule-policy=fixed-share
    然后删掉 Deployment 重建

问题 4:宿主机 nvidia-smi 看不到负载,以为 GPU 没在跑

  • 现象:在 master tcs-10-29-25-5 上跑 nvidia-smi,两张卡都是 0% / 0MiB
  • 根因:Pod 实际跑在 10.29.25.6 上,不是 10.29.25.5nvidia-smi 只看本机
  • 解决
    bash
    NODE=$(kubectl get pod -n <ns> <pod> -o jsonpath='{.spec.nodeName}')
    ssh $NODE 'nvidia-smi -l 1'
    换到 6 节点一看就是 GPU-Util 26%、温度 48℃、功耗 86W ✅

问题 5:关闭 VNC 脚本就死

  • 现象:前台跑 python gpu_burn.py,VNC 一关进程就没了
  • 根因:VNC 关闭 → shell 退出 → 给子进程发 SIGHUP → Python 默认挂
  • 解决nohup python -u xxx.py > /tmp/log 2>&1 & + disown 四件套
  • 更优tmux new -s gpuCtrl+B D 脱离,下次 tmux attach -t gpu 接回

今日总结

最深的体会是 K8s + GPU 的排障要分层看:

  • K8s 层(调度)→ kubectl get/describe/logs + 事件对照表
  • 容器运行时层(cgroup、NVIDIA Toolkit)→ ls /dev/nvidia*/proc/driver/nvidia/version
  • 驱动/硬件层(NVML、CUDA 版本)→ 宿主机 nvidia-smi + 驱动文件检查
  • 应用层(PyTorch)→ torch.cuda.is_available() + 实际跑计算

每一层都可能掉链子,而且错误信号不一定指向真正的根因(比如 Pod "未就绪"实际是 ns label 问题,nvidia-smi Unknown Error 实际是 cgroup 问题)。对比法最好用——找一个能跑通的参照对象(比如 gpu-ns)和出问题的对比,差异就是线索。

另外关于 qGPU:它是腾讯 TKE 自研的 GPU 切片方案,和 K8s 标准 nvidia.com/gpu device plugin 是两套独立资源,声明、调度、前置条件都不一样。namespace label → qgpu-operator → 节点资源汇报 → Pod 能用,这个链条缺任何一环 Pod 都起不来。


技术栈:K8s · TCE · qGPU · PyTorch · V100 · NVIDIA Container Toolkit

持续学习,每天进步 🚀