Volcano:AI 场景的批处理调度器
K8s 原生调度器是为微服务设计的,对 AI 任务支持不好。
Volcano 是华为开源的批处理调度器,专门解决 AI/大数据场景的调度问题。
K8s 原生调度的问题
问题一:没有 Gang Scheduling
分布式训练需要多个 Pod 同时启动:
8 卡训练任务:需要 8 个 Pod 同时运行
K8s 原生调度:
- Pod 1 调度成功 ✓
- Pod 2 调度成功 ✓
- ...
- Pod 5 调度成功 ✓
- Pod 6 调度失败 ✗(没资源了)
结果:5 个 Pod 在跑,等 Pod 6
但 Pod 1-5 没法开始训练,因为差一个
→ 资源浪费
这叫「部分调度」问题。正确的做法是:要么 8 个都能调度,要么一个都不调度。
问题二:没有队列管理
多个团队共享 GPU 集群:
团队A 提交 100 个任务
团队B 提交 100 个任务
K8s 原生:先到先得,谁提交快谁先跑
没有公平性保证,没有优先级控制
问题三:没有抢占策略
低优先级任务占着 GPU,高优先级任务进不来。
K8s 有 PriorityClass,但抢占逻辑对批处理任务不够智能。
问题四:不感知拓扑
分布式训练希望 Pod 在同一节点或同一机架:
8 卡训练最好在同一台机器(走 NVLink)
跨机器通信慢(走网络)
K8s 原生调度不考虑这个
Volcano 是什么
Volcano 是 CNCF 的孵化项目,专门为批处理、AI、大数据设计的调度器。
核心功能:
- Gang Scheduling(组调度)
- Queue 管理
- 公平调度
- 抢占
- 拓扑感知
- 资源预留
安装 Volcano
# 方式一:kubectl
kubectl apply -f https://raw.githubusercontent.com/volcano-sh/volcano/master/installer/volcano-development.yaml
# 方式二:Helm
helm repo add volcano-sh https://volcano-sh.github.io/helm-charts
helm install volcano volcano-sh/volcano -n volcano-system --create-namespace
验证
kubectl get pods -n volcano-system
# 应该看到:
# volcano-admission
# volcano-controllers
# volcano-scheduler
核心概念
Job
Volcano 的 Job(不是 K8s 的 Job):
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: pytorch-job
spec:
minAvailable: 8 # 最少需要 8 个 Pod 才能开始
schedulerName: volcano
queue: default
tasks:
- replicas: 8
name: worker
template:
spec:
containers:
- name: pytorch
image: pytorch/pytorch:latest
resources:
limits:
nvidia.com/gpu: 1
关键字段:
minAvailable:Gang Scheduling 的核心,必须凑够才能调度schedulerName: volcano:使用 Volcano 调度器queue:提交到哪个队列
Queue
资源队列,用于多租户管理:
apiVersion: scheduling.volcano.sh/v1beta1
kind: Queue
metadata:
name: team-a
spec:
weight: 2 # 权重,用于公平调度
capability:
cpu: 100
memory: 200Gi
nvidia.com/gpu: 16 # 队列最多用 16 张 GPU
PodGroup
一组需要一起调度的 Pod:
apiVersion: scheduling.volcano.sh/v1beta1
kind: PodGroup
metadata:
name: training-group
spec:
minMember: 8 # 最少 8 个 Pod
queue: default
Job 会自动创建 PodGroup,也可以手动创建给普通 Pod 用。
Gang Scheduling
工作原理
提交 8 Pod 的 Job(minAvailable=8)
↓
Volcano 检查:能否一次性调度 8 个 Pod?
↓
可以 → 全部调度,Job 开始运行
不可以 → 全部不调度,等待资源
配置示例
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: distributed-training
spec:
minAvailable: 4 # 至少 4 个 Pod
policies:
- event: PodEvicted
action: RestartJob # Pod 被驱逐时重启整个 Job
tasks:
- replicas: 4
name: worker
template:
spec:
containers:
- name: worker
image: training:latest
resources:
limits:
nvidia.com/gpu: 1
部分调度场景
有时候不需要全部 Pod:
spec:
minAvailable: 6 # 8 个里面来 6 个就能跑
tasks:
- replicas: 8
队列管理
创建队列
apiVersion: scheduling.volcano.sh/v1beta1
kind: Queue
metadata:
name: high-priority
spec:
weight: 4
capability:
nvidia.com/gpu: 32
---
apiVersion: scheduling.volcano.sh/v1beta1
kind: Queue
metadata:
name: low-priority
spec:
weight: 1
capability:
nvidia.com/gpu: 16
提交到队列
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: my-job
spec:
queue: high-priority # 指定队列
# ...
队列优先级
权重高的队列优先分配资源:
high-priority (weight=4):分到 80% 资源
low-priority (weight=1):分到 20% 资源
调度策略
Volcano 支持多种调度插件:
Gang
Gang Scheduling 插件,前面讲过。
Priority
按优先级调度:
spec:
priorityClassName: high-priority
DRF(Dominant Resource Fairness)
公平调度算法,保证各队列公平使用资源。
Binpack
尽量把 Pod 调度到同一节点,提高资源利用率。
Nodeorder
考虑节点拓扑,优先调度到更近的节点。
配置调度策略
# volcano-scheduler-configmap
apiVersion: v1
kind: ConfigMap
metadata:
name: volcano-scheduler-configmap
namespace: volcano-system
data:
volcano-scheduler.conf: |
actions: "enqueue, allocate, backfill"
tiers:
- plugins:
- name: priority
- name: gang
- name: conformance
- plugins:
- name: drf
- name: predicates
- name: nodeorder
- name: binpack
抢占
配置抢占
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: urgent-job
spec:
priorityClassName: high-priority
preemptable: false # 不可被抢占
tasks:
- replicas: 4
name: worker
# ...
抢占策略
# 被抢占时的行为
policies:
- event: PodEvicted
action: RestartJob # 重启整个 Job
# 或 action: AbortJob # 终止 Job
与训练框架集成
PyTorch 分布式训练
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: pytorch-distributed
spec:
minAvailable: 4
schedulerName: volcano
plugins:
env: []
svc: []
tasks:
- replicas: 4
name: worker
policies:
- event: TaskCompleted
action: CompleteJob
template:
spec:
containers:
- name: pytorch
image: pytorch/pytorch:latest
command:
- python
- -m
- torch.distributed.launch
- --nproc_per_node=1
- --nnodes=4
- --node_rank=$(VK_TASK_INDEX)
- --master_addr=$(MASTER_ADDR)
- --master_port=23456
- train.py
resources:
limits:
nvidia.com/gpu: 1
Kubeflow 集成
Volcano 可以作为 Kubeflow Training Operator 的调度器:
# PyTorchJob
apiVersion: kubeflow.org/v1
kind: PyTorchJob
metadata:
name: pytorch-job
spec:
pytorchReplicaSpecs:
Worker:
replicas: 4
template:
spec:
schedulerName: volcano # 使用 Volcano
containers:
- name: pytorch
# ...
监控
查看队列状态
kubectl get queue
# NAME STATE INQUEUE PENDING RUNNING UNKNOWN
# default Open 0 0 4 0
# high-priority Open 2 1 8 0
查看 Job 状态
kubectl get vcjob
# NAME STATUS MINAVAILABLE RUNNINGS
# pytorch-job Running 8 8
Prometheus 指标
Volcano 暴露 Prometheus 指标:
volcano_queue_allocated_gpu
volcano_queue_pending_gpu
volcano_job_status_count
小结
Volcano 解决的问题:
| 问题 | K8s 原生 | Volcano |
|---|---|---|
| Gang Scheduling | 不支持 | 支持 |
| 队列管理 | 简单 | 完善 |
| 公平调度 | 无 | DRF |
| 抢占 | 简单 | 灵活 |
| 拓扑感知 | 无 | 支持 |
使用场景:
- 分布式训练
- 批处理任务
- 多租户 GPU 集群
- 需要资源公平的场景
核心概念:
- Job:批处理任务
- Queue:资源队列
- PodGroup:组调度单位
- minAvailable:Gang Scheduling 的关键
下一篇讲 GPU 切分:MIG、MPS、vGPU。