Volcano Job
随着人工智能、大数据分析和高性能计算(HPC)等场景的快速发展,传统Kubernetes Job在复杂任务调度、资源保障、任务依赖等方面逐渐显现出局限性。为解决这些问题,CCE Standard/Turbo 集群基于Volcano提供了 Volcano Job(简称 vcjob) 功能。Volcano是一个面向批处理与高性能计算场景的Kubernetes原生调度系统,提供了比原生Job更强大的作业管理能力。
通过 Volcano Job,用户可以:
- 定义包含多个任务类型的复杂作业(如 MPI、Spark、TensorFlow 等)。
- 设置最小成功 Pod 数(minAvailable),保障作业执行的可靠性。
- 指定专用调度器(如 volcano)进行资源调度。
- 支持任务间依赖关系、索引型任务(Indexed Job)等高级特性。
基本概念
|
概念 |
定义 |
作用 |
|---|---|---|
|
Volcano Job(vcjob) |
Volcano 自定义的 Job 资源类型,扩展了 Kubernetes 原生 Job 的能力 |
支持多任务模板、最小运行 Pod 数、任务依赖、索引任务等,适用于 AI 训练、基因测序等批处理场景 |
|
Task |
Volcano Job 中的一个任务单元,可定义多个不同类型的 Task(如 master、worker) |
每个 Task 可拥有独立的容器镜像、资源请求、副本数等,实现异构任务编排 |
|
MinAvailable |
作业成功运行所需的最小 Pod 数量 |
若实际成功运行的 Pod 数小于该值,则整个作业被视为失败,避免部分成功导致结果不可靠 |
|
SchedulerName |
指定用于调度该 Job 的调度器名称(通常为 volcano) |
确保作业由 Volcano 调度器处理,启用高级调度策略(如 gang scheduling) |
|
Queue |
Volcano 提供的资源队列机制,用于对作业进行分组和优先级管理 |
支持多租户资源隔离、配额控制和优先级调度 |
|
Policy |
定义在特定事件(如 Pod 失败、任务完成)发生时应采取的动作 |
支持自动重启、完成作业、终止作业等行为,提升作业鲁棒性和自动化程度 |
|
Plugin |
Volcano 提供的作业增强插件机制,用于自动注入框架所需的环境变量或启动参数 |
如 pytorch 插件可自动配置 MASTER_ADDR、RANK、WORLD_SIZE 等分布式训练参数 |
前提条件
- 已创建 CCE Standard/Turbo 集群,集群版本建议为 v1.27 及以上。
- 已安装1.19.11及以上版本的Volcano插件:在 CCE 控制台“插件中心”中搜索并安装 “Volcano 调度器” 插件。
- 集群节点具备足够的 CPU、内存等资源以运行批处理任务。
- (可选)若需使用 Queue 功能,需提前通过 kubectl 创建 Volcano Queue 资源。
在使用 Volcano 作为调度器时,建议将集群中所有相关工作负载统一使用 Volcano 调度,以避免调度冲突。
约束与限制
- Volcano Job 依赖 Volcano 调度器插件,未安装插件时无法生效。
- 当前 CCE 控制台暂不支持图形化创建 vcjob,需通过 kubectl 或 YAML 文件部署。
- 若使用 minAvailable,需确保集群资源充足,否则可能导致作业长期处于 Pending 状态。
- Volcano Job 不支持与 Kubernetes CronJob 直接集成,需通过外部控制器实现定时触发。
使用示例:使用 Volcano Job 运行 PyTorch 分布式训练
以下 YAML 示例展示如何使用 Volcano Job 启动一个包含 1 个 master + 2 个 worker 的 PyTorch 分布式训练任务,并利用 Policy 和 PyTorch Plugin 实现高可靠性和自动配置。
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: resnet-dist-train
spec:
# 至少需要 3 个 Pod(1 master + 2 worker)同时成功运行,作业才算成功
minAvailable: 3
# 指定使用 Volcano 调度器,启用 Gang Scheduling 等高级调度能力
schedulerName: volcano
# 定义作业级策略:当有 Pod 被驱逐(PodEvicted)或失败(PodFailed)时,
# 执行 RestartJob 动作 —— 重建整个 Job 的所有 Pod。
# 这对分布式训练至关重要,可避免部分节点失败导致训练不同步。
policies:
- events: [PodEvicted, PodFailed]
action: RestartJob
# 启用 PyTorch 插件,自动注入分布式训练所需的环境变量和启动参数。
# 插件会根据 tasks 中的 master/worker 名称和副本数,
# 自动设置 MASTER_ADDR、RANK、WORLD_SIZE、MASTER_PORT 等。
plugins:
pytorch: ["--master=master", "--worker=worker", "--port=23456"]
status-mounter: ["-statusJson=true","-mountPoint=/status","-values=retryCount,pending,running"]
tasks:
# Master 任务:负责协调训练过程
- replicas: 1
name: master
# Task 级策略:当 master 任务完成时,自动标记整个 Job 为完成状态
policies:
- event: TaskCompleted
action: CompleteJob
template:
spec:
containers:
- image: gcr.io/kubeflow-ci/pytorch-dist-sendrecv-test:1.0
imagePullPolicy: IfNotPresent
name: master
restartPolicy: OnFailure
# Worker 任务:执行实际的模型训练
- replicas: 2
name: worker
template:
spec:
containers:
- image: gcr.io/kubeflow-ci/pytorch-dist-sendrecv-test:1.0
imagePullPolicy: IfNotPresent
name: worker
workingDir: /home
restartPolicy: OnFailure
关键特性解析
Policy(策略)机制
- 作业级策略(spec.policies):适用于整个 Job。例如,当任意 Pod 失败时,RestartJob 会销毁所有 Pod 并重新创建,确保分布式训练从一致状态开始。
- 任务级策略(tasks[].policies):适用于单个 Task。例如,TaskCompleted 事件触发 CompleteJob,可用于 master 完成后自动结束整个作业。
PyTorch Plugin(插件)
- Volcano 内置 pytorch 插件,可自动为容器注入以下环境变量:
- MASTER_ADDR:master Pod 的 IP 地址
- MASTER_PORT:由 --port 指定(本例为 23456)
- WORLD_SIZE:总进程数(= master 1 + worker 2 = 3)
- RANK:每个 Pod 的唯一序号(master 通常为 0,worker 依次为 1、2...)
- 用户无需手动编写服务发现或 IP 配置逻辑,极大简化分布式训练部署。
该插件要求容器内使用 torch.distributed 启动方式(如 torch.distributed.run 或 torch.distributed.launch),并读取上述环境变量。
status-mounter Plugin(插件)
Volcano 内置 status-mounter 插件,可自动将vcjob的状态通过环境变量或者通过文件挂载注入容器 插件支持如下配置:
- 挂载路径 mountPoint: 用于指定状态信息写入的文件路径。若未设置,则不会进行文件挂载 示例配置:-mountPoint="/status"
- 环境变量注入开关 addEnv: 控制是否将状态信息注入为容器的环境变量。默认为启用状态 示例配置:-addEnv=true
- 状态值列表 values: 定义需要注入的 vcjob 状态字段。默认仅包含 retryCount 示例配置:-values=retryCount,pending,running 表示将 retryCount、pending 和 running 三个状态值注入容器。
- 状态 JSON 序列化开关 statusJson: 决定是否将整个 vcjob 的状态对象序列化为 JSON 格式并挂载。默认为关闭 示例配置:-statusJson=true 启用后,会生成一个名为 jsonStatus 的字段,内容为完整的 JSON 格式状态数据
- 环境变量前缀 prefix: 设置注入环境变量时的前缀名称。默认为 Job_ 示例配置:-prefix=Job_ 最终环境变量名称如 Job_retryCount、Job_pending 等
- 容器过滤器 containers: 用于指定状态注入的目标容器。默认为 *,表示对所有容器生效 示例配置:-containers=*
部署与验证
- 应用YAML
kubectl apply -f resnet-dist-train.yaml
- 查看状态
# 查看 Job 状态 kubectl get vcjob resnet-dist-train # 查看 Pod kubectl get pods -l volcano.sh/job-name=resnet-dist-train # 查看日志(例如查看 worker-0) kubectl logs resnet-dist-train-worker-0
当 Job 状态为 Completed 时,表示训练成功完成。
在训练过程中,可以通过读取插件注入的环境变量或挂载文件,来实时监控分布式任务的运行状态。这种方式能够帮助判断当前任务的调度和执行情况,从而进行相应的调整或决策。 例如,status-mounter 插件将任务状态写入指定路径下的文件,用户可以通过执行命令查看这些状态值:
kubectl exec resnet-dist-train-worker-0 -- cat /status/pending 1 kubectl exec resnet-dist-train-worker-0 -- cat /status/running 2
从上述输出可以看出,当前有 1 个 Pod 处于待启动状态,2 个 Pod 正在运行中。结合这些信息,可以判断任务尚未完全启动,仍有一个工作节点等待调度。 这种方式不仅便于调试,也适用于在训练脚本中动态读取状态,实现更智能的任务控制和资源管理。
组件说明
Volcano Job 依赖以下核心组件(均部署在 kube-system 命名空间):
|
组件名称 |
说明 |
资源类型 |
|---|---|---|
|
volcano-admission |
准入控制器,校验 vcjob 配置合法性 |
Deployment |
|
volcano-controllers |
控制器,管理 Job、Queue、PodGroup 等资源生命周期 |
Deployment |
|
volcano-scheduler |
核心调度器,实现 Gang Scheduling、优先级调度等策略 |
Deployment |
常见问题
- Volcano Job 和 Kubernetes 原生 Job 有何区别?
Volcano Job 支持多 Task、minAvailable、Queue、Gang Scheduling 等高级特性,更适合 AI/HPC 批处理场景;而原生 Job 仅支持单一 Pod 模板和简单重试机制。
- 如何查看 Volcano Job 的调度日志?
可通过以下命令查看调度器日志:
kubectl logs -n kube-system -l app=volcano-scheduler