Volcano 部署与基础功能测试:VolcanoJob、Gang Scheduling、Queue 与 Deployment 调度验证
一、Volcano 简介Volcano 是一个 Kubernetes 原生的批调度系统主要面向 AI 训练、大数据计算、HPC、高性能批处理等场景。相比 Kubernetes 默认调度器Volcano 更关注“成组任务”的调度语义。例如分布式训练中的多个 worker、parameter server、MPI 任务等这类任务往往不是单个 Pod 能独立完成的而是需要一组 Pod 同时满足资源条件后才具备运行意义。在普通 Kubernetes 调度中Pod 通常是以单个对象为单位进行调度而在分布式训练场景中如果只启动其中一部分 Pod任务可能无法正常运行同时还会占用集群资源。Volcano 的 Gang Scheduling 就是为了解决这类问题。Volcano 的核心能力主要包括VolcanoJobVolcano 提供的批任务 CRDPodGroup一组成组调度 Pod 的抽象Gang Scheduling成组调度能力Queue队列资源管理能力多种调度插件如 gang、priority、drf、predicates、proportion、capacity、nodeorder、binpack 等。Volcano 不会替换 Kubernetes 默认调度器。只有在 Pod 模板中显式指定schedulerName: volcano该 Pod 才会交给 Volcano Scheduler 调度。没有指定该字段的普通工作负载仍然会使用 Kubernetes 默认调度器。二、Volcano 部署Volcano 官方文档提供了 YAML、源码和 Helm 等部署方式。实验环境中建议使用 Helm 部署后续升级和卸载都比较方便。1. 添加 Helm 仓库helm repo add volcano-sh https://volcano-sh.github.io/helm-charts helm repo update2. 安装 Volcano官方 Helm 安装命令如下helm install volcano volcano-sh/volcano \ -n volcano-system \ --create-namespace如果希望避免镜像被频繁拉取也可以增加镜像拉取策略参数helm install volcano volcano-sh/volcano \ -n volcano-system \ --create-namespace \ --set basic.image_pull_policyIfNotPresent其中--set basic.image_pull_policyIfNotPresent不是必需参数主要用于实验环境中减少重复拉取镜像。3. 查看 Volcano 组件状态kubectl get pod -n volcano-system实际输出如下NAME READY STATUS RESTARTS AGE volcano-admission-cf4d8dd5c-dshz9 1/1 Running 1 (11m ago) 22h volcano-controllers-5b976c6d4b-6s92b 1/1 Running 1 (11m ago) 22h volcano-scheduler-549f77db69-whptp 1/1 Running 1 (11m ago) 21h这三个核心组件的作用如下组件作用volcano-schedulerVolcano 调度器负责 PodGroup、VolcanoJob 等资源的调度volcano-controllersVolcano 控制器负责 VolcanoJob、PodGroup、Queue 等资源的生命周期管理volcano-admissionAdmission 组件负责资源校验、默认值处理等只要这几个组件正常 Running说明 Volcano 基础组件已经启动成功。三、测试一VolcanoJob 基础运行1. 测试目标该测试用于验证 Volcano 的基础功能是否正常包括VolcanoJob CRD 是否可用Volcano Controller 是否能够创建对应 PodVolcano Scheduler 是否能够调度 PodVolcanoJob 是否会自动关联 PodGroupTaskCompleted - CompleteJob生命周期策略是否生效。VolcanoJob 是 Volcano 提供的 CRD和 Kubernetes 原生 Job 不是同一个资源。VolcanoJob 更适合批处理、AI 训练、MPI、大数据计算等场景因为它天然集成了 Queue、PodGroup、Gang Scheduling 等能力。2. YAML 示例apiVersion: batch.volcano.sh/v1alpha1 kind: Job metadata: name: vcjob-basic namespace: volcano-demo spec: schedulerName: volcano queue: default minAvailable: 1 maxRetry: 1 tasks: - name: basic-task replicas: 1 policies: - event: TaskCompleted action: CompleteJob template: spec: restartPolicy: Never containers: - name: busybox image: busybox:latest imagePullPolicy: IfNotPresent command: - sh - -c - | echo Volcano job is running sleep 20 echo Volcano job completed resources: requests: cpu: 100m memory: 64Mi limits: cpu: 100m memory: 64Mi3. 验证结果查看 VolcanoJobkubectl -n volcano-demo get vcjob输出如下NAME STATUS MINAVAILABLE RUNNINGS AGE vcjob-basic Running 1 1 13s查看 PodGroupkubectl -n volcano-demo get podgroup输出如下NAME STATUS MINMEMBER RUNNINGS AGE vcjob-basic-90ac694a-9eae-4cfb-aef2-e14c7ef7cd5a Running 1 1 20s查看 Podkubectl -n volcano-demo get pod输出如下NAME READY STATUS RESTARTS AGE vcjob-basic-basic-task-0 0/1 Completed 0 23s4. 结果分析这个测试中vcjob-basic的minAvailable为 1task 副本数也是 1因此只要这个 Pod 能够被调度整个 Job 就满足最小运行条件。从 PodGroup 可以看到STATUS Running MINMEMBER 1 RUNNINGS 1说明 Volcano 已经为该 VolcanoJob 创建了对应的 PodGroup并且 PodGroup 当前满足最小成员数要求。Pod 最终变成STATUS Completed这是正常现象。因为 busybox 容器执行完echo和sleep 20后会正常退出restartPolicy: Never表示容器退出后不会重启所以 Pod 状态会变成 Completed。需要注意的是kubectl get vcjob中 Job 状态从 Running 变为 Completed 可能会有一个短暂的 controller 同步延迟。只要 Pod 已经 Completed并且配置了policies: - event: TaskCompleted action: CompleteJobVolcano Controller 后续会根据 task 完成状态把 VolcanoJob 标记为 Completed。5. 字段说明schedulerName: volcano表示该 Job 创建出来的 Pod 使用 Volcano Scheduler 调度。queue: default表示该 Job 使用 Volcano 默认队列。Volcano 启动后会自动创建defaultqueue未显式指定队列的 VolcanoJob 会进入默认队列。minAvailable: 1表示该 Job 至少需要 1 个 Pod 满足调度条件Job 才能进入运行状态。tasks: - name: basic-task replicas: 1表示该 Job 中包含一个名为basic-task的 task副本数量为 1。policies: - event: TaskCompleted action: CompleteJob表示当该 task 内的 Pod 成功完成后将整个 VolcanoJob 标记为完成。TaskCompleted用于判断某个 task 是否完成CompleteJob用于将 Job 置为完成状态并处理未完成的 Pod。四、测试二Gang Scheduling 成功场景1. 测试目标该测试用于验证 Volcano 的 Gang Scheduling 能力。Gang Scheduling 的核心语义是一组 Pod 必须作为整体满足调度条件。如果最小成员数不满足则该组 Pod 不应被部分调度。在分布式训练场景中假设一个任务需要 2 个 worker 同时启动如果资源只允许启动其中 1 个 worker那么任务实际上无法正常工作。Gang Scheduling 的作用就是避免这种“部分启动、整体不可用”的情况。2. YAML 示例apiVersion: batch.volcano.sh/v1alpha1 kind: Job metadata: name: vcjob-gang-success namespace: volcano-demo spec: schedulerName: volcano queue: default minAvailable: 2 maxRetry: 1 tasks: - name: worker replicas: 2 policies: - event: TaskCompleted action: CompleteJob template: spec: restartPolicy: Never containers: - name: busybox image: busybox:latest imagePullPolicy: IfNotPresent command: - sh - -c - | echo gang worker started: $(hostname) sleep 60 echo gang worker finished resources: requests: cpu: 100m memory: 64Mi limits: cpu: 100m memory: 64Mi3. 验证结果查看 VolcanoJobkubectl -n volcano-demo get vcjob输出如下NAME STATUS MINAVAILABLE RUNNINGS AGE vcjob-gang-success Running 2 2 15s查看 Podkubectl -n volcano-demo get pod输出如下NAME READY STATUS RESTARTS AGE vcjob-gang-success-worker-0 1/1 Running 0 17s vcjob-gang-success-worker-1 1/1 Running 0 17s查看 PodGroupkubectl -n volcano-demo get podgroup输出如下NAME STATUS MINMEMBER RUNNINGS AGE vcjob-gang-success-b731581b-ea2f-4d6b-b936-35bbb842b5f5 Running 2 2 23s4. 结果分析该 Job 的核心配置是minAvailable: 2 tasks: - name: worker replicas: 2这表示该 Job 需要创建 2 个 worker Pod并且至少要有 2 个 Pod 同时满足调度条件后Volcano 才会放行。从实验结果可以看到MINAVAILABLE 2 RUNNINGS 2同时 PodGroup 中也显示MINMEMBER 2 RUNNINGS 2这说明 Volcano 已经将该 Job 转换为一个 PodGroup 进行调度并且当前集群资源满足该 PodGroup 的最小运行要求。因此两个 worker Pod 被一起调度成功。这里的重点不是“创建了两个 Pod”而是 Volcano 在调度前确认了这两个 Pod 作为一个整体满足最小运行条件。五、测试三Gang Scheduling 失败场景1. 测试目标该测试用于验证资源不足时Volcano 是否会阻止 PodGroup 被部分调度。为了便于观察效果下面示例故意让每个 Pod 申请较大的内存。我的测试环境是 32Gi 内存的单节点 Kubernetes 集群每个 Pod 申请 20Gi 内存两个 Pod 总共需要 40Gi 内存因此无法同时满足minAvailable: 2的要求。如果测试节点内存更大可以将20Gi调整为更高值例如100Gi或200Gi确保资源不足。2. YAML 示例apiVersion: batch.volcano.sh/v1alpha1 kind: Job metadata: name: vcjob-gang-pending namespace: volcano-demo spec: schedulerName: volcano queue: default minAvailable: 2 maxRetry: 1 tasks: - name: worker replicas: 2 template: spec: restartPolicy: Never containers: - name: busybox image: busybox:latest imagePullPolicy: IfNotPresent command: - sh - -c - | echo should-not-start sleep 3600 resources: requests: cpu: 100m memory: 20Gi limits: cpu: 100m memory: 20Gi3. 验证结果查看 VolcanoJobkubectl -n volcano-demo get vcjob输出如下NAME STATUS MINAVAILABLE RUNNINGS AGE vcjob-gang-pending Pending 2 13s查看 PodGroupkubectl -n volcano-demo get podgroup输出如下NAME STATUS MINMEMBER RUNNINGS AGE vcjob-gang-pending-5fbf33e1-39c5-4938-af57-88bb2c9f8b2e Pending 2 17s查看 PodGroup 事件kubectl -n volcano-demo describe podgroup vcjob-gang-pending-5fbf33e1-39c5-4938-af57-88bb2c9f8b2e输出如下Status: Phase: Pending Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Unschedulable 8s (x25 over 33s) volcano resource in cluster is overused: overused memory Warning Unschedulable 8s (x25 over 33s) volcano 0/0 tasks in gang unschedulable: pod group is not ready, 2 minAvailable4. 结果分析该测试的核心配置是minAvailable: 2 replicas: 2同时每个 Pod 的内存请求为requests: memory: 20Gi两个 Pod 总共需要 40Gi 内存而测试节点只有 32Gi 内存无法同时满足两个 Pod 的资源请求。因此 Volcano 将该 Job 保持在 Pending 状态。PodGroup 事件中最关键的信息是resource in cluster is overused: overused memory这说明当前集群内存资源无法满足该 PodGroup 的最小运行需求。另一条事件pod group is not ready, 2 minAvailable说明 Volcano 当前没有满足minAvailable2的条件因此不会放行这组 Pod。这里需要注意不要只看0/0 tasks in gang unschedulable这一段。真正的根因要结合上面的事件一起看。本例中根因是内存资源不足也就是overused memory这正是 Gang Scheduling 的核心效果当两个 Pod 不能同时满足调度条件时Volcano 不会只启动其中一个 Pod而是让整个 PodGroup 等待资源满足。六、测试四Queue 队列资源限制1. 测试目标该测试用于验证 Volcano Queue 的资源管理能力。Queue 是 Volcano 中用于组织 PodGroup 的队列资源可以作为多租户、团队隔离、资源分配的基础对象。本测试重点验证 Queue 的capability字段。capability表示该 Queue 可使用资源的上限属于硬约束。也就是说如果一个 PodGroup 的资源需求超过 Queue 的 capability该 PodGroup 不应被正常调度。需要注意Queue 的资源控制依赖 Volcano Scheduler 中启用的队列相关插件例如proportion或capacity。如果手动修改过volcano-scheduler-configmap需要确认队列插件没有被关闭。2. 创建 small-queueapiVersion: scheduling.volcano.sh/v1beta1 kind: Queue metadata: name: small-queue spec: weight: 1 reclaimable: false capability: cpu: 500m memory: 512Mi查看 Queuekubectl get queue输出如下NAME PARENT default root root small-queue root查看small-queue详情kubectl describe queue small-queue输出如下Name: small-queue API Version: scheduling.volcano.sh/v1beta1 Kind: Queue Spec: Capability: Cpu: 500m Memory: 512Mi Dequeue Strategy: traverse Parent: root Reclaimable: false Weight: 1 Status: Allocated: Cpu: 0 Memory: 0 Reservation: State: Open Events: none3. Queue 结果分析从输出可以看到State: Open表示small-queue当前处于可用状态可以接收新的 PodGroup。Allocated: Cpu: 0 Memory: 0表示当前该 Queue 已经分配出去的资源为 0。也就是说此时还没有运行中的 PodGroup 占用该 Queue 的资源。Capability: Cpu: 500m Memory: 512Mi表示该 Queue 最多只能使用 500m CPU 和 512Mi 内存。后续提交到该 Queue 的 Job资源使用量不能超过这个上限。4. 创建未超过 Queue capability 的 JobapiVersion: batch.volcano.sh/v1alpha1 kind: Job metadata: name: vcjob-small-queue-ok namespace: volcano-demo spec: schedulerName: volcano queue: small-queue minAvailable: 1 tasks: - name: worker replicas: 1 policies: - event: TaskCompleted action: CompleteJob template: spec: restartPolicy: Never containers: - name: busybox image: busybox:latest imagePullPolicy: IfNotPresent command: - sh - -c - | echo queue-ok sleep 6000 resources: requests: cpu: 200m memory: 128Mi limits: cpu: 200m memory: 128Mi该 Job 申请的资源为cpu: 200m memory: 128Mi而small-queue的资源上限为cpu: 500m memory: 512Mi因此该 Job 没有超过 Queue 的 capability应能够正常调度。验证结果如下kubectl get pod -n volcano-demoNAME READY STATUS RESTARTS AGE vcjob-small-queue-ok-worker-0 1/1 Running 0 7s查看 PodGroupkubectl get podgroup -n volcano-demoNAME STATUS MINMEMBER RUNNINGS vcjob-small-queue-ok-b0b82002-a693-4c89-98a6-23d1fa43e0ba Running 1 1查看 VolcanoJobkubectl get vcjob -n volcano-demoNAME STATUS MINAVAILABLE RUNNINGS AGE vcjob-small-queue-ok Running 1 1 29s5. 结果分析该 Job 使用的是queue: small-queue并且minAvailable为 1task 副本数也为 1。从实验结果可以看到PodGroup 状态为 RunningMINMEMBER1RUNNINGS1说明该 PodGroup 已经满足最小运行条件并且没有超过 Queue 的 capability 限制。这个实验说明当 Job 的资源请求没有超过 Queue 的资源上限时Volcano 可以正常调度该 Job。6. 创建超过 Queue capability 的 JobapiVersion: batch.volcano.sh/v1alpha1 kind: Job metadata: name: vcjob-small-queue-over namespace: volcano-demo spec: schedulerName: volcano queue: small-queue minAvailable: 1 tasks: - name: worker replicas: 1 template: spec: restartPolicy: Never containers: - name: busybox image: busybox:latest imagePullPolicy: IfNotPresent command: - sh - -c - | echo queue-over sleep 3600 resources: requests: cpu: 1 memory: 128Mi limits: cpu: 1 memory: 128Mi该 Job 申请的资源为cpu: 1 memory: 128Mi而small-queue的 CPU 上限只有cpu: 500m因此该 Job 的 CPU 请求超过了 Queue 的 capability。验证结果如下kubectl get vcjob -n volcano-demoNAME STATUS MINAVAILABLE RUNNINGS AGE vcjob-small-queue-over Pending 1 5s查看 PodGroupkubectl get podgroup -n volcano-demoNAME STATUS MINMEMBER RUNNINGS AGE vcjob-small-queue-over-89a74ecf-2cca-4eff-afec-2d5570a77db7 Pending 1 9s查看 PodGroup 事件kubectl describe podgroup vcjob-small-queue-over-89a74ecf-2cca-4eff-afec-2d5570a77db7 -n volcano-demo输出如下Status: Phase: Pending Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Unschedulable 21s (x25 over 45s) volcano queue resource quota insufficient: insufficient cpu Warning Unschedulable 21s (x25 over 45s) volcano 0/0 tasks in gang unschedulable: pod group is not ready, 1 minAvailable7. 结果分析该实验中最关键的事件是queue resource quota insufficient: insufficient cpu这句话表示不是节点 CPU 一定不足而是 Queue 的资源额度不足。也就是说当前 PodGroup 所属的small-queue只有 500m CPU capability而 Job 申请了 1 核 CPU超过了该 Queue 的资源上限。因此 Volcano 不会调度该 PodGroup。这里要区分两类资源不足第一类是集群资源不足例如前面 Gang Scheduling 失败场景中的resource in cluster is overused: overused memory这表示集群维度资源不够。第二类是队列资源额度不足例如本测试中的queue resource quota insufficient: insufficient cpu这表示 Queue 维度资源额度不够即使集群整体可能还有资源也不能突破该 Queue 的 capability 上限。8. Queue 字段说明weight: 1表示队列权重。使用proportion插件时Volcano 会根据所有队列的 weight 计算队列应得资源比例。weight是软约束不是硬限制。reclaimable: false表示当该队列使用了超过自身应得资源的部分时是否允许其他队列回收这部分超额资源。设置为false后其他队列不能回收该队列已经占用的超额资源。实验环境中设置为false主要是为了减少资源回收带来的干扰。capability: cpu: 500m memory: 512Mi表示该队列可使用资源的上限。capability是硬约束超过该上限的 PodGroup 不应被调度运行。七、测试五普通 Deployment 使用 Volcano 调度1. 测试目标Volcano 不只支持 VolcanoJob也可以调度 Kubernetes 原生工作负载例如 Deployment、StatefulSet、Kubernetes Job 等。对于普通工作负载如果希望使用 Volcano 的 Gang Scheduling需要同时满足两个条件第一在工作负载上层资源中配置scheduling.volcano.sh/group-min-member: 2第二在 Pod 模板中指定schedulerName: volcano这两个配置缺一不可。group-min-member用于告诉 Volcano这个工作负载最少需要多少个 Pod 作为一组满足调度条件。schedulerName: volcano用于告诉 Kubernetes这个工作负载创建出来的 Pod 要交给 Volcano Scheduler 调度。如果只写group-min-member但没有写schedulerName: volcanoPod 仍然会走默认调度器不会真正使用 Volcano 的调度能力。如果只写schedulerName: volcano但没有写group-min-memberPod 可以交给 Volcano 调度但普通工作负载不会体现指定最小成员数的 Gang Scheduling 效果。2. YAML 示例apiVersion: apps/v1 kind: Deployment metadata: name: volcano-deploy-gang namespace: volcano-demo annotations: scheduling.volcano.sh/group-min-member: 2 spec: replicas: 2 selector: matchLabels: app: volcano-deploy-gang template: metadata: labels: app: volcano-deploy-gang annotations: scheduling.volcano.sh/queue-name: default spec: schedulerName: volcano containers: - name: busybox image: busybox:latest imagePullPolicy: IfNotPresent command: - sh - -c - | echo deployment gang pod started: $(hostname) sleep 3600 resources: requests: cpu: 100m memory: 20Gi limits: cpu: 100m memory: 20Gi3. 验证结果查看 Podkubectl -n volcano-demo get pod输出如下NAME READY STATUS RESTARTS AGE volcano-deploy-gang-5dc6b66cfc-4b597 0/1 Pending 0 7s volcano-deploy-gang-5dc6b66cfc-tsfnh 0/1 Pending 0 7s查看 PodGroupkubectl -n volcano-demo get podgroup输出如下NAME STATUS MINMEMBER RUNNINGS AGE podgroup-89bcd154-6137-49f5-9eb6-aaa0f39023fc Pending 2 15s查看其中一个 Podkubectl -n volcano-demo describe pod volcano-deploy-gang-5dc6b66cfc-4b597关键输出如下Name: volcano-deploy-gang-5dc6b66cfc-4b597 Namespace: volcano-demo Node: none Labels: appvolcano-deploy-gang pod-template-hash5dc6b66cfc Annotations: scheduling.k8s.io/group-name: podgroup-89bcd154-6137-49f5-9eb6-aaa0f39023fc Status: Pending Controlled By: ReplicaSet/volcano-deploy-gang-5dc6b66cfc Containers: busybox: Image: busybox:latest Limits: cpu: 100m memory: 20Gi Requests: cpu: 100m memory: 20Gi Conditions: Type Status PodScheduled False Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 58s volcano pod group is not ready, 2 Pending, 2 minAvailable; Pending: 2 Unschedulable4. 结果分析从 Pod 输出可以看到两个 Deployment Pod 都处于 PendingSTATUS Pending该 Deployment 配置了 2 个副本每个 Pod 申请 20Gi 内存总共需要 40Gi 内存而测试环境是 32Gi 单节点集群无法同时满足两个 Pod 的资源需求。从 PodGroup 输出可以看到STATUS Pending MINMEMBER 2 RUNNINGS这说明 Volcano 已经为这个 Deployment 自动创建了 PodGroup并且该 PodGroup 的最小成员数是 2。但是当前没有 Pod 被成功调度所以RUNNINGS为空。Pod 的 annotation 中有scheduling.k8s.io/group-name: podgroup-89bcd154-6137-49f5-9eb6-aaa0f39023fc这说明该 Pod 已经被 Volcano 关联到了对应的 PodGroup。也就是说这个 Deployment 创建出来的 Pod 已经不再是单独按普通 Pod 进行调度而是被纳入 PodGroup 的 Gang Scheduling 逻辑中。5. 关键字段说明metadata: annotations: scheduling.volcano.sh/group-min-member: 2该注解写在 Deployment 的metadata.annotations下用于声明该 Deployment 至少需要 2 个 Pod 作为一组满足调度条件。普通 Deployment 本身不是 VolcanoJob因此需要通过这个注解告诉 Volcano这个普通工作负载也需要按 PodGroup 方式进行成组调度。spec: template: metadata: annotations: scheduling.volcano.sh/queue-name: default该注解写在 Pod template 下用于指定 PodGroup 所属队列。最终创建出来的 Pod 会携带该注解Volcano 在创建 PodGroup 时会根据该信息设置 queue。spec: template: spec: schedulerName: volcano该字段必须写在 Pod 模板中。Deployment 本身不会直接被调度真正被调度的是 Deployment 创建出来的 Pod。因此schedulerName: volcano必须出现在spec.template.spec下。6. 普通 Deployment 的 PodGroup 创建逻辑普通 Deployment 使用 Volcano Gang Scheduling 的大致流程如下Deployment | v ReplicaSet | v Pod | v Volcano PodGroup Controller | v 自动创建或更新 PodGroup | v Volcano Scheduler 按 PodGroup 调度Deployment 并不会直接变成 VolcanoJob。它仍然是 Kubernetes 原生 Deployment。真正发生的是Deployment 创建 ReplicaSetReplicaSet 创建 PodPod 模板中指定了schedulerName: volcanoDeployment 上配置了scheduling.volcano.sh/group-min-memberVolcano Controller 根据这些信息自动创建 PodGroupVolcano Scheduler 根据 PodGroup 的minMember和资源需求进行调度调度成功后Pod 会绑定到节点资源不足时PodGroup 保持 Pending。从实验中的 Pod annotation 可以看到scheduling.k8s.io/group-name: podgroup-89bcd154-6137-49f5-9eb6-aaa0f39023fc这就是 Volcano 将 Pod 关联到 PodGroup 的结果。同时Pod 的Controlled By字段显示Controlled By: ReplicaSet/volcano-deploy-gang-5dc6b66cfc说明这个 Pod 的上层控制器仍然是 ReplicaSet。也就是说Deployment 的工作负载控制逻辑仍然由 Kubernetes 原生控制器负责Volcano 只负责调度层面的成组调度。八、核心概念补充1. VolcanoJob 与 Kubernetes Job 的区别VolcanoJob 是 Volcano 自定义资源apiVersion: batch.volcano.sh/v1alpha1 kind: JobKubernetes 原生 Job 是apiVersion: batch/v1 kind: Job两者不是同一种资源。查看 VolcanoJobkubectl get vcjob -n volcano-demo查看 Kubernetes 原生 Jobkubectl get job -n volcano-demoVolcanoJob 更适合批计算、AI 训练、MPI、分布式任务等场景因为它天然集成了 PodGroup、Queue、Gang Scheduling 等能力。2. minAvailable 与 replicas 的关系replicas表示 task 需要创建多少个 Pod。minAvailable表示整个 VolcanoJob 至少需要多少个 Pod 同时满足调度条件。例如tasks: - replicas: 3 minAvailable: 2表示该 Job 总共期望创建 3 个 Pod但至少有 2 个 Pod 可以调度时Job 就可以进入运行状态。如果希望所有 Pod 都必须同时满足调度条件应设置minAvailable 所有 task 的 replicas 总数例如tasks: - replicas: 2 minAvailable: 2这表示两个 Pod 必须同时满足调度条件。3. PodGroup 是 Volcano 调度的关键对象PodGroup 是 Volcano 成组调度的核心对象用于描述一组 Pod 的最小运行条件。核心字段包括spec: minMember: 2 queue: default minResources: cpu: 200m memory: 128Mi字段含义如下字段说明minMemberPodGroup 中至少需要多少个 Pod 或 task 运行queuePodGroup 所属 QueueminResourcesPodGroup 满足最小运行条件所需的资源priorityClassNamePodGroup 的优先级status.phasePodGroup 当前状态PodGroup 的常见状态如下状态含义Pending已被 Volcano 接收但资源条件尚未满足Inqueue已通过队列校验等待调度Running至少已有 minMember 数量的 Pod 正在运行Unknown部分 Pod 运行部分 Pod 未被调度通常与资源不足有关4. Gang Scheduling 的本质Gang Scheduling 不是简单地创建多个 Pod也不是让多个 Pod 的创建时间尽量接近。它的核心是调度约束达到最小成员数则整体调度 达不到最小成员数则整体等待。例如一个训练任务需要 2 个 workerreplicas: 2 minAvailable: 2如果资源只够启动 1 个 workerVolcano 不会只启动其中一个而是让整个 PodGroup 等待资源满足。5. Queue capability 与 weight 的区别capability是硬约束表示队列最多可以使用多少资源。capability: cpu: 500m memory: 512Mi超过该上限的任务不应被正常调度。weight是软约束主要用于proportion插件计算队列之间的资源分配比例。weight: 1当集群资源空闲时某个队列可能临时使用超过其应得值的资源当其他队列需要资源时超额使用的资源可能被回收或重新分配。6. 普通工作负载使用 Volcano 的必要条件普通 Deployment、StatefulSet、Kubernetes Job 想使用 Volcano 调度需要满足以下条件第一Pod 模板中必须指定 Volcano 调度器spec: template: spec: schedulerName: volcano第二如果希望使用 Gang Scheduling需要在上层工作负载中配置metadata: annotations: scheduling.volcano.sh/group-min-member: 2第三如果希望指定 Queue可以在 Pod 模板中配置spec: template: metadata: annotations: scheduling.volcano.sh/queue-name: default其中最容易遗漏的是schedulerName: volcano。如果不写这个字段Pod 不会交给 Volcano Scheduler 调度group-min-member也就无法真正体现 Volcano 的 Gang Scheduling 效果。九、总结本文主要验证了 Volcano 的几个基础能力。第一Volcano 可以通过 Helm 快速部署核心组件包括volcano-scheduler、volcano-controllers、volcano-admission。第二VolcanoJob 使用的是 Volcano 自定义 CRDapiVersion: batch.volcano.sh/v1alpha1 kind: Job它与 Kubernetes 原生 Job 不是同一个资源。第三Gang Scheduling 的核心是 PodGroup。对于 VolcanoJob通常通过minAvailable控制最小可运行 Pod 数对于 PodGroup则对应minMember。第四Queue 可以用于队列级资源管理。其中capability是资源上限属于硬约束weight用于资源比例划分属于软约束。第五普通 Deployment、StatefulSet、Kubernetes Job 也可以使用 Volcano 调度。如果希望普通工作负载使用 Volcano Gang Scheduling需要同时配置scheduling.volcano.sh/group-min-member: 2以及schedulerName: volcano其中group-min-member用于声明最小成组调度数量schedulerName: volcano用于确保 Pod 交给 Volcano Scheduler 调度。两者缺一不可。整体来看Volcano 的核心价值不是简单地提供一个新的 Job 类型而是为 Kubernetes 增强了批处理、成组调度和队列资源管理能力。对于 AI 训练、大数据计算、HPC 等场景Volcano 能够更好地表达“任务组整体运行”的调度语义避免只启动部分 Pod 导致任务无法运行和资源浪费。