AI训练容器化实践:Docker+K8s GPU集群搭建指南_极智算
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里锁定驱动版本:
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数据从镜像层解压。
现在的标准做法:
- 训练数据挂载外部存储(NFS或对象存储)
- 代码和配置打进镜像,数据绝不进镜像
- 高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方案 →