3.3 批处理调度器对比:Volcano、Kueue 与 YuniKorn 分布式训练的 8 个 worker 必须同时启动,少一个都跑不起来——这就是 Gang Scheduling(成组调度)的诉求。但 K8s 原生调度器是逐个 Pod 调度的,可能造成「调度了 5 个、剩 3 个资源不够、前 5 个死等」的僵局。批处理调度器就是为破解这类问题而生。 3.3.1 原生调度器的批处理短板 K8s 默认调度器(kube-scheduler)是为在线服务设计的,假设「每个 Pod 是独立的、随时可调度」。但批处理负载(训练、Spark、Ray)有几个截然不同的诉求: Gang Scheduling(成组调度):一组 Pod 必须全部调度成功,否则一个都不调度。
分布式训练的 8 个 worker 必须同时启动,少一个都跑不起来——这就是 Gang Scheduling(成组调度)的诉求。但 K8s 原生调度器是逐个 Pod 调度的,可能造成「调度了 5 个、剩 3 个资源不够、前 5 个死等」的僵局。批处理调度器就是为破解这类问题而生。
K8s 默认调度器(kube-scheduler)是为在线服务设计的,假设「每个 Pod 是独立的、随时可调度」。但批处理负载(训练、Spark、Ray)有几个截然不同的诉求:
原生调度器对这些诉求的支持都很弱。于是出现了专门为批处理设计的调度器,主流有三:Volcano、Kueue、YuniKorn。
先讲清 Gang Scheduling 为什么是批处理的「命门」。
假设一个 8 卡训练,原生调度器逐个调度 8 个 worker Pod:
init_process_group 会卡住),但剩余 3 个又调度不上(资源被前 5 个占着)。Gang Scheduling 的解决方案是「要么全成功,要么全不调度」:
💡 判读:Gang Scheduling 是「用资源利用率换调度确定性」。它宁可让作业等待,也不让它半吊子占着资源。对训练这种「全有或全无」的负载,这是唯一合理的调度语义。
Volcano(原名 kube-batch)是华为开源、CNCF 孵化的批处理调度器,是 K8s 上最早成熟的 AI/大数据调度方案。
Volcano 的核心特性:
PodGroup 概念,把一组相关 Pod 作为一个调度单元,原生支持 Gang Scheduling。Volcano 与 Training Operator 的协作:
PyTorchJob(Training Operator CRD)。PodGroup 标签。| 维度 | Volcano |
|---|---|
| 出身 | 华为开源,CNCF 孵化 |
| 核心 CRD | PodGroup、Queue |
| Gang 调度 | 原生支持 |
| 队列模型 | 多级队列、DRF 公平 |
| 拓扑感知 | 支持 |
| 生态成熟度 | 高(CNCF 项目,广泛使用) |
| 典型用户 | 大数据 + AI 混部集群 |
Kueue 是 Kubernetes SIG-WG Batch 官方推出的作业排队与配额管理项目,2023 年成为官方推荐方案。它的设计哲学与 Volcano 略有不同:
ClusterQueue 与 LocalQueue,定义资源配额与借调策略。Kueue 的工作流程:
ClusterQueue(配额池)与 LocalQueue(用户视角的队列)。Job 时指定要进的 LocalQueue。| 维度 | Kueue |
|---|---|
| 出身 | Kubernetes SIG 官方 |
| 核心抽象 | ClusterQueue、LocalQueue、Cohort |
| 替换调度器 | 否(叠加在原生调度器之上) |
| Gang 调度 | 借助原生 Job 的 Indexed completion(K8s 1.27+) |
| 队列模型 | 配额 + Cohort 借调 |
| 拓扑感知 | 渐进增强 |
| 生态成熟度 | 快速增长,官方力推 |
| 典型用户 | 新建 AI 集群、K8s 原生优先团队 |
💡 判读:Kueue 与 Volcano 的本质区别是「是否替换调度器」。Volcano 是「Volcano 调度器接管」,Kueue 是「原生调度器 + Kueue 排队」。后者更轻量、与原生生态融合更好,是官方力推的方向。但 Kueue 的 Gang 调度依赖原生 Job 的 Indexed completion,对一些复杂场景不如 Volcano 灵活。
YuniKorn 是 Apache 社区(最初来自 Cloudera)的调度器,定位偏大数据与流式作业(Spark、Flink)。它的强项是:
但在 AI 场景,YuniKorn 的使用相对少,因为它的设计假设更接近 Hadoop YARN 而非 K8s AI 负载。多数 AI 团队在 Volcano 与 Kueue 之间选择。
把三者放一张表里全面对比,这是选型的核心参考:
| 维度 | Volcano | Kueue | YuniKorn |
|---|---|---|---|
| 出身 | 华为/CNCF | Kubernetes 官方 | Apache/Cloudera |
| 是否替换调度器 | 是 | 否(叠加) | 是 |
| 核心抽象 | PodGroup + Queue | ClusterQueue + LocalQueue | Queue hierarchy |
| Gang Scheduling | 原生强支持 | 借助原生 Job Indexed | 支持 |
| 公平调度 | DRF | Cohort 借调 | Hierarchical DRF |
| 拓扑感知 | 较好 | 渐进增强 | 一般 |
| 大数据生态 | 较好(Spark) | 一般 | 强(Spark/Flink) |
| AI 训练集成 | 强(Training Operator) | 强(原生 Job/CRD) | 一般 |
| 学习成本 | 中 | 低(K8s 原生) | 中高 |
| 社区活跃 | 高 | 快速增长 | 中 |
| 官方推荐 | CNCF 孵化 | K8s 官方力推 | Apache |
| AI 场景推荐度 | ★★★★★ | ★★★★★ | ★★★ |
面对三大调度器,怎么选?给出一个工程决策树:
💡 选型经验总结:
- 纯 AI 训练集群、新建、追求官方路线 → Kueue(轻量、与 K8s 原生融合、官方力推)。
- 复杂 Gang 场景、需要大数据与 AI 混部、训练生态深度集成 → Volcano(功能强、生态成熟)。
- 以 Spark/Flink 为主、有 Hadoop 背景 → YuniKorn(大数据强项)。
- 不确定时优先 Kueue,因为它的路线最清晰、与未来 K8s 演进对齐。
无论选哪个调度器,配额与公平调度都是核心议题。几个工程实践:
LocalQueue,配额绑定到 ClusterQueue,避免一个团队吃掉全部资源。| 实践 | Kueue 对应 | Volcano 对应 |
|---|---|---|
| 团队配额 | LocalQueue + ClusterQueue | Queue + 配额 |
| 借调 | Cohort | reclaim |
| 优先级 | workload priority | PodPriority |
| 抢占 | preemption 借调时触发 | preempt action |
最后回顾一下,本章的批处理调度器与第 2 章的训练 Operator 是如何协作的:
三者形成清晰的分工:Operator 提交 Pod → Kueue/Volcano 排队与 Gang 准入 → kube-scheduler 落节点。这种分层让每个组件职责单一、可独立演进,是云原生 AI 调度栈的设计精髓。
下一节《3.4 抢占、重调度与弹性训练》将讲清中断与故障下的弹性恢复策略。