GPU 服务器与 Kubernetes GPU 集群生产运维
GPU 集群的运维对象不只是“显卡”。一条完整的软件链包含固件、内核、驱动、CUDA、容器运行时、设备插件、调度、MIG、RDMA、监控和训练框架。任何一层版本不匹配,都可能表现为 Pod 无法使用 GPU、任务性能下降、GPU 掉卡或节点反复重启。
本文面向自建 GPU 服务器和 Kubernetes GPU 集群,重点讲资产、版本、部署、监控、故障定位和变更治理。
一、先建立GPU资产模型
每块 GPU 至少记录:
- 服务器、机柜和节点名称;
- GPU 型号、数量、显存;
- PCIe 地址和 NUMA 节点;
- 序列号、UUID;
- VBIOS、固件和驱动版本;
- MIG 支持与当前切分模式;
- NVLink/NVSwitch 拓扑;
- RDMA 网卡及亲和关系;
- 保修、温度和功耗上限;
- 所属资源池和业务负责人。
nvidia-smi -L
nvidia-smi -q
nvidia-smi topo -m
lspci -nn | grep -i nvidia
numactl --hardware
节点名和 Kubernetes 资源数量无法替代硬件台账。故障换卡后,GPU UUID、PCIe 拓扑和 MIG 实例都会变化。
二、理解软件栈
业务框架(PyTorch / TensorFlow / 推理服务)
└─ CUDA Runtime / 通信库
└─ NVIDIA Container Toolkit
└─ containerd / CRI
└─ NVIDIA Driver
└─ GPU / NVLink / PCIe / Fabric
Kubernetes 侧还包括:
- NVIDIA Device Plugin;
- GPU Feature Discovery;
- GPU Operator;
- DCGM 与 DCGM Exporter;
- MIG Manager;
- Node Feature Discovery;
- 调度器或队列系统。
排障时要先判断问题发生在宿主机驱动、容器注入、设备发现、调度还是应用框架。
三、版本兼容与升级策略
驱动、CUDA Toolkit 和应用镜像存在兼容关系。不要简单认为“驱动越新越好”。
变更前记录:
nvidia-smi
cat /proc/driver/nvidia/version
containerd --version
kubectl get nodes -o wide
kubectl get pods -A | grep -i nvidia
生产策略:
- 固定驱动和 GPU Operator 版本;
- 维护驱动、CUDA、框架与内核兼容矩阵;
- 建立 GPU 金丝雀节点;
- 先迁移任务并 cordon;
- 升级单节点并跑基准;
- 观察稳定后再滚动;
- 保留已验证的旧驱动安装包和恢复流程。
内核升级可能导致 DKMS 模块重新编译失败,应把 GPU 节点纳入内核补丁变更流程。
四、宿主机健康检查
nvidia-smi
nvidia-smi -q -d TEMPERATURE,POWER,MEMORY,ECC
dmesg -T | grep -Ei 'NVRM|Xid|pcie|aer'
journalctl -k --since '-1 hour' | grep -Ei 'nvidia|xid|pcie'
重点关注:
- GPU 是否全部可见;
- 持久化模式;
- 温度、功耗和降频原因;
- ECC 单比特与双比特错误;
- PCIe 链路宽度和速率;
- 显存使用与残留进程;
- Xid 错误;
- NVLink 状态;
- Fabric Manager 状态。
“nvidia-smi 能执行”不代表节点健康。还需要跑 CUDA 样例、带宽测试和实际业务小任务。
五、GPU Operator生产部署
GPU Operator 可以管理驱动、Container Toolkit、Device Plugin、GPU Feature Discovery、DCGM Exporter 和 MIG Manager,但是否让 Operator 管理宿主机驱动,应结合变更制度决定。
部署前确认:
- 操作系统和内核支持;
- Secure Boot;
- 驱动由系统还是 Operator 管理;
- containerd 配置;
- 代理与镜像仓库;
- GPU 节点污点;
- 是否启用 MIG;
- 监控栈是否已有 Prometheus Operator。
kubectl get pods -n gpu-operator
kubectl get clusterpolicy
kubectl describe node <gpu-node> | grep -A10 -i nvidia
如果宿主机已经安装并受配置管理系统维护驱动,可考虑关闭 Operator 的驱动管理,避免两个系统同时修改驱动。
六、设备发现与调度
传统 Device Plugin 通常以扩展资源形式暴露:
resources:
limits:
nvidia.com/gpu: 1
扩展资源通常是整数,不能像 CPU 那样超卖。调度还应配合:
- 节点标签;
- nodeSelector 或 nodeAffinity;
- taint/toleration;
- PriorityClass;
- Pod 反亲和;
- 拓扑感知;
- 队列和配额。
示例:
kubectl describe node <gpu-node>
kubectl get node <gpu-node> -o jsonpath='{.status.allocatable}'
kubectl get pods -A -o wide --field-selector spec.nodeName=<gpu-node>
不要只看 nvidia.com/gpu 可分配数量,还要考虑显存、GPU 型号、互联拓扑和任务时长。
七、MIG切分与治理
MIG 可将支持的 GPU 切分为隔离实例。它适合中小型推理、开发和多租户场景,但会引入新的容量碎片。
常见策略:
single:节点上的 GPU 采用统一 MIG 形态;mixed:允许混合不同 MIG 配置,灵活但调度和容量管理更复杂。
变更 MIG 形态前:
- cordon 节点;
- 迁移或停止 GPU 工作负载;
- 确认宿主机没有 GPU 客户端;
- 应用 MIG 配置;
- 必要时重启节点;
- 验证 Device Plugin 和资源名称;
- 运行测试任务;
- uncordon。
MIG 重配置可能停止 GPU 客户端,不能在仍有任务运行时直接切换。
八、GPU共享与超卖
除 MIG 外,一些方案支持 time-slicing 或 MPS。必须区分:
- 计算时间共享;
- 显存隔离;
- 故障隔离;
- 性能保证;
- 安全边界。
时间切片不等于显存隔离。一个任务耗尽显存,仍可能影响同卡其他任务。生产资源池应明确哪些节点允许共享、适用哪些业务以及是否提供性能 SLO。
九、DCGM监控体系
DCGM Exporter 可以把 GPU 指标暴露给 Prometheus。建议覆盖:
- GPU 利用率;
- 显存已用和总量;
- 温度;
- 功耗;
- SM、Tensor Core 使用情况;
- PCIe/NVLink 流量;
- ECC 错误;
- Xid 事件;
- 时钟和降频原因;
- MIG 实例利用率。
告警示例:
| 场景 | 建议判断 |
|---|---|
| 高温 | 持续超过设备和机房基线,而不是单点瞬时值 |
| 显存泄漏 | 无业务吞吐但显存长期不释放 |
| 掉卡 | allocatable 下降、Device Plugin异常或 nvidia-smi 丢失设备 |
| ECC | 双比特错误立即升级处理,单比特错误观察趋势 |
| 降频 | 功耗、温度、可靠性限制与性能下降同时出现 |
| 利用率低 | GPU低但CPU、I/O或数据加载繁忙,提示瓶颈不在GPU |
十、Xid错误处理
Xid 是 GPU 驱动记录的错误代码,含义可能涉及应用、显存、PCIe、驱动或硬件。
处理流程:
- 记录时间、节点、GPU UUID、PCIe 地址和 Xid;
- 找到当时运行的 Pod 和进程;
- 保存
nvidia-smi -q、dmesg 和系统日志; - 判断是否为单次应用错误还是重复硬件错误;
- cordon 节点;
- 停止或迁移任务;
- 按厂商建议执行 GPU reset 或节点重启;
- 运行诊断和压力测试;
- 重复出现时更换硬件或升级驱动;
- 更新故障档案。
不要看到 Xid 就立即清空日志并重启,先保留诊断证据。
十一、Pod申请GPU但不可见
排查顺序:
kubectl describe pod -n <namespace> <pod>
kubectl describe node <gpu-node>
kubectl logs -n gpu-operator <device-plugin-pod>
kubectl logs -n gpu-operator <toolkit-pod>
nvidia-smi
常见原因:
- 驱动未加载;
- Container Toolkit 未正确配置 containerd;
- Device Plugin 未运行;
- 节点标签或污点不匹配;
- Pod 未声明 GPU limit;
- MIG 资源名与请求不一致;
- 运行时类配置错误;
- 节点 allocatable 尚未刷新。
可以运行最小 CUDA 验证 Pod,将复杂训练框架问题与基础运行时问题分离。
十二、GPU任务性能低
低利用率不一定是 GPU 故障。按流水线排查:
- 数据读取是否足够快;
- CPU 预处理是否饱和;
- 内存和 NUMA 是否合理;
- PCIe 链路是否降速;
- GPU 间通信是否走正确拓扑;
- RDMA、NCCL 和网络是否正常;
- batch size 是否合理;
- 是否频繁 CPU/GPU 同步;
- 是否发生功耗或温度降频;
- 是否存在同卡竞争。
nvidia-smi dmon
nvidia-smi pmon
nvidia-smi topo -m
numastat
pidstat -u -d 1
训练任务还应记录 NCCL 日志、步耗时和数据加载时间,建立可比较的性能基线。
十三、GPU与NUMA/RDMA
大规模训练中,GPU、CPU、内存和网卡的拓扑会明显影响性能。
应检查:
- GPU 与 RDMA 网卡是否位于相同或邻近 NUMA;
- PCIe 是否经过额外桥接;
- CPU 绑核与内存亲和;
- GPUDirect RDMA 支持;
- IOMMU 和 ACS 配置;
- NVLink/NVSwitch 健康;
- 交换网络无损配置和拥塞。
调度层可以用节点标签和拓扑信息区分资源池,避免把高性能分布式训练调度到互联能力不足的节点。
十四、容量规划
GPU 容量不能只统计卡数。建议同时管理:
- GPU 型号和算力;
- 显存容量;
- MIG 形态;
- 可用时段;
- 队列等待时间;
- 任务成功率;
- 平均利用率和 P95 利用率;
- 训练与推理资源池;
- 故障和维护预留;
- 电力、制冷和机柜承载。
容量决策应观察排队时间、显存需求分布和任务画像。平均 GPU 利用率低,可能是容量碎片或调度不合理,而不是资源过剩。
十五、安全与多租户
- 不给普通业务容器宿主机特权;
- 限制可挂载设备和主机目录;
- 管理 GPU 固件和驱动来源;
- 镜像执行漏洞扫描和签名验证;
- 不在日志中输出模型密钥与训练数据;
- 区分研发、训练和生产推理资源池;
- 对共享 GPU 明确数据残留和隔离风险;
- 审计节点标签、MIG 配置和资源配额变更。
十六、典型故障:升级内核后GPU全部消失
现象
- 节点重启后
nvidia-smi失败; - Device Plugin CrashLoopBackOff;
- Kubernetes 中 GPU allocatable 变为 0。
排查
uname -r
lsmod | grep nvidia
dkms status
journalctl -k -b | grep -Ei 'nvidia|module|signature'
处理
- 保持节点 cordon;
- 检查驱动模块是否为当前内核构建;
- 检查 Secure Boot 模块签名;
- 安装兼容驱动或回到已验证内核;
- 验证
nvidia-smi; - 验证 Container Toolkit 和 Device Plugin;
- 跑 GPU 基准与样例 Pod;
- 观察后再恢复调度。
根因治理是把内核和 GPU 驱动纳入同一变更矩阵,而不是每次启动失败后临时重装。
十七、生产检查清单
资产
- [ ] GPU UUID、PCIe、NUMA、固件和驱动有台账;
- [ ] 驱动、CUDA、框架兼容矩阵已维护;
- [ ] MIG 与共享策略有负责人和变更流程。
运行
- [ ] 宿主机、Device Plugin、Toolkit、DCGM 健康;
- [ ] 温度、功耗、ECC、Xid 和掉卡有告警;
- [ ] GPU、CPU、存储和网络性能有基线;
- [ ] 资源池和调度策略符合业务类型。
变更
- [ ] 先在金丝雀节点验证;
- [ ] 节点逐台 cordon、迁移、升级、验证;
- [ ] MIG 重配置前已停止工作负载;
- [ ] 升级后跑真实业务样例和压力测试;
- [ ] 保留可执行的驱动与内核恢复方案。
参考资料
- NVIDIA GPU Operator
https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/ - NVIDIA GPU Operator with MIG
https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/gpu-operator-mig.html - Kubernetes:Device Plugins
https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/ - NVIDIA DCGM Documentation
https://docs.nvidia.com/datacenter/dcgm/latest/