Volcano 调度框架深度解读
Volcano 调度框架深度解读
调研日期: 2026-07-01 | 版本: v1.15.0 (2026-06) | 置信度: 全部 findings 经 3-vote 对抗验证,均 High confidence 官方站点: volcano.sh | GitHub: volcano-sh/volcano
一、项目概览与 CNCF 状态
Volcano 是 CNCF 孵化项目(2022-03-21 从 Sandbox 升级至 Incubator,截至 v1.15.0 尚未毕业)。其调度器基于 kube-batch 构建——后者已归档并由 Volcano 接续演进。架构上与默认 kube-scheduler 完全独立,是专为批处理工作负载设计的独立调度框架。
核心定位: 为 AI/ML 训练、大数据等批处理场景提供 Kubernetes 原生的 gang scheduling、层级队列管理和可扩展调度能力。
三大组件部署(volcano-system namespace):
volcano-admission— webhook 准入控制volcano-controllers— CRD 控制器(Job、PodGroup、Queue)volcano-scheduler— 批调度器核心
🔗 Sources: CNCF Projects, CNCF Blog 2022, GitHub README
二、调度架构:Action × Plugin 可扩展框架
Volcano 调度器将 Action(定义调度流程步骤)与 Plugin(提供算法决策逻辑)分离,两者均可通过注册接口自定义实现(RegisterAction、RegisterPluginBuilder)。
graph TD
subgraph Actions["Actions - 调度流程步骤"]
A1[enqueue] --> A2[allocate]
A2 --> A3[preempt] --> A4[reclaim] --> A5[backfill]
A3a[gangpreempt]
A4a[gangreclaim]
A5a[shuffle]
end
subgraph Plugins["Plugins - 算法决策逻辑"]
P1[DRF]
P2[Gang]
P3[Priority]
P4[QueueOrder]
P5[NodeOrder]
P6[Predicate]
P7[Proportion]
end
Actions -.-> Plugins
⚠️ 验证修正: 官方设计文档早期仅描述 4 个 action(allocate, preempt, reclaim, backfill),但当前源码
pkg/scheduler/actions/factory.go注册了 8 个 action: enqueue, allocate, backfill, preempt, reclaim, gangpreempt, gangreclaim, shuffle。5 个核心 action 按顺序执行:enqueue → allocate → preempt → reclaim → backfill。
核心概念:
- Action: 定义每一步"做什么"(如 enqueue 将 Job 放入 Queue,allocate 绑定 Pod 到 Node)
- Plugin: 定义每一步"怎么做"(如 Gang plugin 提供
PreemptableFn判断驱逐是否安全)
调度 Session 生命周期:
OnSessionOpen— 初始化 plugin 状态- 依次执行各 action(action 调用 plugin 注册的函数)
OnSessionClose— 清理 session
🔗 Sources: Scheduler Plugins Docs, Interface.go, Plugins.go
三、PodGroup — Gang Scheduling 的实现
3.1 CRD 定义
PodGroup 是 scheduling.volcano.sh/v1beta1 API 组下的 CRD,是实现 gang scheduling 的核心机制。
apiVersion: scheduling.volcano.sh/v1beta1
kind: PodGroup
spec:
minMember: 4 # 最少需同时运行的 Pod 数
priorityClassName: "" # PodGroup 优先级排序
queue: default # 所属队列
3.2 Gang Scheduling 语义
All-or-Nothing: 如果集群资源无法同时容纳至少 minMember 个 Pod,则该 PodGroup 中的 所有 Pod 都不会被调度。这避免了批处理任务的部分执行(如分布式训练仅启动部分 worker)。
flowchart LR
A["PodGroup 提交"] --> B{"集群资源 >= minMember?"}
B -->|Yes| C["全部 Pod 度启动"]
B -->|No| D["全部 Pod 等待"]
C --> E{"运行 Pod >= minAvailable?"}
E -->|Yes| F["正常运行"]
E -->|No 抢占或故障| G["Job 标记 Inqueue 等待资源恢复"]
3.3 优先级与抢占保护
priorityClassName字段在 Queue 内对 PodGroup 排序,用于抢占优先级调度- 保留值
system-node-critical和system-cluster-critical代表最高优先级 - Gang 抢占保护: Gang plugin 的
PreemptableFn会阻止驱逐导致运行 Pod 数低于minAvailable的任务
🔗 Sources: PodGroup Docs, CRD YAML, Types.go
四、队列管理 — 层级公平分配
4.1 权重公平分配公式
Volcano 使用基于权重的公平资源分配:
4.2 三级资源模型
每个 Queue 有三个资源层级配置:
| 层级 | 含义 | 特性 |
|---|---|---|
| guarantee | 保留资源 | 独享,不借出 |
| deserved | 软配额 | 可借出,但当需求上升时可 reclaim 回来 |
| capability | 硬上限 | Queue 不可超过此上限 |
推荐顺序: guarantee ≤ deserved ≤ capability
4.3 Reclaimable 与超额惩罚
- reclaimable=false: 阻止其他 Queue reclaim 该 Queue 的超额资源
- 超额惩罚: Queue 的
Allocated > Deserved时,失去对其他 Queue 的 reclaim 权利(AddPreemptiveFn检查Queue.Allocated >= Queue.Deserved阻止 reclaim;AddReclaimableFn选择 victim 时优先选queue.Allocated > Queue.Deserved的任务)
flowchart TB
Total["总资源: 20 CPU"] --> QA["Queue A weight=30<br>guarantee=2 / deserved=6 / cap=10<br>allocated=8 超额 无reclaim权"]
Total --> QB["Queue B weight=70<br>guarantee=4 / deserved=14 / cap=20<br>allocated=10 可reclaim A超额"]
🔗 Sources: Queue Docs, Queue Resource Management, Capacity Scheduling Design
五、Reclaim vs Preempt — 双轨抢占机制
Volcano 明确区分两种抢占,源码级强制隔离:
| 维度 | Reclaim | Preempt |
|---|---|---|
| 范围 | 跨队列(cross-queue) | 同队列内(intra-queue) |
| 触发 | Queue 的 allocated 超过 deserved 时 | 高优先级 Job 需要资源时 |
| victim 选择 | j.Queue != job.Queue |
job.Queue == preemptorJob.Queue |
| 考虑因素 | 超额程度 + 队列/Job 优先级 | Job 优先级 + Task 优先级 |
flowchart LR
subgraph Reclaim["Reclaim - 跨队列"]
R1["Queue B 不足"] --> R2["选择 Queue A 中 allocated > deserved 的任务"] --> R3["驱逐后资源归还 Queue B"]
end
subgraph Preempt["Preempt - 同队列内"]
P1["高优先级 Job 入队"] --> P2["选择同 Queue 内低优先级 Job 的任务"] --> P3["驱逐后资源给高优先级 Job"]
end
🔗 Sources: Queue Resource Management Docs, reclaim.go, preempt.go
六、Gang-Aware Preemption — v1.15.0 关键演进
6.1 问题:默认抢占是 Gang-Blind 的
Volcano 的默认抢占策略是 node-first(先选 Node,再选驱逐哪些 Task),不考虑 gang/PodGroup 边界。结果是:
- 驱逐 victims 可能跨越多个 Job
- Gang plugin 只充当"护栏"(threshold check),而非 gang-aware 的 victim 选择策略
- 对 AI/ML 工作负载尤其不利——分布式训练的部分 Pod 驱逐可能导致整个 Job 回退
6.2 PR #4637 — 三种 Gang-Aware 模式
v1.15.0 合入的 PR #4637 通过 volcano-scheduler-configmap 引入三种可配置模式:
| 模式 | 常量 | 行为 |
|---|---|---|
| off (默认) | GPModeOff |
保持当前 node-first 行为,向后兼容 |
| minimal | GPModeMinimal |
按 gang 分组 preemptable tasks per node,偏好单 gang fit |
| atomic | GPModeAtomic |
集群级 gang 驱逐——选中 victim gang 时,跨所有 Node 驱逐该 gang 的全部 tasks |
# volcano-scheduler-configmap 配置示例
apiVersion: v1
kind: ConfigMap
data:
volcano-scheduler.conf: |
actions: "enqueue, allocate, preempt, reclaim, backfill"
tiers:
- plugins:
- name: gang
arguments:
gangPreemptionMode: minimal # off | minimal | atomic
⚠️ 重要: gang-aware 模式需要显式配置启用,默认仍为 node-first。AI/ML 场景建议启用
minimal或atomic模式。
🔗 Sources: PR #4637, Preempt-action Design Doc, preempt.go
七、与默认 kube-scheduler 的对比
| 维度 | kube-scheduler | Volcano |
|---|---|---|
| 调度粒度 | 单 Pod | PodGroup (gang) |
| 队列 | PriorityClass + Namespace | 层级 Queue + 权重公平分配 |
| 抢占 | 单 Pod preempt | reclaim (跨队列) + preempt (同队列) + gang-aware |
| 扩展方式 | Scheduler Framework (Extender) | Action + Plugin 注册 |
| 批处理支持 | 无原生 gang scheduling | PodGroup CRD 全有全无 |
| 资源公平性 | PriorityClass 粗粒度 | DRF/Proportion 权重公平 |
| 适用场景 | 通用微服务 | AI/ML 训练、大数据、批处理 |
八、实际应用场景
AI/ML 训练
- 分布式训练: PodGroup gang scheduling 确保 all-or-nothing,避免部分 worker 启动浪费 GPU
- GPU 共享: 配合 HAMi(CNCF Sandbox)实现多厂商 GPU 切分,Volcano 负责 batch 层调度
- KServe + Volcano: Kserve LLM 路由场景中,Volcano 作为 batch 层调度器
大数据
- Spark on Volcano: 社区有成熟的 Spark 集成方案,PodGroup 保证 Executor 全部启动
- Flink on Volcano: 类似 gang scheduling 保证
其他
- MPI/HPC: gang scheduling 天然适配 MPI 任务的 all-or-nothing 需求
- CI/CD batch: Queue 权重分配确保不同团队的构建公平性
九、关键 CRD 速查
| CRD | API Group | 核心字段 |
|---|---|---|
| PodGroup | scheduling.volcano.sh/v1beta1 |
minMember, priorityClassName, queue, minAvailable |
| Queue | batch.volcano.sh/v1beta1 |
weight, guarantee, deserved, capability, reclaimable |
| Job (VCJob) | batch.volcano.sh/v1beta1 |
tasks[], minAvailable, schedulerName, priorityClassName |
十、相关生态与延伸阅读
- AI INFRA 全景分析与展望 — Volcano 在 AI INFRA 全景中的定位(K8s 调度层)
- 2026-06-24 AI INFRA 全景分析与展望 — HAMi + Volcano + LWS 三层架构
- kube-batch (archived) — Volcano 的前身
- Volcano Docs — 官方文档
- Volcano GitHub — 源码与 design docs
📋 调研方法: deep-research 工作流 — 5 角度并行搜索 → 15+ 源抓取 → 6 falsifiable claims → 每 claim 3-vote 对抗验证(≥2/3 refutes 即 kill)→ 最终 6/6 claims 全部 High confidence 存活