Volcano Job API 完整参考

1. 概述

Volcano Job 是 Volcano 批量调度系统的核心 CRD,定义在 batch.volcano.sh/v1alpha1 API Group 中。它扩展了 Kubernetes 原生 Job 的能力,提供了多任务(Multi-Task)、Gang 调度、生命周期策略、分区调度、网络拓扑感知等高级特性。

源码位置staging/src/volcano.sh/apis/pkg/apis/batch/v1alpha1/job.go

1.1 CRD 注册信息

属性
API Groupbatch.volcano.sh
API Versionv1alpha1
KindJob
Resource Pathjobs
Short Namesvcjob, vj
ScopeNamespaced
Subresourcestatus

1.2 kubebuilder Markers

// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:object:root=true
// +kubebuilder:resource:path=jobs,shortName=vcjob;vj
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="STATUS",type=string,JSONPath=`.status.state.phase`
// +kubebuilder:printcolumn:name="minAvailable",type=integer,JSONPath=`.status.minAvailable`
// +kubebuilder:printcolumn:name="RUNNINGS",type=integer,JSONPath=`.status.running`
// +kubebuilder:printcolumn:name="AGE",type=date,JSONPath=`.metadata.creationTimestamp`
// +kubebuilder:printcolumn:name="QUEUE",type=string,priority=1,JSONPath=`.spec.queue`

1.3 kubectl 输出列

执行 kubectl get vcjob 时显示的列:

列名类型JSONPath优先级
STATUSstring.status.state.phase默认
minAvailableinteger.status.minAvailable默认
RUNNINGSinteger.status.running默认
AGEdate.metadata.creationTimestamp默认
QUEUEstring.spec.queue1 (扩展)

2. Job 顶层结构

type Job struct {
    metav1.TypeMeta   `json:",inline"`
    metav1.ObjectMeta `json:"metadata,omitempty"`
    Spec   JobSpec    `json:"spec,omitempty"`
    Status JobStatus  `json:"status,omitempty"`
}
classDiagram class Job { +TypeMeta +ObjectMeta metadata +JobSpec spec +JobStatus status } class JobSpec { +string schedulerName +int32 minAvailable +VolumeSpec[] volumes +TaskSpec[] tasks +LifecyclePolicy[] policies +map~string,string[]~ plugins +Duration runningEstimate +string queue +int32 maxRetry +int32* ttlSecondsAfterFinished +string priorityClassName +int32* minSuccess +NetworkTopologySpec* networkTopology } class JobStatus { +JobState state +int32 minAvailable +map~string,TaskState~ taskStatusCount +int32 pending +int32 running +int32 succeeded +int32 failed +int32 terminating +int32 unknown +int32 version +int32 retryCount +Duration runningDuration +map~string,string~ controlledResources +JobCondition[] conditions } Job --> JobSpec Job --> JobStatus JobSpec --> TaskSpec JobSpec --> VolumeSpec JobSpec --> LifecyclePolicy JobSpec --> NetworkTopologySpec JobStatus --> JobState JobStatus --> TaskState JobStatus --> JobCondition

3. JobSpec 完整字段参考

3.1 字段总览

字段类型必填默认值验证规则说明
schedulerNamestring-MaxLength=63调度器名称,作为 tasks.template.spec.schedulerName 默认值
minAvailableint32tasks replicas 之和Minimum=0Gang 调度最小可用 Pod 数
volumes[]VolumeSpec--Job 级别的卷挂载定义
tasks[]TaskSpec-MinItems=1任务规格定义列表
policies[]LifecyclePolicy--默认生命周期策略
pluginsmap[string][]string--插件配置,Key=插件名,Value=参数列表
runningEstimate*metav1.Durationnil-用户预估的运行时长
queuestring"default"MaxLength=253, DNS label pattern所属队列名称
maxRetryint323Minimum=0最大重试次数
ttlSecondsAfterFinished*int32nilMinimum=0完成后自动清理等待秒数
priorityClassNamestring-MaxLength=253, DNS label pattern优先级类名称
minSuccess*int32nilMinimum=1最小成功 Pod 数,达到即视为 Job 完成
networkTopology*NetworkTopologySpecnil-网络拓扑约束

3.2 schedulerName

指定调度器名称。该值会作为 tasks[*].template.spec.schedulerName 的默认值。当使用 Volcano Scheduler 时通常设置为 "volcano"

spec:
  schedulerName: volcano

3.3 minAvailable

定义 Gang 调度的最小可用 Pod 数。只有当集群能同时满足 minAvailable 个 Pod 的资源需求时,调度器才会开始调度该 Job 的 Pod。

  • 若未设置,默认为所有 tasks 的 replicas 之和
  • 设置为 0 表示不启用 Gang 调度
spec:
  minAvailable: 4  # 至少 4 个 Pod 才能启动
  tasks:
    - name: worker
      replicas: 8

3.4 queue

指定 Job 所属的资源队列。调度器根据队列进行资源分配和公平调度。

  • 默认值为 "default"
  • 队列名称必须符合 DNS label 命名规范:^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
  • 最大长度 253 字符

3.5 maxRetry

Job 级别的最大重试次数。当 Job 因错误重启时,超过此次数将标记为 Failed。

  • 默认值为 3
  • 设置为 0 表示不重试

3.6 ttlSecondsAfterFinished

Job 完成(Completed 或 Failed)后,等待指定秒数自动删除:

  • nil - 不自动删除
  • 0 - 立即删除
  • N - 等待 N 秒后删除

3.7 minSuccess

定义 Job 成功所需的最少 Pod 完成数。当成功完成的 Pod 数达到该值时,Job 即被视为成功完成。

  • 未设置时需所有 Pod 成功
  • Minimum=1

4. TaskSpec 详解

4.1 TaskSpec 结构

type TaskSpec struct {
    Name            string              `json:"name,omitempty"`
    Replicas        int32               `json:"replicas,omitempty"`
    MinAvailable    *int32              `json:"minAvailable,omitempty"`
    Template        v1.PodTemplateSpec  `json:"template,omitempty"`
    Policies        []LifecyclePolicy   `json:"policies,omitempty"`
    TopologyPolicy  NumaPolicy          `json:"topologyPolicy,omitempty"`
    MaxRetry        int32               `json:"maxRetry,omitempty"`
    DependsOn       *DependsOn          `json:"dependsOn,omitempty"`
    PartitionPolicy *PartitionPolicySpec `json:"partitionPolicy,omitempty"`
}

4.2 字段说明

字段类型必填默认值验证规则说明
namestring-MaxLength=63, DNS label patternTask 名称
replicasint32-Minimum=0该 Task 的 Pod 副本数
minAvailable*int32等于 replicasMinimum=0Task 级 Gang 调度最小 Pod 数
templatev1.PodTemplateSpec--Pod 模板定义
policies[]LifecyclePolicy--Task 级生命周期策略
topologyPolicyNumaPolicy-Enum: none/best-effort/restricted/single-numa-nodeNUMA 拓扑策略
maxRetryint32-Minimum=0Task 级最大重试次数
dependsOn*DependsOn--Task 依赖定义
partitionPolicy*PartitionPolicySpec--分区策略

4.3 NumaPolicy 枚举

TopologyPolicy 控制 NUMA 拓扑感知调度策略:

说明
none不启用 NUMA 拓扑感知
best-effort尽力满足 NUMA 亲和性,不强制
restricted严格遵守 NUMA 策略,但允许跨多个 NUMA 节点
single-numa-node所有资源必须分配在同一个 NUMA 节点上

4.4 多 Task 示例

spec:
  minAvailable: 3
  tasks:
    - name: ps
      replicas: 1
      template:
        spec:
          containers:
            - name: ps
              image: tensorflow/tensorflow:latest
    - name: worker
      replicas: 4
      minAvailable: 2
      template:
        spec:
          containers:
            - name: worker
              image: tensorflow/tensorflow:latest-gpu
              resources:
                limits:
                  nvidia.com/gpu: 1

5. PartitionPolicySpec 详解

5.1 结构定义

type PartitionPolicySpec struct {
    TotalPartitions int32               `json:"totalPartitions"`
    PartitionSize   int32               `json:"partitionSize"`
    NetworkTopology *NetworkTopologySpec `json:"networkTopology,omitempty"`
    MinPartitions   int32               `json:"minPartitions,omitempty"`
}

5.2 字段说明

字段类型必填默认值验证规则说明
totalPartitionsint32-Minimum=1总分区数
partitionSizeint32-Minimum=1每个分区包含的 Pod 数量
networkTopology*NetworkTopologySpec--分区级网络拓扑约束
minPartitionsint320Minimum=0最小分区数

5.3 核心约束规则

TotalPartitions * PartitionSize == Replicas

分区策略将一个 Task 下的所有 Pod 分为多个组,每组内的 Pod 遵循相同的网络拓扑约束。

flowchart TB subgraph task["Task - worker (Replicas=8)"] subgraph p1["Partition 1 (Size=4)"] Pod1["Pod-0"] Pod2["Pod-1"] Pod3["Pod-2"] Pod4["Pod-3"] end subgraph p2["Partition 2 (Size=4)"] Pod5["Pod-4"] Pod6["Pod-5"] Pod7["Pod-6"] Pod8["Pod-7"] end end note["TotalPartitions=2\nPartitionSize=4\nReplicas=8\n2 * 4 = 8"]

5.4 MinPartitions 的作用

MinPartitions 定义了最少需要调度成功的分区数。当集群资源不足以满足所有分区时,只要满足 MinPartitions 个分区的资源需求即可开始调度。

spec:
  tasks:
    - name: worker
      replicas: 32
      partitionPolicy:
        totalPartitions: 4
        partitionSize: 8
        minPartitions: 2          # 至少 2 个分区(16 Pods)才能调度
        networkTopology:
          mode: hard
          highestTierAllowed: 2

6. VolumeSpec 详解

6.1 结构定义

type VolumeSpec struct {
    MountPath       string                        `json:"mountPath"`
    VolumeClaimName string                        `json:"volumeClaimName,omitempty"`
    VolumeClaim     *v1.PersistentVolumeClaimSpec `json:"volumeClaim,omitempty"`
}

6.2 字段说明

字段类型必填验证规则说明
mountPathstringMinLength=1, 不含 :容器内挂载路径
volumeClaimNamestringMaxLength=253引用已有 PVC 名称
volumeClaim*PersistentVolumeClaimSpec-内联定义 PVC 规格

使用方式二选一:引用已有 PVC(volumeClaimName)或内联创建新 PVC(volumeClaim)。

spec:
  volumes:
    - mountPath: /data
      volumeClaimName: shared-data
    - mountPath: /output
      volumeClaim:
        accessModes: [ "ReadWriteOnce" ]
        resources:
          requests:
            storage: 10Gi

7. LifecyclePolicy 详解

7.1 结构定义

type LifecyclePolicy struct {
    Action   v1alpha1.Action   `json:"action,omitempty"`
    Event    v1alpha1.Event    `json:"event,omitempty"`
    Events   []v1alpha1.Event  `json:"events,omitempty"`
    ExitCode *int32            `json:"exitCode,omitempty"`
    Timeout  *metav1.Duration  `json:"timeout,omitempty"`
}

7.2 XOR 规则

Event/Events 和 ExitCode 是互斥的,只能设置其中之一。

  • 设置 Event/Events:根据 Pod 事件触发 Action
  • 设置 ExitCode:根据容器退出码触发 Action

7.3 Action 枚举

Action说明适用级别
AbortJob中止整个 Job,驱逐所有 Pod,不再重建Job/Task
RestartJob重启整个 JobJob/Task
RestartTask仅重启对应 Task 的所有 PodTask
RestartPod仅重启触发事件的单个 PodTask (Pod 级事件)
RestartPartition重启整个分区组的 PodTask (分区场景)
TerminateJob终止 Job,不可恢复Job/Task
CompleteJob标记 Job 完成,清理未完成 PodJob/Task
ResumeJob恢复被中止的 JobJob

7.4 Event 枚举

Event说明
*匹配所有事件
PodPendingPod 处于 Pending 状态
PodRunningPod 处于 Running 状态
PodFailedPod 失败
PodEvictedPod 被驱逐
Unknown任务不可调度(部分 Pod 调度成功但整体无法满足)
TaskCompletedTask 内所有 Replicas 的 Pod 成功完成
TaskFailedTask 异常结束

7.5 生命周期策略流程

flowchart TD A["Pod/Task 产生事件"] --> B{"匹配 LifecyclePolicy?"} B -->|"否"| C["默认处理"] B -->|"是"| D{"设置了 Timeout?"} D -->|"否"| E["立即执行 Action"] D -->|"是"| F["等待 Timeout"] F --> G{"超时期间状态恢复?"} G -->|"是"| H["取消 Action"] G -->|"否"| E E --> I{"Action 类型"} I --> J["AbortJob - 中止 Job"] I --> K["RestartJob - 重启 Job"] I --> L["RestartTask - 重启 Task"] I --> M["TerminateJob - 终止 Job"] I --> N["CompleteJob - 完成 Job"] I --> O["RestartPod - 重启 Pod"] I --> P["RestartPartition - 重启分区"]

7.6 策略配置示例

spec:
  # Job 级策略
  policies:
    - event: PodEvicted
      action: RestartJob
    - event: PodFailed
      action: AbortJob
      timeout: 30s
  tasks:
    - name: worker
      replicas: 4
      # Task 级策略(覆盖 Job 级策略)
      policies:
        - event: PodFailed
          action: RestartTask
        - exitCode: 137        # OOMKilled
          action: RestartPod

8. JobStatus 详解

8.1 结构定义

type JobStatus struct {
    State               JobState                `json:"state,omitempty"`
    MinAvailable        int32                   `json:"minAvailable,omitempty"`
    TaskStatusCount     map[string]TaskState    `json:"taskStatusCount,omitempty"`
    Pending             int32                   `json:"pending,omitempty"`
    Running             int32                   `json:"running,omitempty"`
    Succeeded           int32                   `json:"succeeded,omitempty"`
    Failed              int32                   `json:"failed,omitempty"`
    Terminating         int32                   `json:"terminating,omitempty"`
    Unknown             int32                   `json:"unknown,omitempty"`
    Version             int32                   `json:"version,omitempty"`
    RetryCount          int32                   `json:"retryCount,omitempty"`
    RunningDuration     *metav1.Duration        `json:"runningDuration,omitempty"`
    ControlledResources map[string]string       `json:"controlledResources,omitempty"`
    Conditions          []JobCondition          `json:"conditions,omitempty"`
}

8.2 字段说明

字段类型说明
stateJobState当前 Job 状态(Phase/Reason/Message/LastTransitionTime)
minAvailableint32生效的最小可用 Pod 数
taskStatusCountmap[string]TaskState每个 Task 的 Pod 状态分布
pendingint32Pending 状态 Pod 数
runningint32Running 状态 Pod 数
succeededint32Succeeded 状态 Pod 数
failedint32Failed 状态 Pod 数
terminatingint32Terminating 状态 Pod 数
unknownint32Unknown 状态 Pod 数
versionint32Job 当前版本号
retryCountint32已重试次数
runningDuration*metav1.Duration从 Running 到完成的运行时长
controlledResourcesmap[string]stringJob 控制的资源(如 Service, ConfigMap)
conditions[]JobConditionJob 条件历史记录

8.3 JobState 结构

type JobState struct {
    Phase             JobPhase    `json:"phase,omitempty"`
    Reason            string      `json:"reason,omitempty"`
    Message           string      `json:"message,omitempty"`
    LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"`
}

8.4 TaskState 结构

type TaskState struct {
    Phase map[v1.PodPhase]int32 `json:"phase,omitempty"`
}

TaskState 记录了每个 Task 下各 PodPhase 的 Pod 数量。例如:

{
  "taskStatusCount": {
    "worker": {
      "phase": {
        "Running": 3,
        "Pending": 1
      }
    }
  }
}

9. JobPhase 枚举与状态流转

9.1 所有 JobPhase

Phase说明
Pending"Pending"Job 在队列中等待调度
Aborting"Aborting"Job 正在中止,等待释放 Pod
Aborted"Aborted"Job 已被中止(可通过 ResumeJob 恢复)
Running"Running"满足 minAvailable 的 Pod 已运行
Restarting"Restarting"Job 正在重启,等待 Pod 释放和重建
Completing"Completing"所需 Task 已完成,Job 开始清理
Completed"Completed"所有 Task 成功完成
Terminating"Terminating"Job 正在终止,等待释放 Pod
Terminated"Terminated"Job 异常结束(如事件触发)
Failed"Failed"Job 达到最大重试次数后失败

9.2 状态流转图

stateDiagram-v2 [*] --> Pending Pending --> Running : minAvailable Pods scheduled Pending --> Aborting : AbortJob action Pending --> Terminating : TerminateJob action Running --> Completing : Tasks completed / minSuccess reached Running --> Aborting : AbortJob action Running --> Restarting : RestartJob action Running --> Terminating : TerminateJob action Running --> Failed : MaxRetry exceeded Completing --> Completed : All pods cleaned up Aborting --> Aborted : All pods released Aborted --> Restarting : ResumeJob action Restarting --> Pending : Pods released, recreating Terminating --> Terminated : All pods released Completed --> [*] Terminated --> [*] Failed --> [*]

9.3 JobCondition

type JobCondition struct {
    Status             JobPhase     `json:"status"`
    LastTransitionTime *metav1.Time `json:"lastTransitionTime,omitempty"`
}

Conditions 记录了 Job 的状态转换历史,每次 Phase 变化都会追加一条记录。

10. NetworkTopologySpec 详解

10.1 结构定义

type NetworkTopologySpec struct {
    Mode               NetworkTopologyMode `json:"mode,omitempty"`
    HighestTierAllowed *int                `json:"highestTierAllowed,omitempty"`
    HighestTierName    string              `json:"highestTierName,omitempty"`
}

10.2 字段说明

字段类型默认值说明
modeNetworkTopologyMode"hard"拓扑约束模式
highestTierAllowed*intnil允许跨越的最高层级(数字)
highestTierNamestring-允许跨越的最高层级名称

10.3 互斥规则

HighestTierAllowed 和 HighestTierName 不能同时设置。

  • HighestTierAllowed 按层级编号指定
  • HighestTierName 按层级名称指定

10.4 Mode 说明

Mode说明
hard严格模式 - Job 的所有 Pod 必须在指定拓扑范围内,否则不调度
soft柔性模式 - 尽力将 Pod 调度到同一拓扑范围,允许跨边界

10.5 配置示例

spec:
  networkTopology:
    mode: hard
    highestTierAllowed: 2
  tasks:
    - name: worker
      replicas: 8
      # 使用 partitionPolicy 结合拓扑约束
      partitionPolicy:
        totalPartitions: 2
        partitionSize: 4
        networkTopology:
          mode: hard
          highestTierAllowed: 1   # 分区内更严格

11. DependsOn 与 Iteration

11.1 结构定义

type DependsOn struct {
    Name      []string  `json:"name,omitempty"`
    Iteration Iteration `json:"iteration,omitempty"`
}

11.2 Iteration 模式

说明
any任意一个依赖 Task 达到指定状态即触发调度
all所有依赖 Task 必须达到指定状态才触发调度

11.3 Task 依赖示例

spec:
  tasks:
    - name: data-prepare
      replicas: 1
      template: ...

    - name: train
      replicas: 4
      dependsOn:
        name: ["data-prepare"]
        iteration: all     # 等待 data-prepare 完全完成
      template: ...

    - name: evaluate
      replicas: 1
      dependsOn:
        name: ["train"]
        iteration: all
      template: ...

11.4 依赖调度流程

flowchart LR A["data-prepare\n(Replicas=1)"] -->|"all completed"| B["train\n(Replicas=4)"] B -->|"all completed"| C["evaluate\n(Replicas=1)"]

12. CronJob API

CronJob 定义在同一 API Group 下,Short Names 为 cronvcjob / cronvj,Namespaced 作用域。核心字段包括 schedule(Cron 表达式)、jobTemplate(Job 模板)、concurrencyPolicyAllow/Forbid/Replace)、suspend(暂停调度)、successfulJobsHistoryLimit(默认 3)和 failedJobsHistoryLimit(默认 1)。

13. 总结

Volcano Job API 提供了丰富的功能来支持复杂的批量计算场景:

特性对应字段/机制
Gang 调度minAvailable (Job/Task 级)
多任务编排tasks[], dependsOn
生命周期管理policies[], Action/Event 机制
分区调度partitionPolicy
网络拓扑感知networkTopology
NUMA 亲和topologyPolicy
自动清理ttlSecondsAfterFinished
定时调度CronJob
容错重试maxRetry (Job/Task 级)
资源队列queue