2023年我们开始把AI训练迁移到容器化环境的时候,团队里只有一个人用过Kubernetes。三年下来,踩过的坑比写过的代码还多。有些问题是文档里不会写的——比如"为什么两张A100在同一个Pod里NVLink带宽只有标称值的一半"、"为什么GPU Operator装完nvidia-smi显示正常但训练跑不起来"。

这篇文章不讲基础概念,只讲实际落地中真正遇到的问题和解决思路。如果你正准备把训练环境容器化,或者已经踩在坑里,希望能帮你省点时间。

先想清楚:你真的需要Kubernetes吗

这可能是最反直觉的一条建议。很多团队一上来就搞K8s集群、GPU Operator、Prometheus监控全家桶,结果运维复杂度远超预期。

我们的判断标准很简单:

决策准则:团队<5人且GPU卡数<8张 → Docker Compose就够用。团队>10人或GPU卡数>16张 → 值得上K8s。中间地带看是否有频繁的多机多卡训练需求。

Docker Compose做GPU管理虽然简陋,但胜在出问题能快速定位。K8s出问题时,排查链路可能是:Pod Pending → 看Events → Scheduler日志 → Device Plugin状态 → nvidia-smi → 驱动版本。每一步都可能出岔子。

GPU Operator不是银弹,配置不对照样翻车

NVIDIA GPU Operator确实简化了很多工作,但有几个配置项如果不设对,问题会非常隐蔽:

1. TimeSlicing配置:GPU Operator默认不会开启GPU分片。如果不上MIG(Multi-Instance GPU)或TimeSlicing,每个Pod会独占整张卡,造成严重浪费。我们的做法是推理Pod用TimeSlicing(一张卡切成4份),训练Pod用整卡或MIG。

2. 驱动版本锁定:GPU Operator默认会安装最新驱动,但在生产环境里,CUDA Toolkit版本必须和驱动版本严格匹配。建议在ClusterPolicy里锁定驱动版本:

apiVersion: nvidia.com/v1
kind: ClusterPolicy
spec:
  driver:
    version: "550.90.07" # 锁定版本,不要用latest
    enabled: true

3. MIG配置陷阱:A100的MIG可以把一张卡切成7个实例,但开启MIG后NVLink会被禁用。做分布式训练的话,千万别开MIG——我们为此白费了三天排查时间

训练任务调度:别用默认Scheduler

K8s默认的调度器对GPU任务来说太"粗"了。它只知道节点有没有GPU,但不知道每张卡的显存使用情况、NVLink拓扑、卡间带宽。结果就是:一个需要8卡NVLink全互联的训练任务,可能被调度到跨NUMA节点的卡上,性能直接腰斩。

我们的解决方案是加了两层调度策略:

  • 节点层面:用nodeSelector/nodeAffinity确保训练Pod调度到GPU节点
  • 拓扑层面:通过Topology Manager + GPU Topology Aware Scheduling,确保多卡Pod落在同一个NVSwitch域内

这个优化对多卡训练效果显著。以前8卡分布式训练时,AllReduce通信时间占总时间的35%;优化拓扑感知后降到了12%。

存储:别把训练数据和容器放一起

又是一个踩过大坑的点。Docker的overlay2存储驱动对大量小文件的读写性能很差,而训练数据集恰恰就是"大量小文件"的典型场景。我们早期把ImageNet数据打包进镜像,结果容器启动要5分钟——因为要把几十GB数据从镜像层解压。

现在的标准做法:

  1. 训练数据挂载外部存储(NFS或对象存储)
  2. 代码和配置打进镜像,数据绝不进镜像
  3. 高IO场景(如强化学习的replay buffer)用hostPath或local PV

多租户资源隔离的实用方案

团队大了之后,多个人共享一个GPU集群是必然的。隔离做不好就会出现"A同学的调试任务把B同学训练任务的显存挤爆了"这种问题。

我们用的是一套三层隔离方案:

隔离层级方案效果
GPU显存NVIDIA Device Plugin + 显存限制单个容器不能超过分配的显存
CPU/内存K8s ResourceQuota + LimitRange命名空间级别限制总资源
存储PVC + StorageClass每人独立的持久化存储
网络NetworkPolicy训练Pod之间通信隔离

这套方案跑了一年多,稳定性和隔离性都够用。唯一的小问题是显存限制只能做"硬限制",无法做"软限制"——即Pod不用那么多显存时,其他Pod也用不了。这需要GPU分时复用方案来解决,目前行业里还在探索阶段。


监控:这4个指标比GPU利用率更重要

大多数人只看GPU利用率,但真正反映问题的指标是这些:

  • GPU显存带宽利用率:如果这个值低于60%,说明数据加载是瓶颈
  • NVLink带宽利用率:多卡训练的核心指标,低于80%就要检查拓扑
  • GPU温度:持续超过80℃会触发降频,直接影响训练速度
  • PCIe吞吐:CPU到GPU的数据搬运速度,小模型训练时经常是瓶颈

我们用DCGM(Data Center GPU Manager)+ Prometheus + Grafana搭了一套GPU监控,重点就是盯这几个指标。

容器化的本质是让算力像水龙头一样用

最后说个理念层面的东西。容器化的最终目的不是"用上Docker和K8s",而是让算力资源能够按需分配、动态调度、即停即走。如果一个团队成员还在因为"环境装不上"而等半天,那容器化就没做透。

对于不想自己折腾集群的团队,直接用成熟的云GPU容器服务是个更现实的选择——底层调度和运维交给平台,团队把精力放在模型上。极智算这类平台提供的容器化GPU服务,从环境搭建到任务调度都封装好了,对于10人以下的小团队来说,省下的运维时间可能比省下的GPU租赁费还值钱。

不用自己搭集群,开箱即用的GPU容器环境

查看容器化GPU方案 →