Volcano 部署与基础功能测试:VolcanoJob、Gang Scheduling、Queue 与 Deployment 调度验证
2026/6/13 20:24:57 网站建设 项目流程

一、Volcano 简介

Volcano 是一个 Kubernetes 原生的批调度系统,主要面向 AI 训练、大数据计算、HPC、高性能批处理等场景。

相比 Kubernetes 默认调度器,Volcano 更关注“成组任务”的调度语义。例如分布式训练中的多个 worker、parameter server、MPI 任务等,这类任务往往不是单个 Pod 能独立完成的,而是需要一组 Pod 同时满足资源条件后才具备运行意义。

在普通 Kubernetes 调度中,Pod 通常是以单个对象为单位进行调度;而在分布式训练场景中,如果只启动其中一部分 Pod,任务可能无法正常运行,同时还会占用集群资源。Volcano 的 Gang Scheduling 就是为了解决这类问题。

Volcano 的核心能力主要包括:

  • VolcanoJob:Volcano 提供的批任务 CRD;

  • PodGroup:一组成组调度 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 update

2. 安装 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_policy=IfNotPresent

其中:

--set basic.image_pull_policy=IfNotPresent

不是必需参数,主要用于实验环境中减少重复拉取镜像。

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 是否能够创建对应 Pod;

  • Volcano Scheduler 是否能够调度 Pod;

  • VolcanoJob 是否会自动关联 PodGroup;

  • TaskCompleted -> 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: "64Mi"

3. 验证结果

查看 VolcanoJob:

kubectl -n volcano-demo get vcjob

输出如下:

NAME STATUS MINAVAILABLE RUNNINGS AGE vcjob-basic Running 1 1 13s

查看 PodGroup:

kubectl -n volcano-demo get podgroup

输出如下:

NAME STATUS MINMEMBER RUNNINGS AGE vcjob-basic-90ac694a-9eae-4cfb-aef2-e14c7ef7cd5a Running 1 1 20s

查看 Pod:

kubectl -n volcano-demo get pod

输出如下:

NAME READY STATUS RESTARTS AGE vcjob-basic-basic-task-0 0/1 Completed 0 23s

4. 结果分析

这个测试中,vcjob-basicminAvailable为 1,task 副本数也是 1,因此只要这个 Pod 能够被调度,整个 Job 就满足最小运行条件。从 PodGroup 可以看到:

STATUS Running MINMEMBER 1 RUNNINGS 1

说明 Volcano 已经为该 VolcanoJob 创建了对应的 PodGroup,并且 PodGroup 当前满足最小成员数要求。Pod 最终变成:

STATUS Completed

这是正常现象。因为 busybox 容器执行完echosleep 20后会正常退出,restartPolicy: Never表示容器退出后不会重启,所以 Pod 状态会变成 Completed。

需要注意的是,kubectl get vcjob中 Job 状态从 Running 变为 Completed 可能会有一个短暂的 controller 同步延迟。只要 Pod 已经 Completed,并且配置了:

policies: - event: TaskCompleted action: CompleteJob

Volcano 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: "64Mi"

3. 验证结果

查看 VolcanoJob:

kubectl -n volcano-demo get vcjob

输出如下:

NAME STATUS MINAVAILABLE RUNNINGS AGE vcjob-gang-success Running 2 2 15s

查看 Pod:

kubectl -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

查看 PodGroup:

kubectl -n volcano-demo get podgroup

输出如下:

NAME STATUS MINMEMBER RUNNINGS AGE vcjob-gang-success-b731581b-ea2f-4d6b-b936-35bbb842b5f5 Running 2 2 23s

4. 结果分析

该 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调整为更高值,例如100Gi200Gi,确保资源不足。

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: "20Gi"

3. 验证结果

查看 VolcanoJob:

kubectl -n volcano-demo get vcjob

输出如下:

NAME STATUS MINAVAILABLE RUNNINGS AGE vcjob-gang-pending Pending 2 13s

查看 PodGroup:

kubectl -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 minAvailable

4. 结果分析

该测试的核心配置是:

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 当前没有满足minAvailable=2的条件,因此不会放行这组 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 中启用的队列相关插件,例如proportioncapacity。如果手动修改过volcano-scheduler-configmap,需要确认队列插件没有被关闭。

2. 创建 small-queue

apiVersion: scheduling.volcano.sh/v1beta1 kind: Queue metadata: name: small-queue spec: weight: 1 reclaimable: false capability: cpu: "500m" memory: "512Mi"

查看 Queue:

kubectl 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: <none>

3. 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 的 Job

apiVersion: 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-demo
NAME READY STATUS RESTARTS AGE vcjob-small-queue-ok-worker-0 1/1 Running 0 7s

查看 PodGroup:

kubectl get podgroup -n volcano-demo
NAME STATUS MINMEMBER RUNNINGS vcjob-small-queue-ok-b0b82002-a693-4c89-98a6-23d1fa43e0ba Running 1 1

查看 VolcanoJob:

kubectl get vcjob -n volcano-demo
NAME STATUS MINAVAILABLE RUNNINGS AGE vcjob-small-queue-ok Running 1 1 29s

5. 结果分析

该 Job 使用的是:

queue: small-queue

并且minAvailable为 1,task 副本数也为 1。

从实验结果可以看到,PodGroup 状态为 Running,MINMEMBER=1RUNNINGS=1,说明该 PodGroup 已经满足最小运行条件,并且没有超过 Queue 的 capability 限制。

这个实验说明:当 Job 的资源请求没有超过 Queue 的资源上限时,Volcano 可以正常调度该 Job。

6. 创建超过 Queue capability 的 Job

apiVersion: 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-demo
NAME STATUS MINAVAILABLE RUNNINGS AGE vcjob-small-queue-over Pending 1 5s

查看 PodGroup:

kubectl get podgroup -n volcano-demo
NAME 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 minAvailable

7. 结果分析

该实验中最关键的事件是:

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: volcano,Pod 仍然会走默认调度器,不会真正使用 Volcano 的调度能力。

如果只写schedulerName: volcano,但没有写group-min-member,Pod 可以交给 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: "20Gi"

3. 验证结果

查看 Pod:

kubectl -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

查看 PodGroup:

kubectl -n volcano-demo get podgroup

输出如下:

NAME STATUS MINMEMBER RUNNINGS AGE podgroup-89bcd154-6137-49f5-9eb6-aaa0f39023fc Pending 2 15s

查看其中一个 Pod:

kubectl -n volcano-demo describe pod volcano-deploy-gang-5dc6b66cfc-4b597

关键输出如下:

Name: volcano-deploy-gang-5dc6b66cfc-4b597 Namespace: volcano-demo Node: <none> Labels: app=volcano-deploy-gang pod-template-hash=5dc6b66cfc 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 Unschedulable

4. 结果分析

从 Pod 输出可以看到,两个 Deployment Pod 都处于 Pending:

STATUS 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。

真正发生的是:

  1. Deployment 创建 ReplicaSet;

  2. ReplicaSet 创建 Pod;

  3. Pod 模板中指定了schedulerName: volcano

  4. Deployment 上配置了scheduling.volcano.sh/group-min-member

  5. Volcano Controller 根据这些信息自动创建 PodGroup;

  6. Volcano Scheduler 根据 PodGroup 的minMember和资源需求进行调度;

  7. 调度成功后,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: Job

Kubernetes 原生 Job 是:

apiVersion: batch/v1 kind: Job

两者不是同一种资源。

查看 VolcanoJob:

kubectl get vcjob -n volcano-demo

查看 Kubernetes 原生 Job:

kubectl get job -n volcano-demo

VolcanoJob 更适合批计算、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 所属 Queue
minResourcesPodGroup 满足最小运行条件所需的资源
priorityClassNamePodGroup 的优先级
status.phasePodGroup 当前状态

PodGroup 的常见状态如下:

状态含义
Pending已被 Volcano 接收,但资源条件尚未满足
Inqueue已通过队列校验,等待调度
Running至少已有 minMember 数量的 Pod 正在运行
Unknown部分 Pod 运行,部分 Pod 未被调度,通常与资源不足有关

4. Gang Scheduling 的本质

Gang Scheduling 不是简单地创建多个 Pod,也不是让多个 Pod 的创建时间尽量接近。

它的核心是调度约束:

达到最小成员数,则整体调度; 达不到最小成员数,则整体等待。

例如,一个训练任务需要 2 个 worker:

replicas: 2 minAvailable: 2

如果资源只够启动 1 个 worker,Volcano 不会只启动其中一个,而是让整个 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-schedulervolcano-controllersvolcano-admission

第二,VolcanoJob 使用的是 Volcano 自定义 CRD:

apiVersion: 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 导致任务无法运行和资源浪费。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询