解锁 Kubernetes 批处理新范式:Volcano 调度引擎初体验
还在为 Kubernetes 大规模批处理任务调度烦恼?Volcano——CNCF 官方批处理调度引擎,提供 Gang Scheduling、队列优先级、异构设备支持等高级特性。本文以最小化实践带你完成 Volcano 安装到验证。
1.Volcano 简介
Volcano 是什么?
官方描述:Volcano is a batch system built on Kubernetes. 基于 Kubernetes 的高性能工作负载调度引擎。
Volcano 能做什么?
支持 Kubernetes 原生负载及主流计算框架 (如TensorFlow、Spark、PyTorch、Ray、Flink等) 的一体化作业调度。
强大的批处理调度能力:通过 VcJob 完美支持 Ray、TensorFlow、PyTorch、MindSpore、Spark、Flink 等主流 AI 和大数据框架
完整的 Kubernetes 工作负载支持:可直接调度 Deployment、StatefulSet、Job、DaemonSet 等原生工作负载
为什么需要 Volcano?
或者说 Volcano 之前有哪些痛点。
随着各种新兴高性能计算需求的持续增长,Job 的调度和管理能力变得必要和复杂。下面罗列了一些共性需求:
调度算法的多样性
调度性能的高效性
无缝对接主流计算框架
对异构设备的支持
Volcano 正是针对这些需求应运而生的。同时,Volcano 继承了 Kubernetes 接口的设计风格和核心概念。用户可以在充分享受 Volcano 的高效性和便利性的同时不用改变任何以前使用 Kubernetes 的习惯。
场景 | 原生 Kubernetes | Volcano | 优势 |
---|---|---|---|
分布式任务调度 | Pod 独立调度 | Gang Scheduling (All-or-Nothing) | 避免死锁,提高集群利用率 |
资源争用处理 | 简单 FIFO | 优先级队列+公平共享 | 保障关键任务资源 |
GPU 调度 | 基础设备分配 | 拓扑感知+虚拟化 | 提升 GPU 利用率 30%+ |
批量作业 | Job 资源限制弱 | 作业级资源配额 | 精准控制批量任务资源占用 |
现在以一个分布式训练场景为例,说明为什么需要 Volcano。
在 AI 中大规模任务比较常见,如果按照 k8s 默认的以 Pod 为单位进行调度,可能会出现资源浪费,甚至死锁的情况。
例如:启动一个 PyTorchJob 包括 1 Master 2 Worker,yaml 如下:
apiVersion: kubeflow.org/v1
kind: PyTorchJob
metadata:
name: pytorch-job-example
namespace: default
spec:
cleanPodPolicy: None
pytorchReplicaSpecs:
Master:
replicas: 1 # 主节点数量
restartPolicy: OnFailure
template:
spec:
containers:
- name: pytorch
image: pytorch/pytorch:1.9.0-cuda11.1-cudnn8-runtime
command: ["python", "/workspace/train.py"]
args: ["--epochs", "10"]
resources:
limits:
nvidia.com/gpu: 1 # 请求 GPU 资源
Worker:
replicas: 2 # Worker 节点数量
restartPolicy: OnFailure
template:
spec:
containers:
- name: pytorch
image: pytorch/pytorch:1.9.0-cuda11.1-cudnn8-runtime
command: ["python", "/workspace/train.py"]
args: ["--epochs", "10"]
resources:
limits:
nvidia.com/gpu: 1 # 每个 Worker 使用 1 个 GPU
按照 K8s 默认的以 Pod 为单位进行调度,可能出现只有部分 Pod 能成功调度并启动的情况,这样的结果对该 Job 来说都是无意义的。
如果有多个这样的 Job 可能都只调度了一部分 Pod,最终集群资源耗尽,所有 Job 都在等待其他 Job 释放资源。
我们需要该 Job 在调度时满足满足 Gang 调度语义,任务的所有工作负载必须全部运行或全部不运行(All or nothing),从而避免 Pod 的任意调度导致集群资源的浪费。
2. Volcano 架构
可以看到 Volcano 完全构建于 Kubernetes 之上,与 Kubernetes 天然兼容,并为高性能计算而生,遵循 Kubernetes的设计理念和风格。
Volcano 包括以下组件:
Volcano Scheduler:通过一系列的action和plugin调度Job,并为它找到一个最适合的节点。与Kubernetes default-scheduler相比,Volcano与众不同的 地方是它支持针对Job的多种调度算法。
Volcano ControllerManager: Volcano controllermanager管理CRD资源的生命周期。它主要由 Queue ControllerManager、 PodGroupControllerManager、 VCJob ControllerManager构成。
Volcano Admission: Volcano admission 负责对 CRD API资源进行校验。
CRD:Job、Queue、PodGroup 等自定义资源。
vcctl:Volcano vcctl是Volcano的命令行客户端工具。
Volcano 通过 CRD 扩展了 K8s 对象,然后自定义 Controller 和 Scheduler 进行管理以及调度。
3. Volcano 部署
部署时需要注意 volcano 和 k8s 的版本兼容性问题,参考官方 README:Kubernetes compatibility
这里我们部署 Volcano 的 1.12.0 版本。
helm 部署
官方提供了 chart,直接使用 helm 安装即可
# 添加仓库
helm repo add volcano-sh https://volcano-sh.github.io/helm-charts
helm repo update
# 部署
helm upgrade --install volcano volcano-sh/volcano --version 1.12.0 -n volcano-system --create-namespace
验证
安装完成,验证 Volcano 组件的状态
[root@volcano ~]# kubectl get all -n volcano-system
NAME READY STATUS RESTARTS AGE
pod/volcano-admission-dcf9bb957-l294f 1/1 Running 0 85s
pod/volcano-controllers-bd48dd8f8-l5z9c 1/1 Running 0 85s
pod/volcano-scheduler-64f9655f97-vhk9w 1/1 Running 0 85s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/volcano-admission-service ClusterIP 10.99.238.1 <none> 443/TCP 86s
service/volcano-scheduler-service ClusterIP 10.104.54.47 <none> 8080/TCP 86s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/volcano-admission 1/1 1 1 86s
deployment.apps/volcano-controllers 1/1 1 1 86s
deployment.apps/volcano-scheduler 1/1 1 1 86s
NAME DESIRED CURRENT READY AGE
replicaset.apps/volcano-admission-dcf9bb957 1 1 1 86s
replicaset.apps/volcano-controllers-bd48dd8f8 1 1 1 86s
replicaset.apps/volcano-scheduler-64f9655f97 1 1 1 86s
查看相关 crd
[root@volcano ~]# kubectl get crd|grep volcano
commands.bus.volcano.sh 2025-03-14T08:05:09Z
jobflows.flow.volcano.sh 2025-03-14T08:05:09Z
jobs.batch.volcano.sh 2025-03-14T08:05:09Z
jobtemplates.flow.volcano.sh 2025-03-14T08:05:09Z
numatopologies.nodeinfo.volcano.sh 2025-03-14T08:05:09Z
podgroups.scheduling.volcano.sh 2025-03-14T08:05:09Z
queues.scheduling.volcano.sh 2025-03-14T08:05:09Z
4. Volcano 简单使用
接下来我们跑一个简单的 Demo 测试一下 Volcano 的能力,确认 Volcano 正确运行。
首先创建一个名为 test 的 Queue
cat <<EOF | kubectl apply -f -
apiVersion: scheduling.volcano.sh/v1beta1
kind: Queue
metadata:
name: test
spec:
weight: 1
reclaimable: false
capability:
cpu: 2
EOF
再创建一个名为job-1
的Volcano Job。
cat <<EOF | kubectl apply -f -
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: job-1
spec:
minAvailable: 1
schedulerName: volcano
queue: test
policies:
- event: PodEvicted
action: RestartJob
tasks:
- replicas: 1
name: nginx
policies:
- event: TaskCompleted
action: CompleteJob
template:
spec:
containers:
- command:
- sleep
- 10m
image: nginx:latest
name: nginx
resources:
requests:
cpu: 1
limits:
cpu: 1
restartPolicy: Never
EOF
可以看到,这个 Volcano Job 和 K8s 原生 Job 类似,不过也多了几个字段:
spec:
minAvailable: 1
schedulerName: volcano
queue: test
policies:
- event: PodEvicted
action: RestartJob
minAvailable:需要满足最小数量后才进行调度
schedulerName:指定调度器
queue:指定 Job 所属的队列,就是前面我们创建的队列
policies:一些特殊策略
检查 Job 的状态
kubectl get vcjob job-1 -oyaml
检查 PodGroup 的状态
kubectl get podgroup -oyaml
检查 Queue 的状态
kubectl get queue test -oyaml
最后检查 Pod 状态
[root@volcano ~]# kubectl get po
NAME READY STATUS RESTARTS AGE
job-1-nginx-0 0/1 ContainerCreating 0 24s
能够正常启动,说明 Volcano 能够正常使用,具体各个 CRD 对象的作用,后面在详细分析。
5. 小结
Volcano 是 Kubernetes 生态中一个强大的批处理调度系统,通过高级调度算法、增强的 Job 管理能力、异构设备支持和多框架集成等等,解决了 Kubernetes 在处理高性能工作负载时的局限性。
本文主要是介绍了什么是 Volcano 以及使用场景,然后通过 helm 部署 Volcano 并运行了一个最简单的 Demo。
后续详细介绍 Volcano 的各个 CRD 的作用,调度策略,以及 HAMi vGPU 和 Volcano 如何搭配使用。