跳转到内容

Kubernetes 与 GPU 调度

云原生时代的 GPU 集群大多长在 Kubernetes 上。但 K8s 原生不理解 GPU:它是为无状态 web 服务设计的,而 GPU 训练要的是独占、整组分配、拓扑感知、长时运行。本章讲清楚 K8s 上跑 GPU 的三层补丁:device plugin(让 K8s 看见 GPU)、拓扑感知调度(让分配对齐 NVLink/IB)、以及调度插件(让大作业整组进)。

K8s 原生假设GPU 训练的真实需要
Pod 是小单位,随意打散训练作业要整组进(gang:8 卡一组,少一张都跑不了)
尽量打散负载(反亲和)尽量聚合(同 NVLink 域、同轨道组)
短生命周期,随时迁移长时运行,绝不能随便重启(见容错)
CPU/内存可超卖GPU 超卖 = 事故(OOM/降速)

三层补丁分别解决这三个错配。

第一层:Device Plugin——让 K8s 看见 GPU

Section titled “第一层:Device Plugin——让 K8s 看见 GPU”

K8s 原生只认 CPU/内存。NVIDIA device plugin 是一个 DaemonSet,负责:

  • 发现每节点的 GPU 数量,注册为扩展资源(nvidia.com/gpu: 8)
  • 容器请求 GPU 时的分配与挂载(device 注入、驱动库挂载)
resources:
limits:
nvidia.com/gpu: 8 # 请求整卡

三个注意点:

  • GPU 是整卡分配的(默认无分片);需要切分(MIG/vGPU)用 MIG device plugin 或 time-slicing(后者是时间片轮转,性能隔离差,慎用于训练)
  • 容器的驱动库:容器内 CUDA 版本与宿主机驱动的兼容(驱动在宿主,CUDA runtime 在容器,向下兼容规则)
  • 健康检查:device plugin 上报 GPU 健康状态(XID 错误),坏卡节点被标记——配合调度器自动排除(见故障)

第二层:拓扑感知调度——对齐 NVLink/IB

Section titled “第二层:拓扑感知调度——对齐 NVLink/IB”

默认调度器不知道卡之间的拓扑:一个 8 卡作业可能被拆到 4 个节点各 2 卡——TP 跨 PCIe,性能崩塌(见节点内互连)。

解法按成熟度:

方案做什么
拓扑感知调度器(Volcano/Kueue/Scheduler-Plugins)按 NVLink/NUMA 域分配,作业的卡尽量同节点
Network-topology aware(K8s 1.31+ 的 NetworkTopology)感知节点间的网络距离(同轨道/同 spine),分配对齐轨道优化
手工对齐大作业按节点数整除的度(TP=8 节点内),绕开调度器

实践原则:TP 度 ≤ 节点内卡数(8),让 TP 永远落在 NVLink 域内——配置正确时调度器的拓扑错误就不再是问题。

第三层:Gang 调度——整组进或整组等

Section titled “第三层:Gang 调度——整组进或整组等”

训练作业的天然属性是 all-or-nothing:8 卡的作业来了 5 个卡位,启动也没用(凑不齐就跑不了,见gang scheduling)。K8s 默认的"逐 Pod 调度"会造成死锁:两个 8 卡作业各拿到 4 卡,互相等对方释放——谁也起不来,卡全占着。

方案机制
VolcanoPodGroup 原语:整组调度,凑不齐就等(不占坑)
Kueue队列 + 配额 + 整组调度,与 Volcano/原生调度器配合
scheduler-plugins 的 gang轻量方案

gang 调度是训练集群的必选项,不是可选项——没有它,多作业共享集群必然出现调度死锁。

# 作业侧(Volcano PodGroup + K8s Job)
spec:
schedulerName: volcano
minMember: 8 # gang:8 个 Pod 齐了才调度
resources: nvidia.com/gpu: 8 per pod
# 集群侧
- device plugin(GPU 可见性 + 健康)
- 拓扑感知(NVLink 域内分配)
- 配额(Kueue quota,见[多租户](/scheduling-cluster/02-policy/multi-tenancy-quota/))

调度层的故障处理与训练框架的容错(见训练容错)是配套的:

  • 训练框架检测到坏节点 → 通知调度器 → 调度器摘除节点、作业缩容重启(elastic)
  • 节点维护(驱动升级等)→ cordon + drain(先封住不接新作业,再迁移)——但训练作业不能随便迁移,维护要排到训练间隙
  • K8s 与 GPU 三重错配:打散 vs 聚合、逐 Pod vs 整组、可迁移 vs 不可重启——三层补丁对应解决。
  • Device plugin 让 K8s 看见 GPU(整卡分配;time-slicing 慎用);健康状态上报是自动排除的基础。
  • 拓扑感知调度对齐 NVLink/轨道;配置正确(TP ≤ 节点内卡数)比调度器调参更根本。
  • Gang 调度是训练集群必选项:没有它,多作业共享必然调度死锁(各拿一半互相等)。
  • 调度层与训练容错衔接:坏节点通知 → 摘除 → 缩容重启;维护排到训练间隙。