GPU 别再被“抢着用”了:聊聊 K8s 上 AI 任务的调度与隔离那点事
这两年只要你公司一搞 AI,运维就很容易陷入一种状态:
白天看 GPU 利用率,晚上做 GPU 的梦。
你会发现一个很现实的问题:
GPU 明明很贵,但就是用不好。
- 有的 Pod 一把占满 8 张卡
- 有的训练任务跑着跑着把别人挤死
- 有的 GPU 100% 显存,算力却只有 20%
- 老板问:
👉 “这卡一天烧几千块,真值吗?”
如果你也有类似的经历,那今天这篇文章,基本就是给你写的。
一、先说句大实话:GPU 在 K8s 里,从来就不是“一等公民”
CPU / Memory 在 K8s 里是什么地位?
- 可压缩 / 不可压缩
- Requests / Limits
- CFS 调度
- QoS 等级
而 GPU 呢?
👉 本质上是个“整块资源”
- 不能被 kube-scheduler 原生切
- 不能像 CPU 一样时间片抢占
- 不能像内存一样 swap
所以 K8s 一开始的态度是:
“GPU?我不懂,你自己搞。”
于是,Device Plugin 就登场了。
二、Device Plugin:GPU 能进 K8s 的“通行证”
我一直把 Device Plugin 理解成一句话:
“把物理设备,翻译成 K8s 能听懂的资源。”
NVIDIA Device Plugin 做了什么?
简单拆一下:
- 探测节点上的 GPU
向 kubelet 注册资源:
nvidia.com/gpu- kube-scheduler 看到这个资源
- Pod 通过 requests / limits 申请 GPU
- kubelet 在容器启动时完成设备注入
一个最经典的 GPU Pod 示例
apiVersion: v1
kind: Pod
metadata:
name: gpu-train
spec:
containers:
- name: trainer
image: pytorch/pytorch:latest
resources:
limits:
nvidia.com/gpu: 1
关键点只有一个:
👉 GPU 只能写在
limits,不能写在requests
因为 GPU 不能被超卖。
这套机制解决了什么?
- ✅ GPU 不会被多个 Pod 同时占
- ✅ 调度器知道哪台机器还有卡
- ✅ 运维终于不用靠“人肉记忆”卡在哪
但注意,这只是“能用”,离“好用”还差得远。
三、问题来了:一张 GPU,真的只能一个任务用吗?
这是我最常被问的一句:
“Echo,GPU 能不能像 CPU 一样分着用?”
答案是:
能,但 K8s 不原生支持,需要 NVIDIA 帮你兜底。
四、GPU 隔离的三种境界(非常真实)
第一层:整卡独占(最简单,也最浪费)
- 一 Pod = 一 GPU
- 适合大模型训练
问题是:
- 推理任务太浪费
- 小模型“杀鸡用牛刀”
第二层:MIG(硬隔离,强推荐)
如果你用的是 A100 / H100:
- MIG(Multi-Instance GPU)
一张卡切成:
- 1g.5gb
- 2g.10gb
- 7g.40gb
👉 这是“真隔离”,不是时间片
K8s 里表现为:
nvidia.com/mig-1g.5gb
nvidia.com/mig-2g.10gb
Pod 示例:
resources:
limits:
nvidia.com/mig-1g.5gb: 1
我个人评价一句:
MIG 是目前最“像 CPU 的 GPU”。
第三层:时间片 / 共享(高级玩法,风险也高)
- CUDA MPS
- GPU Time Slicing
- 适合推理高并发
但说句良心话:
👉 共享 GPU = 运维背锅概率直线上升
性能抖动、OOM、不可预测,是家常便饭。
五、NVIDIA DCGM:GPU 世界的“Node Exporter”
说完“能调度、能隔离”,我们聊点运维最关心的:
“这 GPU 到底用得咋样?”
这时候,DCGM(Data Center GPU Manager) 就必须登场了。
DCGM 解决的不是“能不能用”,而是“用得好不好”
它能给你什么?
- GPU 利用率
- 显存占用
- Tensor Core 使用率
- PCIe 带宽
- 温度 / 功耗
- ECC 错误
👉 一句话:GPU 的体检报告
DCGM + K8s + Prometheus 的经典组合
部署 DCGM Exporter 后,你会看到类似指标:
DCGM_FI_DEV_GPU_UTIL
DCGM_FI_DEV_FB_USED
DCGM_FI_DEV_POWER_USAGE
然后你就可以:
- 做 Grafana 大盘
- 给 GPU 过热报警
- 找出“占着卡不干活”的作业
六、调度才是灵魂:别让 GPU 看“运气”
很多团队 GPU 用不好,不是卡的问题,是调度策略太佛系。
1️⃣ 节点分池(非常重要)
- gpu-train-node
- gpu-infer-node
- gpu-mig-node
配合:
nodeSelector:
gpu-type: train
👉 别让训练和推理混在一起打架
2️⃣ 用好 Taint / Toleration
tolerations:
- key: "gpu"
operator: "Exists"
effect: "NoSchedule"
GPU 节点不是公共厕所,
不是谁想上就能上。
3️⃣ 调度 ≠ 公平,调度是“业务优先级的体现”
- 离线训练:可以等
- 在线推理:不能抖
- Demo 项目:别来抢卡
👉 PriorityClass 一定要用
七、我个人的一点感受(很真实)
做 GPU 运维这几年,我最大的感触是:
GPU 管理,本质上是“组织管理问题”,不是技术问题。
- 技术能解决 60%
剩下 40% 是:
- 谁能用
- 谁先用
- 谁为浪费买单
K8s + Device Plugin + DCGM
只是帮你把“账算清楚”。
真正决定 GPU 效率的,是:
- 调度策略
- 资源边界
- 团队共识
八、最后一句话
GPU 贵不可怕,可怕的是贵,还用得一塌糊涂。
如果你正在:
- 搭 AI 平台
- 管 GPU 集群
- 被 GPU 利用率折磨
那请记住一句话:
先让 GPU 进 K8s,
再让 GPU 被隔离,
最后让 GPU 被看清。