返回归档
🏞️k8s

初探 Volcano Scheduler

文章目录

本地安装

https://volcano.sh/zh/docs/installation/

k  get -n volcano-system all
NAME                                       READY   STATUS    RESTARTS   AGE
pod/volcano-admission-fcc95c8d7-kr82q      1/1     Running   0          76s
pod/volcano-controllers-77fd6d6557-7495f   1/1     Running   0          76s
pod/volcano-scheduler-68d9959bdd-f2skb     1/1     Running   0          76s

NAME                                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/volcano-admission-service     ClusterIP   10.96.231.110   <none>        443/TCP    76s
service/volcano-controllers-service   ClusterIP   10.96.85.166    <none>        8081/TCP   76s
service/volcano-scheduler-service     ClusterIP   10.96.187.192   <none>        8080/TCP   76s

NAME                                  READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/volcano-admission     1/1     1            1           76s
deployment.apps/volcano-controllers   1/1     1            1           76s
deployment.apps/volcano-scheduler     1/1     1            1           76s

NAME                                             DESIRED   CURRENT   READY   AGE
replicaset.apps/volcano-admission-fcc95c8d7      1         1         1       76s
replicaset.apps/volcano-controllers-77fd6d6557   1         1         1       76s
replicaset.apps/volcano-scheduler-68d9959bdd     1         1         1       76s

Volcano 的 scheduler(volcano-scheduler)是整个系统最核心的组件,它是一个独立的自定义调度器(custom scheduler),不替换 Kubernetes 原生的 kube-scheduler,而是作为补充/扩展存在,专门针对批处理(batch)、AI训练、大数据、HPC 等场景提供增强能力。

Volcano Scheduler 有哪些主要功能

Volcano scheduler 通过Actions + Plugins 的可扩展架构,提供以下核心功能(远超 kube-scheduler 的默认能力):

  • Gang 调度(组调度 / All-or-Nothing):确保一个 Job 的所有 Pod(或达到 minMember 数量)同时启动,避免部分启动导致死锁(如分布式训练的 Worker 等待 PS)。
  • 公平调度:支持 DRF(Dominant Resource Fairness)、Proportion(队列比例分配)、Priority(优先级)。
  • 资源紧凑打包:BinPack 算法,提高节点利用率,支持自动缩容。
  • 抢占与回收:Preempt(抢占低优先级 Pod)、Reclaim(根据队列权重回收资源)。
  • 回填调度:Backfill,利用碎片资源调度低优先级任务。
  • 异构设备调度:GPU/NPU/MIG 共享、NUMA-aware、网络拓扑感知(Task-Topology)。
  • 队列管理:Queue 级配额、借用、回收、预留。
  • SLA 保障:Job 等待时间上限等。
  • 其他:多集群调度、在线离线混部(colocation)、DRA(Dynamic Resource Allocation)支持等。

image

这些功能通过插件实现,用户可以自定义插件或调整配置(在 volcano-scheduler-configmap 中)。

如何与 Kubernetes scheduler(kube-scheduler)交互?如何接入 Kubernetes?

Volcano scheduler 完全独立运行不与 kube-scheduler 直接交互(没有共享缓存或调用关系)。

接入方式非常简单(Kubernetes 原生支持多调度器):

  1. 指定 schedulerName
    • 在 Pod spec 中设置 schedulerName: volcano(或自定义名称)。
    • 原生 Pod、Deployment、StatefulSet 等也可以这样指定,让它们走 Volcano。
    • VolcanoJob / VcJob 默认就是 volcano。
  2. Admission Webhook 自动注入
    • volcano-admission(Mutating Webhook)会自动为需要 Volcano 调度的 Pod 注入 schedulerName: volcano 和 PodGroup 关联(如果未指定)。
  3. kube-scheduler 只调度 schedulerName 为空或 kube-scheduler 的 Pod
    • Volcano scheduler 只 watch 并调度 schedulerName 为 volcano 的 Pending Pod。
  4. 统一调度兼容
    • Volcano 通过实现 predicates(过滤)和 nodeorder(打分)插件,完全兼容 kube-scheduler 的 Filter/Score 框架逻辑,所以即使是原生 Pod 走 Volcano,也能正确处理 affinity、taint、资源等。

这样就实现了统一入口:所有批处理负载走 Volcano,原生微服务仍走 kube-scheduler(或全部统一走 Volcano)。

Volcano 的调度流程(Scheduling Flow)

Volcano scheduler 采用Session-based 调度循环(周期性快照 + 批量处理),避免并发冲突,提高大规模效率。

大致流程如下:

  1. Watch & Cache:通过 Informer 监听 Kubernetes API,缓存 Pod、Node、Queue、PodGroup 等信息。
  2. 打开 Session(调度周期开始):生成当前集群快照(Cache)。
  3. Enqueue:遍历所有待调度 Job/Task,执行过滤(predicates 插件等),满足条件的进入待调度队列(状态从 Pending → InQueue)。
  4. Allocate:为 Job/Task 选择最优节点(nodeorder、binpack、drf 等插件打分/过滤),绑定 Pod(调用 Kubernetes API 的 Binding)。
  5. Preempt:如果资源不足,高优先级 Job 可以抢占低优先级 Pod(优先级、DRF 插件决定)。
  6. Reclaim:根据队列权重回收资源(低权重队列的 Pod 被驱逐)。
  7. Backfill:用低优先级/碎片任务填充节点,提高利用率。
  8. 关闭 Session:提交绑定结果,更新状态,进入下一周期。

动作顺序可在配置中自定义(默认:enqueue, allocate, preempt, reclaim, backfill)。

image

Scheduler 与 Controller 是如何交互的?

Volcano scheduler 和 volcano-controllers 通过 Kubernetes API 间接交互(没有直接 gRPC 或内部调用),都是标准的 operator 模式:

  • Controllers(volcano-controllers):
    • 管理 CRD:Queue、PodGroup、VolcanoJob(VcJob)、JobFlow 等。
    • 负责 CRD 的 reconcile 循环:创建/更新/删除 Pod、校验合法性、更新 Job 状态、处理生命周期(如失败重试、完成)。
  • Scheduler
    • 只关心 Pod 的调度,不管理 Job 生命周期。
    • 通过 Informer watch Controllers 创建的 Pod(schedulerName=volcano 的)。
    • 调度完成后,通过 Binding API 更新 Pod 的 nodeName 和 status。
    • Controllers 再 watch Pod 状态变化,更新 VolcanoJob/PodGroup 的 status。

典型交互链路:

  1. 用户提交 VolcanoJob → controllers reconcile → 创建 PodGroup + Pod(带 schedulerName=volcano)。
  2. Admission Webhook 校验/注入。
  3. Scheduler watch 到 Pending Pod → 调度 → Binding。
  4. Controllers watch 到 Pod Running/Completed → 更新 VolcanoJob 状态。

两者通过 shared Kubernetes API + CRD events 协作,scheduler 专注决策,controllers 专注资源管理。

CRD

CRD 名称 组/版本 主要含义和作用
commands.bus.volcano.sh bus.volcano.sh/v1alpha1 命令管理:用于定义和管理 Volcano 集群中的命令(Command),支持批量执行命令或脚本,常用于 Job 生命周期管理(如重启、停止)。
cronjobs.batch.volcano.sh batch.volcano.sh/v1alpha1 定时任务:Volcano 版的 CronJob,支持定时调度 VolcanoJob,支持 Gang 调度、队列优先级等高级特性。
hypernodes.topology.volcano.sh topology.volcano.sh/v1alpha1 超节点拓扑:用于描述大规模集群中“超节点”(HyperNode)的拓扑结构,帮助 Volcano 感知节点间的网络/硬件拓扑,实现拓扑感知调度(如 NUMA、网络域)。
jobflows.flow.volcano.sh flow.volcano.sh/v1alpha1 工作流:定义多阶段、多依赖的 Job 工作流(DAG),支持 Job 间顺序执行、条件分支,常用于复杂 ETL、AI 训练 pipeline。
jobs.batch.volcano.sh batch.volcano.sh/v1alpha1 VolcanoJob(简称 VcJob):Volcano 的核心增强型 Job,支持 Gang 调度、生命周期管理、插件集成(如 binpack、drf)、优先级、队列绑定,是最常用的 CRD。
jobtemplates.flow.volcano.sh flow.volcano.sh/v1alpha1 Job 模板:JobFlow 中的可复用模板,用于定义标准化 Job 步骤,方便在工作流中多次引用。
numatopologies.nodeinfo.volcano.sh nodeinfo.volcano.sh/v1alpha1 NUMA 拓扑信息:描述节点内部 NUMA 节点拓扑(CPU、内存、设备亲和性),供 Volcano 实现 NUMA-aware 调度,减少跨 NUMA 访问延迟。
podgroups.scheduling.volcano.sh scheduling.volcano.sh/v1beta1 PodGroup:Pod 组,用于实现 Gang 调度(All-or-Nothing),定义一组 Pod 的最小启动数(minMember)、所属队列、优先级等,是 Gang 调度的核心 CRD。
queues.scheduling.volcano.sh scheduling.volcano.sh/v1beta1 Queue:资源队列,支持多租户、公平共享、配额管理、权重、借用/回收、抢占等,是 Volcano 实现资源隔离和公平调度的基础。

examples

PS

第一步:创建 Queue (资源队列,用于Gang调度绑定)

# queue.yaml
apiVersion: scheduling.volcano.sh/v1beta1
kind: Queue
metadata:
  name: ps-simulation-queue
spec:
  weight: 1  # 队列权重
  reclaimable: true  # 允许资源回收
  capability:  # 队列配额(可选,根据本地Kind调整;这里设置低资源上限)
    cpu: "1"  # 总CPU上限1
    memory: 1Gi  # 总内存上限1Gi

第二步: 创建 VolcanoJob 模拟 PS (Parameter Server) 架构

  • 1 个 PS 任务 (replicas: 1)
  • 2 个 Worker 任务 (replicas: 2)
  • Gang 调度: minAvailable: 3 (总Pod数,必须同时启动所有,否则等待)
  • 每个Pod资源极低: cpu 100m, memory 128Mi (适合本地Kind)
  • 使用 busybox 镜像,sleep 命令模拟运行(真实可运行,无需复杂命令)
# ps-simulation-job.yaml
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
  name: ps-simulation-job
spec:
  minAvailable: 3  # Gang 阈值: 必须同时调度至少3个Pod (1 PS + 2 Workers)
  schedulerName: volcano  # 使用 Volcano Scheduler
  queue: ps-simulation-queue  # 绑定到上面创建的 Queue
  tasks:
    - replicas: 1  # PS 任务: 1 个 Pod
      name: ps  # 任务名称为 ps (模拟 Parameter Server)
      template:
        spec:
          containers:
            - image: busybox  # 简单镜像
              name: ps-container
              command: ["sleep", "3600"]  # 模拟运行1小时(可调整)
              resources:
                requests:
                  cpu: 100m  # 极低CPU
                  memory: 128Mi  # 极低内存
          restartPolicy: OnFailure
    - replicas: 2  # Worker 任务: 2 个 Pod
      name: worker  # 任务名称为 worker (模拟 Workers)
      template:
        spec:
          containers:
            - image: busybox
              name: worker-container
              command: ["sleep", "3600"]
              resources:
                requests:
                  cpu: 100m
                  memory: 128Mi
          restartPolicy: OnFailure

image

Ref