【集群】云原生批调度实战:Volcano 深度解析(三):核心流程解析与架构设计

【集群】云原生批调度实战:Volcano 深度解析(三):核心流程解析与架构设计

Fre5h1nd Lv6

本系列《云原生批调度实战:Volcano 深度解析》计划分为以下几篇,点击查看其它内容。

  1. 云原生批调度实战:Volcano 深度解析(一)批处理背景需求与Volcano特点
  2. 云原生批调度实战:Volcano 深度解析(二)Volcano调度流程与调度状态
  3. 云原生批调度实战:Volcano 安装与初试
  4. 云原生批调度实战:Volcano 深度解析(三)核心流程解析与架构设计

💡简介

调度器性能对比分析中,我们发现Volcano在大规模Job创建时存在性能瓶颈,特别是与Webhook相关的限制。为了深入理解这一现象并提供有效的优化方案,我们需要从代码层面深入分析Volcano的核心流程。

本文将从Volcano的整体架构出发,详细解析从Job创建到Pod调度的完整流程,通过代码分析揭示Volcano如何实现高效的批处理调度,以及与原生Kubernetes调度器的关键差异。

🖼️背景

问题背景

在性能测试中,我们发现Volcano在以下场景下存在性能瓶颈:

  1. 大规模Job创建:同时创建大量Job时,会出现阶段性阻塞
  2. Webhook QPS限制:Webhook的QPS限制可能影响Job创建速度
  3. 批量处理机制:可能存在批量处理策略,按批创建,导致创建成为瓶颈

为了理解这些问题的根本原因,我们需要深入分析Volcano的核心流程。在这篇博客中,我们对代码进行初步分析,从Job创建到Pod调度的完整流程开始,初步了解各组件的作用和交互关系。

🏗️Volcano整体架构概览

核心组件架构

Volcano作为Kubernetes的批处理调度系统,主要由以下几个核心组件组成:

graph TB
    A[用户] --> B[kube-apiserver]
    B --> C[Volcano Controller Manager]
    B --> D[Volcano Scheduler]
    B --> E[Volcano Webhook Manager]
    
    C --> F[Job Controller]
    C --> G[PodGroup Controller]
    C --> H[Queue Controller]
    
    D --> I[Cache]
    D --> J[Actions]
    D --> K[Plugins]
    
    E --> L[Admission Webhooks]
    E --> M[Validating Webhooks]
    E --> N[Mutating Webhooks]
    
    F --> O[Pod Creation]
    G --> P[PodGroup Management]
    H --> Q[Queue Management]
    
    I --> R[Node Cache]
    I --> S[Pod Cache]
    I --> T[Job Cache]
    
    J --> U[Enqueue]
    J --> V[Allocate]
    J --> W[Preempt]
    J --> X[Reclaim]
    J --> Y[Backfill]

组件职责分析

1. Controller Manager

  • Job Controller:管理Volcano Job的生命周期
  • PodGroup Controller:管理PodGroup的创建和状态
  • Queue Controller:管理队列资源和配额

2. Scheduler

  • Cache:维护集群状态快照
  • Actions:执行调度操作(入队、分配、抢占等)
  • Plugins:提供调度算法和策略

3. Webhook Manager

  • Admission Webhooks:准入控制
  • Validating Webhooks:验证资源
  • Mutating Webhooks:修改资源

🔄Job创建到Pod调度的完整流程

流程概览

sequenceDiagram
    participant User as 用户
    participant API as kube-apiserver
    participant Webhook as Webhook Manager
    participant Controller as Controller Manager
    participant Scheduler as Volcano Scheduler
    participant Cache as Scheduler Cache
    
    User->>API: 创建Volcano Job
    API->>Webhook: 调用准入Webhook
    Webhook->>API: 验证/修改Job
    API->>Controller: 触发Job Controller
    Controller->>API: 创建PodGroup
    API->>Webhook: 调用PodGroup Webhook
    Webhook->>API: 验证PodGroup
    Controller->>API: 创建Pod
    API->>Webhook: 调用Pod Webhook
    Webhook->>API: 验证Pod
    API->>Scheduler: 触发调度
    Scheduler->>Cache: 获取集群快照
    Scheduler->>Scheduler: 执行调度算法
    Scheduler->>API: 绑定Pod到节点

详细流程分析

阶段1:Job创建与验证

1.1 用户提交Job

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: test-job
spec:
minAvailable: 3
schedulerName: volcano
queue: default
tasks:
- replicas: 3
name: task-1
template:
spec:
containers:
- name: container-1
image: busybox
command: ["sleep", "100"]

1.2 Webhook验证

当用户提交Job时,kube-apiserver会调用Volcano的Webhook进行验证。AdmitJobs函数通过HTTP路由系统被kube-apiserver调用,而不是直接的函数调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
// pkg/webhooks/admission/jobs/validate/admit_job.go
var service = &router.AdmissionService{
Path: "/jobs/validate",
Func: AdmitJobs, // 注册到HTTP路由
ValidatingConfig: &whv1.ValidatingWebhookConfiguration{...},
}

func AdmitJobs(ar admissionv1.AdmissionReview) *admissionv1.AdmissionResponse {
switch ar.Request.Operation {
case admissionv1.Create:
msg = validateJobCreate(job, &reviewResponse)
}
}

实际验证内容:根据代码分析,validateJobCreate函数主要验证:

  • 基础参数校验:minAvailable、maxRetry、replicas等参数范围
  • 任务模板验证:Pod模板的合法性和K8s资源规范
  • MPI依赖检查:验证master/worker任务配置
  • 任务间依赖:检查依赖关系是否形成有向无环图(DAG)
  • 队列状态验证:检查Queue是否存在、状态是否为Open、是否为叶子队列
  • 插件配置验证:验证Job插件是否存在

调用机制:Webhook通过以下机制被调用:

  1. webhook-manager启动时注册HTTP路由 (http.HandleFunc(service.Path, service.Handler))
  2. kube-apiserver根据ValidatingWebhookConfiguration向Volcano发送HTTP POST请求
  3. 请求路径为 /jobs/validate,由router.Serve处理并调用AdmitJobs函数

1.3 Job Controller处理

Job Controller监听到Job创建事件后,开始处理:

1
2
3
4
5
6
// pkg/controllers/job/job_controller.go
func (jc *jobcontroller) syncJob(job *vcbatch.Job) error {
// 1. 创建PodGroup
// 2. 创建Pod
// 3. 更新Job状态
}

阶段2:PodGroup创建

2.1 PodGroup的作用

PodGroup是Volcano的核心概念,用于实现Gang调度:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// pkg/controllers/job/job_controller.go
func (jc *jobcontroller) createPodGroup(job *vcbatch.Job) error {
podGroup := &vcscheduling.PodGroup{
ObjectMeta: metav1.ObjectMeta{
Name: job.Name,
Namespace: job.Namespace,
},
Spec: vcscheduling.PodGroupSpec{
MinMember: job.Spec.MinAvailable,
Queue: job.Spec.Queue,
},
}
return jc.vcClient.SchedulingV1beta1().PodGroups(job.Namespace).Create(podGroup)
}

2.2 PodGroup状态管理

PodGroup的状态转换:

stateDiagram-v2
    [*] --> Pending
    Pending --> Inqueue
    Inqueue --> Running
    Running --> Completed
    Running --> Failed
    Completed --> [*]
    Failed --> [*]

阶段3:Pod创建

3.1 批量Pod创建

Job Controller会根据Job配置创建多个Pod:

1
2
3
4
5
6
7
8
9
10
11
// pkg/controllers/job/job_controller.go
func (jc *jobcontroller) createPods(job *vcbatch.Job) error {
for _, task := range job.Spec.Tasks {
for i := 0; i < task.Replicas; i++ {
pod := jc.createPod(job, &task, i)
// 批量创建Pod
pods = append(pods, pod)
}
}
return jc.batchCreatePods(pods)
}

3.2 Pod模板处理

每个Pod都基于任务模板创建:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func (jc *jobcontroller) createPod(job *vcbatch.Job, task *vcbatch.TaskSpec, index int) *corev1.Pod {
pod := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("%s-%s-%d", job.Name, task.Name, index),
Namespace: job.Namespace,
Labels: map[string]string{
"volcano.sh/job-name": job.Name,
"volcano.sh/task-name": task.Name,
},
},
Spec: task.Template.Spec,
}
return pod
}

阶段4:调度处理

4.1 调度器触发

当Pod创建后,调度器开始工作:

1
2
3
4
5
6
// pkg/scheduler/framework/session.go
func (ssn *Session) Open() {
// 1. 获取集群快照
// 2. 执行调度Actions
// 3. 更新调度结果
}

4.2 调度Actions执行

调度器按顺序执行Actions:

1
2
3
4
5
6
7
8
// pkg/scheduler/actions/allocate/allocate.go
func (alloc *Action) Execute(ssn *framework.Session) {
// 1. Enqueue: 将Job加入调度队列
// 2. Allocate: 为Pod分配节点
// 3. Preempt: 处理抢占
// 4. Reclaim: 处理资源回收
// 5. Backfill: 处理回填
}

4.3 节点选择算法

调度器使用多种算法选择最优节点:

1
2
3
4
5
6
7
8
// pkg/scheduler/plugins/predicates/predicates.go
func (p *predicatePlugin) OnNodeAdd(node *v1.Node) {
// 节点预选:过滤不满足条件的节点
}

func (p *predicatePlugin) OnNodeUpdate(oldNode, newNode *v1.Node) {
// 节点优选:为节点打分
}

🔍关键组件深度解析

Controller Manager组件

Job Controller

Job Controller是Volcano的核心控制器,负责管理Job的生命周期:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// pkg/controllers/job/job_controller.go
type jobcontroller struct {
vcClient vcclientset.Interface
kubeClient kubernetes.Interface
jobInformer vcinformer.JobInformer
podInformer corev1informer.PodInformer
// ... 其他字段
}

func (jc *jobcontroller) syncJob(job *vcbatch.Job) error {
// 1. 检查Job状态
// 2. 创建/更新PodGroup
// 3. 创建/更新Pod
// 4. 更新Job状态
}

PodGroup Controller

PodGroup Controller管理PodGroup的状态转换:

1
2
3
4
5
6
// pkg/controllers/podgroup/podgroup_controller.go
func (pgc *podgroupcontroller) syncPodGroup(pg *vcscheduling.PodGroup) error {
// 1. 检查PodGroup状态
// 2. 计算满足条件的Pod数量
// 3. 更新PodGroup状态
}

Scheduler组件

Cache机制

调度器的Cache维护集群状态快照:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// pkg/scheduler/cache/cache.go
type Cache struct {
nodes map[string]*api.NodeInfo
jobs map[api.JobID]*api.JobInfo
pods map[string]*api.PodInfo
// ... 其他字段
}

func (c *Cache) Snapshot() *api.ClusterInfo {
// 创建集群快照
return &api.ClusterInfo{
Nodes: c.nodes,
Jobs: c.jobs,
// ... 其他信息
}
}

Actions机制

Actions定义了调度器的核心操作:

1
2
3
4
5
6
7
8
9
10
11
12
// pkg/scheduler/actions/allocate/allocate.go
type Action struct {
// Action实现
}

func (alloc *Action) Execute(ssn *framework.Session) {
// 1. Enqueue: 入队操作
// 2. Allocate: 分配操作
// 3. Preempt: 抢占操作
// 4. Reclaim: 回收操作
// 5. Backfill: 回填操作
}

Webhook Manager组件

Admission Webhooks

准入控制器处理资源创建和修改:

1
2
3
4
5
6
7
8
9
10
// pkg/webhooks/admission/job/admit.go
type jobAdmit struct {
// Webhook实现
}

func (job *jobAdmit) Admit(ar *admissionv1.AdmissionReview) *admissionv1.AdmissionResponse {
// 1. 解析请求
// 2. 验证资源
// 3. 返回结果
}


  • 希望这篇博客对你有帮助!如果你有任何问题或需要进一步的帮助,请随时提问。
  • 如果你喜欢这篇文章,欢迎动动小手给我一个follow或star。

🗺参考文献

[1] Volcano GitHub 仓库

[2] Volcano 官方文档

[3] Kubernetes 调度器设计

[4] Volcano 架构设计

[5] Kubernetes Webhook 机制

[6] Volcano 调度器 Actions

[7] Kubernetes 控制器

[8] Volcano 调度器

  • 标题: 【集群】云原生批调度实战:Volcano 深度解析(三):核心流程解析与架构设计
  • 作者: Fre5h1nd
  • 创建于 : 2025-08-25 20:39:54
  • 更新于 : 2025-08-25 20:48:03
  • 链接: https://freshwlnd.github.io/2025/08/25/k8s/k8s-volcano-core-flow/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论