Volcano 面试题
30 道题- 分类
- Kubernetes
- 子分类
- llm
- 题目数
- 30 道
1 Volcano 的核心架构与组件组成是什么?
答案:
Volcano 是 CNCF 孵化的 Kubernetes 批量调度系统,专为 AI/ML 和 GPU 工作负载设计。其核心架构由四个组件构成:Controller(作业管理控制器)、Scheduler(批量调度器)、Admission(Webhook 准入控制)和 CLI(命令行工具 vcctl)。
graph TD
KC["kubectl / vcctl"] --> ADM["Admission (Webhook)<br/>- Job 验证<br/>- 默认注入"]
KC --> SCH["Scheduler"]
ADM -->|"校验与注入"| SCH
SCH --> SES["Sessions"]
SES --> PLG["Plugins"]
SES --> ACT["Actions"]
SCH --> CTRL["Controller<br/>- Job<br/>- PodGroup<br/>- Queue"]
SCH --- Q["Queue (CRD)"]
style SCH fill:#e1f5fe
style SES fill:#e1f5fe
style PLG fill:#e1f5fe
style ACT fill:#e1f5fe
Controller 负责 Job、PodGroup、Queue CRD 的生命周期管理,将 Volcano Job 转换为 Kubernetes Pod,并根据调度结果更新 Pod 状态。Scheduler 以插件化架构实现调度逻辑,通过 Session 机制在每次调度周期内聚合集群状态,按 Plugin 注册顺序执行过滤和打分,最终由 Action 决定调度行为。Admission 作为 Mutating Webhook 校验 Job/PodGroup 合法性并注入默认配置。vcctl 提供命令行管理能力,支持 Job 提交、挂起、恢复和队列管理。
2 Volcano 的 Gang Scheduling 调度机制如何实现?
答案:
Gang Scheduling 是 Volcano 的核心调度能力,确保一组关联的 Pod 要么全部调度成功,要么全部等待,避免因部分 Pod 无法调度造成的死锁和资源浪费。
调度流程基于 PodGroup CRD 实现:
graph TD
A["提交 Job(minAvailable: 8)"] --> B["Scheduler 检查集群 GPU 可用量"]
B --> C{"GPU 可用 >= 8 ?"}
C -->|否| D["Job 进入 Pending 状态<br/>所有 8 个 Pod 全部等待"]
C -->|是| E["一次分配 8 个 GPU 槽位<br/>8 个 Pod 同时启动<br/>进入 Running 状态"]
核心参数为 minAvailable,定义任务组的最低启动数量。调度器在单次 Session 内为所有 Pod 预留资源,完成原子性分配。当 minAvailable 未满足时,已分配的 Pod 释放资源回池,Job 整体处于 Pending。
apiVersion: scheduling.volcano.sh/v1beta1
kind: PodGroup
metadata:
name: pytorch-training-pg
spec:
minMember: 8
minResources:
nvidia.com/gpu: "8"
cpu: "64"
memory: "256Gi"
queue: ai-training
priorityClassName: high-priority
3 Volcano 的 Queue 队列管理机制是怎样的?
答案:
Volcano Queue 是多租户资源管理的核心抽象,通过 weight(权重)、capability(资源上限)和 reclaimable(可回收)三个维度控制租户间的资源分配。
| 参数 | 说明 | 典型值 |
|---|---|---|
| weight | 队列权重,影响 Fair-Share 分配比例 | 1-10 |
| capability | 队列可使用的最大资源量 | cpu: 100, memory: 512Gi |
| reclaimable | 空闲资源是否允许其它队列抢占 | true/false |
| guarantee | 队列资源保底量(预留) | cpu: 20, memory: 128Gi |
资源分配层级: 集群总资源按 Queue 权重分配;Queue 内按 Job 优先级分配;Job 内按 Gang Scheduling 原子分配。
apiVersion: scheduling.volcano.sh/v1beta1
kind: Queue
metadata:
name: ai-training
spec:
weight: 3
capability:
cpu: "200"
memory: "1024Gi"
nvidia.com/gpu: "32"
reclaimable: true
apiVersion: scheduling.volcano.sh/v1beta1
kind: Queue
metadata:
name: inference
spec:
weight: 1
capability:
cpu: "50"
memory: "256Gi"
nvidia.com/gpu: "8"
reclaimable: false
reclaimable: true 的队列在空闲时允许其他队列借用其未使用资源,超出 capability 的部分在源队列有新 Job 时被回收(Reclaim)。reclaimable: false 的队列资源严格独占,即使空闲也不被借用。
4 Volcano 的 PodGroup CRD 与 minMember/minResources 如何配置?
答案:
PodGroup 是一组需协同调度的 Pod 的逻辑集合,由 Volcano Controller 为每个 Job 自动创建,也可手动定义。
PodGroup 状态机:
graph LR
Pending --> Inqueue --> Running --> Completed
Running --> Unknown --> Failed
关键字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| minMember | int | 最少成员 Pod 数,决定 Gang Scheduling 门槛 |
| minResources | map | 满足条件所需的最小资源总量 |
| minTaskMember | map | 每种 Task 的最少副本数 |
| priorityClassName | string | 关联的 PriorityClass,决定抢占优先级 |
| queue | string | 所属 Queue,隔离资源域 |
minMember 与 minResources 配合使用:minMember 检查数量,minResources 检查资源总量,二者均满足才判定为 Ready。
apiVersion: scheduling.volcano.sh/v1beta1
kind: PodGroup
metadata:
name: llm-fine-tuning
spec:
minMember: 4
minResources:
nvidia.com/gpu: "16"
cpu: "128"
memory: "512Gi"
minTaskMember:
master: 1
worker: 3
queue: ai-training
priorityClassName: high-priority
5 Volcano 的 Job 生命周期管理是怎样的?
答案:
Volcano Job 封装了批量计算任务的完整生命周期,包括任务定义、依赖关系、重试策略和生命周期钩子。
Job 状态机:
graph TD
Pending --> Running --> Completed
Running --> Failed --> Restarting --> Running
Running --> Terminating --> Terminated
Running --> Aborting --> Aborted
Running --> Completing --> Completed
Job 核心要素:
Volcano Job
│
├── PodGroup(自动创建)
│ └── minMember / minResources
│
├── Tasks[](多任务类型)
│ ├── master
│ │ ├── replicas: 1
│ │ └── template: PodSpec
│ │
│ └── worker
│ ├── replicas: 8
│ └── template: PodSpec
│
├── Policies(策略)
│ ├── Event: PodRunning / PodFailed /…
│ └── Action: RestartJob / AbortJob / CompleteJob
│
└── Plugins(扩展)
├── svc / ssh / env / tensorflow
└── 自定义插件(生成 ConfigMap、Service 等)
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: pytorch-dist-training
spec:
schedulerName: volcano
queue: ai-training
minAvailable: 4
tasks:
- replicas: 1
name: master
template:
spec:
containers:
- name: master
image: pytorch/pytorch:2.0.0-cuda11.8
command: ["torchrun", "--nproc_per_node=1", "--nnodes=4", "train.py"]
resources:
limits:
nvidia.com/gpu: 4
- replicas: 3
name: worker
template:
spec:
containers:
- name: worker
image: pytorch/pytorch:2.0.0-cuda11.8
command: ["torchrun", "--nproc_per_node=1", "--nnodes=4", "train.py"]
resources:
limits:
nvidia.com/gpu: 4
policies:
- event: PodEvicted
action: RestartJob
- event: PodFailed
action: RestartJob
6 Volcano 的 Fair-Share 公平调度算法如何工作?
答案:
Fair-Share 调度确保多个 Queue 按权重比例获得集群资源,而非 FIFO 或优先级独占。算法核心是计算每个 Queue 的 资源份额(Share),将资源按权重分配给份额低于应得比例的 Queue。
Fair-Share 计算示例
三个 Queue:
Queue-A weight: 3, 已分配: 30 GPU
Queue-B weight: 2, 已分配: 10 GPU
Queue-C weight: 1, 已分配: 5 GPU
集群总 GPU: 64
计算过程:
总权重: 3 + 2 + 1 = 6
Queue-A 应得: 64 × 3/6 = 32 GPU, 份额: 30/32 = 0.9375
Queue-B 应得: 64 × 2/6 = 21 GPU, 份额: 10/21 = 0.476
Queue-C 应得: 64 × 1/6 = 11 GPU, 份额: 5/11 = 0.455
份额最低的 Queue-B、Queue-C 优先调度
调度决策优先级:份额 < 保底值的 Queue > 份额低于目标的 Queue > 份额超过目标的 Queue(资源可被回收)。
7 Volcano 的 Binpack 装箱策略如何实现?
答案:
Binpack 策略将 Pod 尽可能紧凑地调度到已使用率高的节点上,减少资源碎片化,提升整机利用率。适用于 GPU 训练场景——将分布式训练的各 Worker 聚集到尽可能少的节点,降低跨节点通信开销。
打分算法:
Binpack 节点打分:
节点 A: CPU 已用 80%, GPU 已用 75% ← 高分(利用率高)
节点 B: CPU 已用 30%, GPU 已用 25% ← 低分(利用率低)
节点 C: CPU 已用 50%, GPU 已用 100% ← 低分(GPU 已满,不可调度)
调度结果: Pod 优先落到节点 A
资源配置示例:
apiVersion: v1
kind: ConfigMap
metadata:
name: volcano-scheduler-config
namespace: volcano-system
data:
volcano-scheduler.conf: |
actions: "enqueue, allocate, backfill"
tiers:
- plugins:
- name: priority
- name: gang
- name: conformance
- plugins:
- name: binpack
arguments:
binpack.weight: 10
binpack.cpu: "1"
binpack.memory: "1"
binpack.nvidia.com/gpu: "2"
binpack.weight 控制装箱权重,资源维度上的系数决定各资源的装箱优先级。
8 Volcano 的 DRF(Dominant Resource Fairness)调度策略是什么?
答案:
DRF 是多资源维度的公平调度算法,以每个 Job 的 主导资源(占总消耗比例最高的资源类型)为基准进行公平分配。
DRF 计算示例:
Job-A: 需要 {CPU: 4, GPU: 8}
├── CPU 占比: 4/100 = 4%
└── GPU 占比: 8/32 = 25% ← 主导资源
Job-B: 需要 {CPU: 20, GPU: 2}
├── CPU 占比: 20/100 = 20% ← 主导资源
└── GPU 占比: 2/32 = 6.25%
调度决策:
Job-A 的 GPU 份额 (25%) > Job-B 的 CPU 份额 (20%)
→ Job-B 优先调度(主导资源份额更低)
DRF 与 Fair-Share 互补:Fair-Share 在 Queue 级别做公平分配,DRF 在 Job 级别按多种资源维度细化公平性。
data:
volcano-scheduler.conf: |
actions: "enqueue, allocate, backfill"
tiers:
- plugins:
- name: drf
arguments:
drf.weight: 5
9 Volcano 的 Topology-Aware 拓扑感知调度如何实现?
答案:
Topology-Aware 调度利用 NUMA、PCIe 拓扑信息优化多 GPU 工作负载的通信性能,将需高速互联的 Pod 调度到物理上相邻的节点或 GPU。
graph TD
subgraph NUMA0["NUMA Node 0"]
CPU0["CPU 0-31"]
G0["GPU 0"] ---|"NVLink"| G1["GPU 1"]
MEM0["Memory: 256GB"]
end
subgraph NUMA1["NUMA Node 1"]
CPU1["CPU 32-63"]
G2["GPU 2"] ---|"NVLink"| G3["GPU 3"]
MEM1["Memory: 256GB"]
end
NOTE["调度决策: 同一 Job 的 Worker 优先调度到同一 NUMA Node<br/>跨 NUMA 时通过 NVSwitch 或 PCIe Switch 保证带宽"]
Task-topology 配置:
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: gpu-dist-training
spec:
schedulerName: volcano
tasks:
- replicas: 8
name: worker
template:
spec:
containers:
- name: training
resources:
limits:
nvidia.com/gpu: 8
env:
- name: NCCL_SOCKET_IFNAME
value: "eth0"
- name: NCCL_DEBUG
value: "INFO"
topologyPolicy: restricted
10 Volcano 的 Task-Topology 多任务拓扑如何配置?
答案:
Task-Topology 定义同一 Job 内不同 Task 类型之间的亲和性关系,控制 master 与 worker、parameter-server 与 worker 的相对位置。
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: tf-dist-training
spec:
schedulerName: volcano
minAvailable: 5
tasks:
- replicas: 1
name: ps
template:
spec:
containers:
- name: parameter-server
resources:
limits:
cpu: "4"
memory: "16Gi"
- replicas: 4
name: worker
template:
spec:
containers:
- name: worker
resources:
limits:
nvidia.com/gpu: 4
taskTopology:
affinity:
pod:
- task: ps
topologyKey: kubernetes.io/hostname
weight: 100
| 亲和类型 | 说明 | 适用场景 |
|---|---|---|
| pod | 指定目标 Task 类型 | PS 与 Worker 同节点部署 |
| node | 指定节点标签 | GPU 型号筛选 |
| zone | 可用区级别 | 跨 AZ 容灾 |
| rack | 机架级别 | 减少跨机架流量 |
11 Volcano 的 Job 依赖关系与 JobFlow 如何定义?
答案:
JobFlow 是 Volcano 的工作流 CRD,定义多个 Job 之间的执行顺序和依赖关系,支持 DAG 形式的有向无环图。
graph LR
A["数据预处理"] --> B["模型训练"] --> C["模型评估"]
B --> D["模型导出"]
JobFlow 配置:
apiVersion: flow.volcano.sh/v1alpha1
kind: JobFlow
metadata:
name: ml-pipeline
spec:
flows:
- name: data-preprocess
jobTemplate:
name: preprocess-job
- name: model-training
dependsOn:
targets:
- data-preprocess
jobTemplate:
name: training-job
- name: model-evaluation
dependsOn:
targets:
- model-training
jobTemplate:
name: eval-job
- name: model-export
dependsOn:
targets:
- model-training
jobTemplate:
name: export-job
依赖状态传递: failed、success、finished、running,默认 success——上游成功后才触发下游。
12 Volcano 对 GPU 工作负载的调度支持如何实现?
答案:
Volcano 原生支持 nvidia.com/gpu 扩展资源调度,结合 Gang Scheduling、Binpack 和 Topology-Aware 特性为 GPU 工作负载提供端到端调度能力。
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: gpu-training
spec:
schedulerName: volcano
queue: gpu-queue
minAvailable: 4
tasks:
- replicas: 4
name: worker
template:
spec:
containers:
- name: training
image: pytorch/pytorch:2.0.0-cuda11.8-cudnn8-devel
command:
- torchrun
- --nproc_per_node=8
- --nnodes=4
- --node_rank=$(VC_TASK_INDEX)
- --master_addr=$(VC_MASTER_HOST)
- --master_port=29500
- train.py
resources:
limits:
nvidia.com/gpu: 8
cpu: "64"
memory: "256Gi"
env:
- name: NCCL_SOCKET_IFNAME
value: "eth0"
- name: NCCL_IB_DISABLE
value: "0"
- name: NCCL_NET_GDR_LEVEL
value: "5"
volumeMounts:
- name: dataset
mountPath: /data
volumes:
- name: dataset
persistentVolumeClaim:
claimName: training-dataset
Volcano 内置环境变量(VC_TASK_INDEX、VC_MASTER_HOST、VC_WORKER_HOSTS)自动注入 Pod,供分布式训练框架发现节点和排序。
13 Volcano 对分布式训练框架(PyTorch/TensorFlow/MPI)的支持是怎样的?
答案:
Volcano 通过内置 Task Plugin 机制为 PyTorch、TensorFlow、MPI 等框架提供原生支持,自动完成 Pod 间通信配置。
| 框架 | Task Plugin | 自动生成 | 通信方式 |
|---|---|---|---|
| PyTorch | pytorch | master Service/ConfigMap | torchrun / torch.distributed |
| TensorFlow | tensorflow | PS/Worker Service | TF_CONFIG 环境变量 |
| MPI | mpi | SSH Config / Hostfile | mpirun / Open MPI |
| Horovod | mpi | Hostfile | mpirun + Horovod |
PyTorch 示例:
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: pytorch-ddp
spec:
schedulerName: volcano
plugins:
pytorch: ["--master=master", "--worker=worker"] # Task 角色映射
minAvailable: 4
tasks:
- replicas: 1
name: master
template:
spec:
containers:
- name: pytorch
image: pytorch/pytorch:2.0.0
command: ["torchrun", "--nnodes=4", "train.py"]
- replicas: 3
name: worker
template:
spec:
containers:
- name: pytorch
image: pytorch/pytorch:2.0.0
command: ["torchrun", "--nnodes=4", "train.py"]
MPI 示例(Horovod):
plugins:
mpi: ["--master=master", "--worker=worker"]
ssh: []
svc: []
14 Volcano-Scheduler 与 Kubernetes 默认调度器的对比是什么?
答案:
| 维度 | K8s Default Scheduler | Volcano Scheduler |
|---|---|---|
| 调度单位 | 单个 Pod | PodGroup(一组 Pod) |
| Gang Scheduling | 不支持(需 coscheduling plugin) | 原生支持 |
| 队列管理 | 无 | Queue CRD + weight/capability |
| 公平调度 | 无 | Fair-Share + DRF |
| 抢占机制 | 单 Pod 为单位 | Job 级原子抢占 |
| 拓扑感知 | PodTopologySpread | NUMA/PCIe/Task-Topology |
| Binpack | NodeResourcesFit | 专用 Binpack Plugin |
| 工作流 | 无 | JobFlow / Dependency |
| 调度延迟 | 毫秒级 | 秒级(批量调度) |
| 适用场景 | 微服务、Web 应用 | AI 训练、HPC、大数据 |
Volcano 与默认调度器可共存于同一集群。Pod 通过 spec.schedulerName 选择调度器,默认调度器处理在线服务,Volcano 处理批量任务。
15 Volcano 的 Resource Reservation 预留机制是什么?
答案:
Resource Reservation 机制在调度周期的 Allocate Action 中完成:Scheduler 为满足 Gang 条件的 PodGroup 预留节点上的资源槽位,预留期间其他 Job 不可占用。
Reservation 流程
1. Session 开始,Scheduler 收集集群资源快照
2. 遍历 Queue 内 Pending PodGroup
3. 为满足 minMember 的 PodGroup 预留资源
4. 所有 Pod 分配完毕后,统一标记为 Allocated
5. Session 结束,Controller 绑定 Pod 到 Node
预留是 Session 内的临时状态,不会持久化到 etcd。若 Session 结束时 PodGroup 仍未满足 minMember,预留释放,下一个 Session 重新尝试。
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: resv-example
spec:
schedulerName: volcano
minAvailable: 8 # 8 个 Pod 必须全部预留成功才分配
tasks:
- replicas: 8
name: worker
template:
spec:
containers:
- name: worker
resources:
limits:
nvidia.com/gpu: 1
16 Volcano 的 Preemption 抢占机制如何工作?
答案:
Preemption 允许高优先级 Job 通过驱逐低优先级 Job 来获得所需资源。Volcano 以 Job 级别(非 Pod 级别)执行抢占,确保被抢占的 Job 整体终止而非部分退化。
graph TD
A["高优 Job<br/>Priority: 100<br/>Pending"] --> B["Scheduler 检查<br/>集群可用资源"]
B --> C{"资源充足?"}
C -->|"充足"| D["直接分配"]
C -->|"不足"| E["触发 Preempt Action"]
E --> F["选择牺牲者 Victim"]
F --> F1["低优先级队列"]
F --> F2["同队列低优先级 Job"]
F --> F3["reclaimable=true 的队列"]
F1 & F2 & F3 --> G["满足 minMember<br/>后停止选择"]
G --> H["驱逐牺牲者 Job<br/>释放资源分配给高优 Job"]
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000
globalDefault: false
description: "高优先级 AI 训练任务"
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: critical-training
spec:
schedulerName: volcano
queue: ai-training
minAvailable: 4
priorityClassName: high-priority
tasks:
- replicas: 4
name: worker
template:
spec:
priorityClassName: high-priority
17 Volcano 的 Backfill 回填调度是什么?
答案:
Backfill 是 Volcano 的调度 Action,在满足 Gang Scheduling 约束的前提下,将因 Gang 条件暂不满足而无法调度的零散 Pod 回填到空闲资源上,提升集群整体利用率。
Backfill 示例
队列中有 Job-A (minMember: 8, 需 8 GPU)
集群当前空闲: 6 GPU
队列中还有 Job-B (minMember: 1, 需 1 GPU)
无 Backfill:
Job-A 等 8 GPU, 6 GPU 空闲浪费
Job-B 排在 Job-A 后面,也被阻塞
有 Backfill:
Job-A 不能调度(不足 8 GPU)
Backfill 发现 Job-B 只需要 1 GPU
Job-B 被调度到空闲 GPU 上
6 GPU 中有 1 GPU 被利用
配置方式:
data:
volcano-scheduler.conf: |
actions: "enqueue, allocate, backfill"
Backfill 仅分配零散资源,不占用预留槽位,不破坏 Gang Scheduling 语义。
18 Volcano 的 NodeOrder 节点排序策略有哪些?
答案:
NodeOrder 是 Scheduler 的 Plugin,对通过 Filter 阶段的候选节点打分排序,决定 Pod 的最终落点。
| 策略 | 算法 | 适用场景 |
|---|---|---|
| binpack | 已用资源越多分越高 | GPU 密集调度,减少碎片 |
| spread | 已用资源越少分越高 | 负载均衡、高可用 |
| least-task | 运行中的 Task 数量越少分越高 | 分散 Pod 分布 |
| most-task | 运行中的 Task 数量越多分越高 | 聚集 Pod 分布 |
| topology | NUMA/Zone 拓扑亲和 | GPU 拓扑感知 |
| priority | PriorityClass 越高分越高 | 抢占调度 |
data:
volcano-scheduler.conf: |
tiers:
- plugins:
- name: priority
- name: gang
- plugins:
- name: nodeorder
arguments:
plugin.weight: 10
plugin.least-task.weight: 5
plugin.binpack.weight: 8
plugin.binpack.nvidia.com/gpu: "2"
19 Volcano 的 Job Reclaim 与超时处理机制是怎样的?
答案:
Reclaim 机制在资源紧张时从 reclaimable=true 的 Queue 中回收空闲资源,分配给有需求的 Queue。超时处理 通过 Job 的 ttlSecondsAfterFinished 和生命周期回调实现。
Reclaim 流程:
graph TD
A["高优 Queue-A<br/>资源不足"] --> B["Scheduler 扫描<br/>reclaimable=true 的 Queue"]
B --> C{"可回收?"}
C -->|"Queue-B<br/>reclaimable=true<br/>有空闲资源"| D["驱逐 Queue-B 中<br/>低优先级 Pod"]
D --> E["资源分配给 Queue-A"]
C -->|"Queue-C<br/>reclaimable=false"| F["资源不可回收<br/>跳过"]
超时与清理配置:
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: training-with-ttl
spec:
schedulerName: volcano
minAvailable: 4
ttlSecondsAfterFinished: 3600 # 完成后 1 小时自动清理
maxRetry: 3 # 最大重试次数
tasks:
- replicas: 4
name: worker
template:
spec:
containers:
- name: training
image: pytorch/pytorch:2.0.0
| 生命周期钩子 | 触发事件 | 动作 |
|---|---|---|
| PodEvicted | Pod 被驱逐 | 重启 Job |
| PodFailed | Pod 失败 | 重启/终止 Job |
| PodCompleted | Pod 正常完成 | 标记 Completing |
| TaskCompleted | Task 全部完成 | 标记 Completed |
| ttlSecondsAfterFinished | 完成后超时 | 清理 Job 资源 |
20 Volcano 与 Nvidia GPU Operator 的集成方案是怎样的?
答案:
GPU Operator 负责 GPU 驱动安装和设备注册,Volcano 负责 GPU 工作负载的批量调度和资源管理,二者协同构成完整的 GPU 计算平台。
graph TD
subgraph GPUOP["GPU Operator"]
DRV["Driver"]
DP["Device Plugin"]
GFD["GFD"]
DCGM["DCGM Exporter"]
end
DP -->|"nvidia.com/gpu"| NODE["节点标签 + 资源注册"]
GPUOP --> NODE
subgraph VOL["Volcano Scheduler"]
Q["Queue"]
PG["PodGroup"]
BP["Binpack"]
TOPO["Topology"]
end
NODE --> VOL
集成关键点:
- GPU Operator 的 NFD/GFD 自动为节点添加 GPU 型号、数量、MIG 配置标签,Volcano NodeOrder 利用这些标签做拓扑感知调度。
- GPU Operator 注册的
nvidia.com/gpu和 MIG 资源nvidia.com/mig-1g.10gb直接作为 Volcano Queue 的 capability 和 Job 的 resource limit。 - DCGM Exporter 暴露的 GPU 指标纳入 Prometheus,配合 Volcano 的调度指标做统一监控。
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
spec:
queue: gpu-training
tasks:
- replicas: 4
template:
spec:
nodeSelector:
nvidia.com/gpu.product: NVIDIA-A100-SXM4-80GB # GFD 注入的标签
containers:
- name: training
resources:
limits:
nvidia.com/gpu: 8
21 Volcano 与 HAMI 的集成如何实现 GPU 共享调度?
答案:
HAMI(Heterogeneous AI Computing Virtualization Middleware)实现单 GPU 的细粒度切分和共享。Volcano 配合 HAMI 完成共享 GPU 的调度、队列管理和资源隔离。
graph TD
A["Job 请求<br/>nvidia.com/gpumem: 10 GB<br/>nvidia.com/gpucores: 20"] --> B["Volcano Scheduler<br/>检查节点可用 GPU 资源"]
B --> C["通过 HAMI 资源维度<br/>找到满足条件的节点<br/>HAMI Device Plugin 注册<br/>gpumem、gpucores"]
C --> D["Volcano 执行<br/>Gang Scheduling"]
D --> E["Pod 分配到指定 GPU<br/>的共享槽位"]
E --> E1["HAMI Core<br/>绑定 CUDA Context"]
E --> E2["HAMI Memory<br/>限制 vRAM 上限"]
HAMI + Volcano 集成 Job 配置:
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: shared-gpu-inference
spec:
schedulerName: volcano
queue: inference-queue
minAvailable: 2
tasks:
- replicas: 2
name: inference
template:
spec:
containers:
- name: inference
image: vllm/vllm-openai:latest
resources:
limits:
nvidia.com/gpumem: 10 # 申请 10GB vRAM
nvidia.com/gpucores: 20 # 申请 20% 算力
| 调度层 | 职责 |
|---|---|
| Volcano | Gang Scheduling、Queue 管理、Binpack、抢占 |
| HAMI | GPU 显存隔离、算力限制、设备虚拟化 |
22 Volcano 的多集群调度方案(Karmada/Clusternet)如何实现?
答案:
Volcano 配合集群联邦系统(Karmada、Clusternet)实现跨集群的 GPU 资源池化和批量调度。
graph TD
subgraph KARMADA["Karmada Control Plane"]
KS["Scheduler"]
RD["Resource Detector"]
end
KS --> CA["Cluster A<br/>Volcano<br/>GPU: 64"]
RD --> CA
KS --> CB["Cluster B<br/>Volcano<br/>GPU: 128"]
RD --> CB
Karmada PropagationPolicy 配置:
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: volcano-job-policy
spec:
resourceSelectors:
- apiVersion: batch.volcano.sh/v1alpha1
kind: Job
placement:
clusterAffinity:
clusterNames:
- cluster-a
- cluster-b
replicaScheduling:
replicaDivisionPreference: Weighted
replicaSchedulingType: Divided
weightPreference:
staticWeightList:
- targetCluster:
clusterNames: [cluster-a]
weight: 1
- targetCluster:
clusterNames: [cluster-b]
weight: 2
各成员集群内的 Volcano Scheduler 独立执行 Gang Scheduling 和 Queue 管理。Karmada 负责 Job 的分发和全局资源聚合。
23 Volcano 的监控指标与 Prometheus 集成是怎样的?
答案:
Volcano 各组件暴露 Prometheus 指标,覆盖调度吞吐、队列状态、Job 生命周期和资源利用率。
核心指标:
| 指标 | 类型 | 说明 |
|---|---|---|
| volcano_scheduler_e2e_scheduling_duration | Histogram | 端到端调度延迟 |
| volcano_scheduler_schedule_attempts | Counter | 调度尝试次数 |
| volcano_scheduler_plugin_latency | Histogram | 各 Plugin 执行延迟 |
| volcano_queue_allocated | Gauge | 队列已分配资源 |
| volcano_job_status | Gauge | Job 状态计数(Running/Pending/Failed) |
| volcano_podgroup_status | Gauge | PodGroup 状态计数 |
| volcano_controller_reconcile | Counter | Controller 调谐次数 |
Prometheus ServiceMonitor:
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: volcano
namespace: volcano-system
spec:
selector:
matchLabels:
app: volcano-scheduler
endpoints:
- port: metrics
interval: 30s
path: /metrics
告警规则示例:
groups:
- name: volcano-alerts
rules:
- alert: VolcanoJobPendingTooLong
expr: volcano_job_pending_duration_seconds > 1800
for: 5m
labels:
severity: warning
annotations:
summary: "Job XQOPEN $labels.job_name XQCLOSE Pending 超过 30 分钟"
- alert: VolcanoQueueGPUSaturation
expr: volcano_queue_allocated{nvidia_com_gpu != ""} / volcano_queue_capability{nvidia_com_gpu != ""} > 0.95
for: 10m
labels:
severity: warning
24 Volcano 的日志收集与故障排查方法是什么?
答案:
Volcano 组件日志通过 Kubernetes 标准机制收集。故障排查从 Job 状态、调度器日志、控制器事件三个层次递进。
组件日志定位:
| 组件 | 日志命令 |
|---|---|
| Scheduler | kubectl logs -n volcano-system deploy/volcano-scheduler |
| Controller | kubectl logs -n volcano-system deploy/volcano-controllers |
| Admission | kubectl logs -n volcano-system deploy/volcano-admission |
故障排查清单:
层次 1:Job 状态检查
kubectl get job -n <namespace> <job-name> -o yaml
kubectl describe podgroup -n <namespace> <podgroup-name>
关注: status.state, status.conditions, events
层次 2:调度器日志分析
kubectl logs -n volcano-system deploy/volcano-scheduler | grep <job-id>
# 关键日志前缀:
# "Session Open" - 调度周期开始
# "PodGroup <name> is inqueue" - 入队
# "PodGroup <name> is pending reason: insufficient resources" - 资源不足
# "Allocate task <name> to node <node>" - 分配成功
层次 3:调度器配置诊断
kubectl get configmap volcano-scheduler-config -n volcano-system -o yaml
# 核对: actions 链路、plugin 参数、queue 配置
常见故障模式:
| 症状 | 原因 | 排查方向 |
|---|---|---|
| Job 长期 Pending | minMember 不满足 | 检查集群资源余量、Queue capability |
| Pod 反复创建销毁 | Gang 冲突重试 | 检查 PodGroup 状态、minMember 配置 |
| 调度时延过高 | 集群规模大,Plugin 链路长 | 调整 Session 周期、裁剪 Plugin |
| Queue 资源不均 | weight 配置不当 | 核对 weight 值、reclaimable 设置 |
25 Volcano 的 Elastic Resource Quota 弹性配额如何配置?
答案:
Elastic Resource Quota 通过 Queue 的 guarantee(保底)+ capability(上限)+ reclaimable(弹性)三层机制实现弹性资源分配。
弹性配额模型
Queue-A:
guarantee: {cpu: 20, nvidia.com/gpu: 8}
capability: {cpu: 100, nvidia.com/gpu: 64}
reclaimable: true
集群实际分配:
保底(guarantee): 8 GPU ← 永远保留
弹性(capability - guarantee): 最多 56 GPU ← 可被回收
超出 capability: 不允许
弹性配额配置示例:
apiVersion: scheduling.volcano.sh/v1beta1
kind: Queue
metadata:
name: elastic-ai-training
spec:
weight: 2
guarantee:
nvidia.com/gpu: "16"
cpu: "64"
memory: "256Gi"
capability:
nvidia.com/gpu: "64"
cpu: "256"
memory: "1024Gi"
reclaimable: true
apiVersion: scheduling.volcano.sh/v1beta1
kind: Queue
metadata:
name: burst-inference
spec:
weight: 1
guarantee:
nvidia.com/gpu: "4"
capability:
nvidia.com/gpu: "32"
reclaimable: false # 独占弹性区间的资源,不被回收
reclaimable: false 适用于对资源波动敏感的在线推理服务;reclaimable: true 适用于可容忍资源回收的离线训练任务。
26 Volcano 的 SLO-Aware 调度是什么?
答案:
SLO-Aware 调度通过感知作业的 SLO(Service Level Objective)约束,在调度决策中平衡资源利用率和 SLO 满足率。
核心机制:
SLO 约束类型:
Deadline SLO:
Job 必须在指定时间前完成
调度器优先为临近 Deadline 的 Job 分配资源
Throughput SLO:
Job 需维持最小吞吐量
调度器为低于吞吐目标的 Job 增加资源倾斜
Availability SLO:
多副本 Job 需保持 N 个副本可用
调度器在副本不足时触发快速恢复调度
Deadline SLO 配置:
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: slo-training
annotations:
scheduling.volcano.sh/slo-deadline: "2025-06-01T00:00:00Z"
spec:
schedulerName: volcano
queue: ai-training
minAvailable: 4
tasks:
- replicas: 4
name: worker
template:
spec:
containers:
- name: training
resources:
limits:
nvidia.com/gpu: 8
调度优先级公式:
SLO 紧急度 = 剩余工作量 / (Deadline - 当前时间)
数值越高 → 紧急度越高 → 调度优先级越高
当多个 Queue 竞争资源时,SLO-Aware 权重覆盖 Fair-Share:
priority_score = fair_share_score × (1 - SLO_slack_factor)
27 Volcano 的生产环境部署最佳实践是什么?
答案:
# Volcano Helm 安装
helm repo add volcano-sh https://volcano-sh.github.io/helm-charts
helm install volcano volcano-sh/volcano \
--namespace volcano-system \
--create-namespace \
--set basic.schedulerConfigFile="volcano-scheduler.conf" \
--set controller.replicas=2 \
--set scheduler.replicas=2 \
--set admission.replicas=2
高可用配置: Controller、Scheduler、Admission 均部署 2+ 副本。Scheduler 使用 Leader Election,同一时间仅一个实例执行调度,其余待命。
| 维度 | 配置 | 说明 |
|---|---|---|
| Scheduler 副本 | 2 | Leader Election 高可用 |
| Controller 副本 | 2 | 多实例并行,通过 Job 的 OwnerRef 去重 |
| Admission 副本 | 2 | Webhook 多副本 + PDB |
| Session 间隔 | 5s(默认) | 大规模集群可调为 10s |
| Queue 层级 | ≤ 3 层 | 避免过深的队列嵌套 |
| Node 数量 | ≤ 5000 | 单集群验证上限 |
资源配额:
| 组件 | CPU Request | Memory Request |
|---|---|---|
| Scheduler | 500m | 512Mi |
| Controller | 200m | 256Mi |
| Admission | 100m | 128Mi |
节点亲和性配置:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: volcano-scheduler
topologyKey: kubernetes.io/hostname
安全配置: Admission Webhook 启用 TLS 证书自动轮换。Controller 和 Scheduler 使用独立的 ServiceAccount 并限制 RBAC 权限。
28 Volcano 的性能调优与大规模集群优化有哪些措施?
答案:
大规模集群(1000+ 节点)场景下,Volcano 性能瓶颈集中在 Scheduler 的 Session 计算量、Controller 的调谐频率和 API Server 请求量。
优化维度与参数:
data:
volcano-scheduler.conf: |
actions: "enqueue, allocate, backfill"
tiers:
- plugins:
- name: priority
- name: gang
- name: conformance
- plugins:
- name: binpack
arguments:
binpack.weight: 10
| 优化项 | 默认值 | 建议值 | 效果 |
|---|---|---|---|
| session.duration | 5s | 10s | 减少调度周期频率 |
| batch/worker-threads | 2 | 6 | 并行处理 Bind 操作 |
| queue.cache-refresh | 30s | 60s | 减少 Queue 状态刷新 |
| podgroup.backoff | 30s | 60s | 减少 PodGroup 重试频率 |
| scheduler.percentageOfNodesToScore | 100 | 30 | 仅对部分节点打分 |
Session 裁剪: 每次 Session 内仅处理状态变化的 PodGroup,跳过无变化的稳定 Job。
Node 采样打分: 大规模集群中仅对符合条件的候选节点子集打分,减少排序开销。
apiVersion: v1
kind: ConfigMap
metadata:
name: volcano-scheduler-config
data:
volcano-scheduler-kubeconfig: |
apiVersion: kubescheduler.config.k8s.io/v1beta3
kind: KubeSchedulerConfiguration
percentageOfNodesToScore: 30
优先级队列缓存: 高优 Queue 的 PodGroup 维护在内存缓存中,避免每次 Session 全量扫描。
# 查看调度器性能指标
kubectl logs -n volcano-system deploy/volcano-scheduler | grep "Session.*duration"
# Session 耗时过高的标志
# "Session Open" 到 "Session Close" 超过 2s 时需关注
29 Volcano 的 VCJob CRD 高级用法有哪些?
答案:
VCJob 是 Volcano v1.9+ 引入的 Job CRD 简化版本,减少字段层级并提供更直观的配置接口。
VCJob vs Job 对比:
Volcano Job(旧版):
spec.tasks[].template.spec.containers[].resources.limits
VCJob(新版):
spec.tasks[].resources.limits ← 扁平化,字段更少
VCJob 配置示例(高级用法):
apiVersion: batch.volcano.sh/v1alpha1
kind: VCJob
metadata:
name: advanced-vcjob
spec:
schedulerName: volcano
queue: ai-training
minAvailable: 4
runPolicy:
maxRetry: 3
ttlSecondsAfterFinished: 7200
cleanUpTaskPolicy:
- action: Delete
task: all
when: Completed
plugins:
svc: []
env: []
pytorch: ["--master=master", "--worker=worker"]
tasks:
- replicas: 1
name: master
restartPolicy: OnFailure
resources:
limits:
nvidia.com/gpu: 8
cpu: "64"
memory: "256Gi"
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "nvidia-smi && echo 'GPU ready'"]
preStop:
exec:
command: ["/bin/sh", "-c", "kill -SIGTERM $PID"]
pod:
image: pytorch/pytorch:2.0.0-cuda11.8
command: ["torchrun", "--nnodes=4", "train.py"]
volumes:
- name: shm
emptyDir:
medium: Memory
sizeLimit: 32Gi
高级特性:
| 特性 | 配置项 | 说明 |
|---|---|---|
| Run Policy | maxRetry, ttlSecondsAfterFinished | 重试与清理策略 |
| Cleanup Policy | cleanUpTaskPolicy | Job 完成后清理 Pod/ConfigMap/Service |
| Lifecycle Hooks | postStart, preStop | 容器生命周期钩子 |
| Shared Memory | emptyDir + sizeLimit | 多进程通信所需的共享内存 |
| Multi-Template | 多 task 定义 | 异构 Pod 模板组合 |
30 Volcano 与 Kubeflow 的集成方案是怎样的?
答案:
Kubeflow 是 Kubernetes 上的机器学习平台,Volcano 作为其推荐的批量调度器,为 Kubeflow Pipelines、Training Operator 和 Notebooks 提供 Gang Scheduling 和队列管理能力。
集成架构
Kubeflow
├── Pipelines → Volcano JobFlow(工作流 DAG)
├── Training Operator → Volcano Job(Gang Scheduling)
│ ├── PyTorchJob → Volcano PyTorch Plugin
│ ├── TFJob → Volcano TensorFlow Plugin
│ └── MPIJob → Volcano MPI Plugin
├── Katib(超参搜索) → Volcano Queue(资源隔离)
└── Notebooks → Volcano Queue + Elastic Quota
Kubeflow Training Operator 集成配置:
apiVersion: kubeflow.org/v1
kind: PyTorchJob
metadata:
name: pytorch-dist
spec:
pytorchReplicaSpecs:
Master:
replicas: 1
restartPolicy: OnFailure
template:
spec:
schedulerName: volcano # 指定 Volcano 调度器
containers:
- name: pytorch
image: pytorch/pytorch:2.0.0
resources:
limits:
nvidia.com/gpu: 8
Worker:
replicas: 3
restartPolicy: OnFailure
template:
spec:
schedulerName: volcano
containers:
- name: pytorch
image: pytorch/pytorch:2.0.0
resources:
limits:
nvidia.com/gpu: 8
runPolicy:
schedulingPolicy:
minAvailable: 4 # Volcano Gang Scheduling
queue: ai-training # Volcano Queue
priorityClass: high-priority
Kubeflow Pipeline 与 Volcano JobFlow 集成:
from kfp import dsl
@dsl.pipeline(name="ml-training-pipeline")
def training_pipeline():
preprocess = dsl.implement(
volcano_jobflow_component(
job_template="preprocess-job",
queue="ai-training"
)
)
train = dsl.implement(
volcano_jobflow_component(
job_template="training-job",
queue="ai-training"
)
)
evaluate = dsl.implement(
volcano_jobflow_component(
job_template="eval-job",
queue="ai-training"
)
)
train.after(preprocess)
evaluate.after(train)
集成收益: Kubeflow Training Operator 创建的 PyTorchJob/TFJob 自动获得 Gang Scheduling 能力;Katib 超参搜索 Trial 按 Queue 隔离资源;Notebook 开发环境享有弹性配额。