Kubernetes 上 GPU 作业编排:Kueue/Volcano 队列与配额
说明:本篇为综述/无第一手实验数据,采用公开文档与部署实践路线。
实验目标
K8s 默认调度器是"在线服务"思维(Deployment 随时拉起),而训练是"批处理作业"思维(排队、配额、抢占、整卡申请)——直接裸用 K8s 跑训练会到处碰壁。本篇目标:拆解 K8s 上的 GPU 作业编排方案——Kueue/Volcano 的队列模型(为什么需要队列)→ 配额与优先级(多租户)→ 批处理作业与抢占 → 与 SLURM 的对应关系。读完能回答:K8s 上怎么实现"SLURM 式"的训练排队与配额。
代码逐段拆解
第一段:Kueue 队列与配额(推荐起步)
yaml
# Kueue:资源配额以"队列"为单位,作业进队排队
apiVersion: kueue.x-k8s.io/v1beta1
kind: ResourceFlavor
metadata: name: gpu-flavor
spec:
nodeLabels: { cloud.google.com/gke-accelerator: nvidia-h100 } # 节点选择
apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
metadata: name: team-a-cq
spec:
namespaceSelector: { matchLabels: { team: a } }
resources:
- name: nvidia.com/gpu
flavors: [ { name: gpu-flavor, resources: [ { name: nvidia.com/gpu, nominalQuota: 32 } ] } ]
preemption: { reclaimWithinCohort: Any } # 队列内抢占
apiVersion: kueue.x-k8s.io/v1beta1
kind: LocalQueue
metadata: name: team-a-lq
spec: clusterQueue: team-a-cq要点:
- 队列模型解决"配额+排队":ClusterQueue 定义"这个团队有多少 GPU 配额",LocalQueue 把命名空间里的作业指向队列——训练作业不再直接抢 GPU,而是进队等配额,这就是"SLURM 分区"的 K8s 版。
- 抢占是"作业级"的:
reclaimWithinCohort允许队列内低优先级作业被高优先级抢占(配合 PreemptionPolicy),实现"大作业等、小作业先跑"——呼应 02 章 Backfill 思想。 - Kueue 是"轻量队列层":它不改 K8s 调度器,只做"作业准入/排队/配额"——部署简单、生产验证多,K8s 上训练编排的推荐起步。
第二段:Volcano——批处理调度器
yaml
# Volcano:独立调度器,支持 gang scheduling(整组调度)
apiVersion: scheduling.volcano.sh/v1beta1
kind: Queue
metadata: name: training-queue
spec: weight: 10 # 队列权重(配额比例)
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata: name: dl-train
spec:
schedulerName: volcano
minAvailable: 4 # gang:4 卡全部就绪才启动
queue: training-queue
tasks:
- replicas: 4
template: { spec: { containers: [{ name: t, image: pytorch:24.01 }] } }要点:
- gang scheduling 是训练特有的需求:分布式训练(DDP/FSDP/3D 并行)要求"所有卡同时就绪"才开跑,否则先就绪的卡空等甚至超时——
minAvailable实现"整组调度",这是裸 K8s 调度器做不到的(06 章 k8s-gpu-scheduling 篇衔接)。 - Volcano 是"完整调度器":比 Kueue 重(接管调度、支持亲和/拓扑感知),适合"K8s 要承担 HPC 工作负载"的强需求;Kueue+默认调度器适合"轻量起步"。
- 二者不互斥:Kueue 管配额排队、Volcano 管整组调度,可叠加使用(Kueue 社区支持对接 Volcano)。
原理讲解
K8s 跑训练的三个缺口与对应方案
| 缺口 | 现象 | 方案 |
|---|---|---|
| 无队列/配额 | 作业直接抢 GPU、无公平性 | Kueue ClusterQueue |
| 无整组调度 | 分布式作业卡部分就绪空等 | Volcano gang scheduling |
| 无抢占/优先级 | 长作业占位、短作业饿死 | preemption + 优先级类 |
核心认知:K8s 默认"即时拉起"(在线服务),训练要"排队+整组+抢占"(批处理)——Kueue/Volcano 就是把 SLURM 的批处理语义搬进 K8s。混合集群(在线推理 + 离线训练同 K8s)里,队列/配额让两类负载公平共享 GPU。
与 SLURM 的对应关系
| SLURM | K8s + Kueue/Volcano |
|---|---|
| Partition | ClusterQueue / Volcano Queue |
| QoS(优先级/抢占) | preemption + priorityClass |
| 作业(srun/sbatch) | Kueue Workload / Volcano Job |
| 回填(Backfill) | 队列间抢占 + 配额弹性 |
| GRES(GPU 资源) | nvidia.com/gpu 扩展资源 |
迁移认知:SLURM 团队迁 K8s,先找到"分区→队列、QoS→抢占、作业→Workload"的映射,语义平移后,运维习惯(排队/配额/优先级)直接复用。
实验结果
(估算口径,非实测)
| 方案 | 部署复杂度 | 能力 |
|---|---|---|
| 裸 K8s | 低 | 无队列/整组,训练易踩坑 |
| Kueue | 中 | 配额/排队/抢占,整组需配合 |
| Volcano | 中-高 | 整组/拓扑感知,较重 |
| Kueue + Volcano | 高 | 全能力(推荐大规模) |
工程启示
- 先 Kueue 起步,按需加 Volcano:配额/排队是多数团队的刚需,Kueue 轻量先上;出现整组调度/拓扑需求再叠加 Volcano。
- 队列与配额是"多租户治理"的关键:按团队建 ClusterQueue、设配额、开抢占——训练作业不再"先到先得抢 GPU",公平性立竿见影。
- gang 调度是分布式训练的底线:minAvailable=整组卡数,避免"部分就绪空等"——DDP/FSDP 作业必须配。
- 与监控/计费联动:队列维度上报利用率(02 章)与成本(06 章成本篇),配额调整才有数据依据。
下一篇预告:K8s 作业编排补齐后,06 云章与 10 预训练章都再进一步;下一批可回 04 存储或 05 装机补缺,或转 SEO 收尾。由你裁量。