Skip to main content

基本介绍

Volcano 是一个基于Kubernetes的批处理平台,提供了机器学习、深度学习、生物信息学、基因组学及其他大数据应用所需要而Kubernetes当前缺失的一系列特性,提供了高性能任务调度引擎、高性能异构芯片管理、高性能任务运行管理等通用计算能力。

Volcano架构

相较于原生的调度器,Volcano具有的显著特点有:

  • 支持 Gang Scheduling

    对于批量作业的调度,容易碰到死锁的问题,比如两个作业都需要同时运行 10 个 Pod 才能启动,当两个作业同时提交时,可能都只有部分 Pod 被调度,两个作业都无法正常运行,而处于互相等待状态。Gang Scheduling 就是为了解决这个问题。

  • 调度队列

    配置不同的调度队列,能够实现对资源的抢占、配额的控制等。

  • 硬件感知

    NumaGPU等硬件资源的感知,能够让Pod对硬件资源更高效的使用。

Volcano是在 Kubernetes原生调度能力的基础上进行的扩展和优化,因此,对于基本的 nodeSelectornodeAffinity等也是支持的。同时也支持 Extended Resource,这点对于GPUIB网卡等资源的在调度层面的感知非常重要。

Volcano是业界首个云原生批量计算项目,2019年由华为云捐献给云原生计算基金会(CNCF),也是CNCF首个和唯一的孵化级容器批量计算项目。它源自于华为云AI容器,在支撑华为云一站式AI开发平台ModelArts、容器服务CCI等服务稳定运行中发挥重要作用。

核心组件

Volcano由以下几个核心组件组成,各自承担不同的功能职责:

  1. Volcano Controller Manager:负责管理Volcano自定义资源的生命周期,监控和处理JobQueuePodGroup等资源的状态变化。

  2. Volcano Scheduler:实现高级调度功能,如Gang Scheduling(组调度)、队列调度和优先级调度,通过插件化架构提供灵活的调度策略配置。

  3. Volcano Admission:验证Volcano资源对象的合法性,为资源对象设置默认值,实现准入控制,确保提交的作业符合系统策略。

  4. Volcano MutatingAdmission:修改资源对象的配置,如添加标签、注解等,自动注入环境变量和配置信息。

  5. Volcano Agent(可选组件):在节点上收集资源使用情况和硬件信息,为调度器提供更精确的节点资源信息,支持 GPU、FPGA 等异构资源的管理。

组件交互关系

下图展示了Volcano各组件之间的交互关系及数据流向:

Volcano的各个组件之间通过清晰的职责划分和有效的协作实现了完整的调度系统:

  1. 用户提交流程:用户提交作业→Admission验证 →Controller处理 →Scheduler调度 →Kubelet执行

  2. 状态监控与管理: -Controller Manager监控所有Volcano自定义资源的状态变化

    • 根据资源状态变化,触发相应的事件处理
    • 当需要重调度或清理资源时,通知Scheduler进行相应操作
  3. 调度决策过程: -Scheduler根据Queue配置和系统状态,为PodGroup分配资源

    • 通过插件化架构,实现不同的调度策略和算法
    • 支持Gang Scheduling,确保相关联的Pod要么全部调度成功,要么全部失败
  4. 资源信息收集: -Agent(如果启用) 提供节点资源信息,辅助调度决策

    • 特别是对于 GPU、FPGA 等异构资源,提供更精确的资源状态
  5. 资源对象之间的关系: -Job包含多个Task,每个Task对应一组相同角色的Pod -PodGroup作为调度的基本单位,表示一组需要同时调度的Pod -Queue容纳多个PodGroup,并控制这些PodGroup的资源分配和调度策略

这种组件化设计使Volcano能够灵活应对不同的工作负载需求,并且可以通过扩展插件来增强系统能力。

Scheduler

Kubernetes Scheduler

kubernetes当然有默认的pod调度器,但是其并不适应AI作业任务需求。在多机训练任务中,一个AI作业可能需要同时创建上千个甚至上万个pod,而只有当所有pod当创建完成后,AI作业才能开始运行,而如果有几个pod创建失败,已经创建成功的pod就应该退出并释放资源,否则便会产生资源浪费的情况。因此Ai作业的pod调度应该遵循All or nothing的理念,即要不全部调度成功,否则应一个也不调度。这便是Volcano项目的由来(前身是kube-batch项目),接下来便来介绍Volcano的调度。

Volcano Scheduler

值得注意的是,原生 Kubernetes 调度器(kube-scheduler)没有内置提供完整的 Gang Scheduling(组调度)能力。Gang Scheduling 是指将一组相关的任务作为一个整体进行调度,要么全部调度成功,要么全部不调度。

Kubernetes 默认调度器主要关注单个 Pod 的调度,它会逐个处理 Pod,而不会考虑 Pod 之间的相互依赖关系或者需要同时调度的需求。这种设计对于无状态应用和独立工作负载很有效,但对于需要多个 Pod 协同工作的场景(如分布式机器学习、大数据处理等)就显得不足。

Volcano 通过实现 Gang Scheduling 能力,确保一组相关的 Pod 要么全部被调度成功,要么全部不被调度,避免资源浪费和死锁情况。这是 Volcano 相对于原生 Kubernetes 调度器的一个关键优势。

Volcano Scheduler是负责Pod调度的组件,它由一系列actionplugin组成。action定义了调度各环节中需要执行的动作;plugin根据不同场景提供了action中算法的具体实现细节。Volcano Scheduler具有高度的可扩展性,您可以根据需要实现自己的actionplugin

Volcano Scheduler的工作流程如下:

  1. 客户端提交的Job被调度器识别到并缓存起来。
  2. 周期性开启会话(Session),一个调度周期开始。
  3. 将没有被调度的Job发送到会话的待调度队列中。
  4. 遍历所有的待调度Job,按照定义的次序依次执行enqueueallocatepreemptreclaimbackfill等动作,为每个Job找到一个最合适的节点。将该Job绑定到这个节点。action中执行的具体算法逻辑取决于注册的plugin中各函数的实现。
  5. 关闭本次会话。

具体流程、ActionsPlugins介绍请参考:

Task/Pod状态转换

Task/Pod状态转换

VolcanoPodPod的状态方面增加了很多状态:

  • 图中蓝色部分Kubernetes自带的状态。
  • 绿色部分session级别的状态,一个调度周期,Volcano Scheduler会创建一个session,它只在调度周期内发挥作用,一旦过了调度周期,这几个状态它是失效的。
  • 黄色部分的状态是放在Cache内的。

我们加这些状态的目的是减少调度和API之间的一个交互,从而来优化调度性能。

Pod的这些状态为调度器提供了更多优化的可能。例如,当进行Pod驱逐时,驱逐在BindingBound状态的Pod要比较驱逐Running状态的Pod的代价要小;并且状态都是记录在Volcano调度内部,减少了与kube-apiserver的通信。但目前Volcano调度器仅使用了状态的部分功能,比如现在的preemption/reclaim仅会驱逐Running状态下的Pod;这主要是由于分布式系统中很难做到完全的状态同步,在驱逐BindingBound状态的Pod会有很多的状态竞争。

Volcano自定义资源

  • Pod组(PodGroup):Pod组是Volcano自定义资源类型,代表一组强关联Pod的集合,主要用于批处理工作负载场景,比如Tensorflow中的一组psworker。这主要解决了Kubernetes原生调度器中单个Pod调度的限制。

  • 队列(Queue):容纳一组PodGroup的队列,也是该组PodGroup获取集群资源的划分依据。它允许用户根据业务需求或优先级,将作业分组到不同的队列中。

  • 作业(Volcano Job,简称vcjob):Volcano自定义的Job资源类型,它扩展了KubernetesJob资源。区别于Kubernetes Jobvcjob提供了更多高级功能,如可指定调度器、支持最小运行Pod数、支持task、支持生命周期管理、支持指定队列、支持优先级调度等。Volcano Job更加适用于机器学习、大数据、科学计算等高性能计算场景。

PodGroup资源组

PodGroupVolcano 中实现Gang Scheduling的核心资源对象,它将一组相关的 Pod 视为一个整体进行调度。

PodGroup 的作用

  1. 整体调度

    • 确保一组相关的 Pod 要么全部调度成功,要么全部不调度
    • 防止部分 Pod 调度成功而其他失败导致资源浪费
  2. 资源预留

    • 可以为 PodGroup 设置最小成员数(minMember
    • 当可用资源不足以调度最小成员数时,整个组将等待而不是部分调度
  3. 状态跟踪

    • 提供 PodGroup 的整体状态信息
    • 包括已调度数量、运行状态等

PodGroup 配置示例

下面是一个基本的 PodGroup 定义示例:

apiVersion: scheduling.volcano.sh/v1beta1
kind: PodGroup
metadata:
name: tf-training-group
spec:
minMember: 4 # 最小需要 4 个 Pod 同时调度
queue: ml-jobs # 指定队列
priorityClassName: high-priority # 指定优先级
minResources: # 最小资源需求
cpu: 8
memory: 16Gi
nvidia.com/gpu: 2

使用 PodGroup 的方法

  1. 直接创建 PodGroup 资源

    先创建 PodGroup,然后在 Pod 中引用它:

    apiVersion: v1
    kind: Pod
    metadata:
    name: tf-worker-1
    annotations:
    volcano.sh/pod-group: "tf-training-group" # 引用 PodGroup 名称
    spec:
    schedulerName: volcano # 使用 Volcano 调度器
    containers:
    - name: tensorflow
    image: tensorflow/tensorflow:latest-gpu
  2. 通过 Volcano Job 自动创建

    Volcano Job 会自动创建并管理 PodGroup

    apiVersion: batch.volcano.sh/v1alpha1
    kind: Job
    metadata:
    name: tensorflow-training
    spec:
    minAvailable: 4
    schedulerName: volcano
    queue: ml-jobs

PodGroup 的实际应用场景

  1. 分布式机器学习

    • 确保参数服务器和工作节点同时启动
    • 避免资源浪费和训练任务失败
  2. 大数据处理

    • 确保SparkFlink集群的所有组件同时启动
    • 提高数据处理效率
  3. 高性能计算

    • MPI等高性能计算任务提供同步启动能力
    • 确保计算节点的一致性

PodGroupVolcano 实现Gang Scheduling的基础,它使得复杂的分布式工作负载可以更可靠地运行在 Kubernetes 集群上。

Queue资源队列

QueueVolcano调度系统中的核心概念,用于管理和分配集群资源。 它充当了资源池的角色,允许管理员将集群资源划分给不同的用户组或应用场景。该自定义资源可以很好地用于多租户场景下的资源隔离。

Queue 的作用

  1. 资源隔离与划分

    • 将集群资源划分给不同的用户组或业务线
    • 防止一个应用或用户组消耗过多资源影响其他应用
  2. 资源配额与限制

    • 为队列设置资源上限(capability
    • 控制队列可以使用的最大CPU、内存、GPU等资源量
  3. 优先级和权重管理

    • 通过weight属性设置队列的相对重要性
    • 当资源竞争时,根据权重比例分配资源
  4. 资源回收策略

    • 通过reclaimable属性控制队列资源是否可被回收(被其他队列借用)
    • 当集群资源紧张时,决定哪些队列的资源可以被抢占

Queue 配置示例

下面是一个定义三个不同队列的示例,分别用于生产、开发和测试环境:

apiVersion: scheduling.volcano.sh/v1beta1
kind: Queue
metadata:
name: production
spec:
weight: 10 # 高权重,资源竞争时获得更多资源
reclaimable: false # 资源不可被回收
capability:
cpu: 100 # 最多使用 100 核 CPU
memory: 500Gi # 最多使用 500Gi 内存
nvidia.com/gpu: 10 # 最多使用 10 个 GPU

---

apiVersion: scheduling.volcano.sh/v1beta1
kind: Queue
metadata:
name: development
spec:
weight: 5 # 中等权重
reclaimable: true # 资源可被回收
capability:
cpu: 50 # 最多使用 50 核 CPU
memory: 200Gi # 最多使用 200Gi 内存

---

apiVersion: scheduling.volcano.sh/v1beta1
kind: Queue
metadata:
name: testing
spec:
weight: 2 # 低权重
reclaimable: true # 资源可被回收
capability:
cpu: 20 # 最多使用 20 核 CPU
memory: 100Gi # 最多使用 100Gi 内存

使用 Queue 的方法

  1. 在 Pod 中指定队列

    通过注解指定:

    metadata:
    annotations:
    volcano.sh/queue-name: "production"
  2. 在 PodGroup 中指定队列

    直接在spec中指定:

    apiVersion: scheduling.volcano.sh/v1beta1
    kind: PodGroup
    metadata:
    name: ml-training
    spec:
    minMember: 5
    queue: production # 指定使用 production 队列
  3. 在 Volcano Job 中指定队列

    apiVersion: batch.volcano.sh/v1alpha1
    kind: Job
    metadata:
    name: tensorflow-training
    spec:
    minAvailable: 3
    schedulerName: volcano
    queue: production # 指定使用 production 队列

Queue 的实际应用场景

  1. 多租户环境

    • 为不同部门或团队创建独立队列
    • 确保每个部门都有公平的资源分配
  2. 优先级划分

    • 为关键业务创建高权重队列
    • 为非关键任务创建可回收队列
  3. 资源限制

    • 防止单个应用消耗过多集群资源
    • 为不同类型的工作负载设置适当的资源上限

Queue机制是Volcano实现多租户资源管理和公平调度的关键组件,它使得集群管理员可以更精细地控制资源分配策略,提高集群资源利用率和用户满意度。

Volcano Job资源

Volcano Job(简称 vcjob)是 Volcano 提供的一种高级作业资源类型,扩展了 Kubernetes 原生的 Job 资源,为高性能计算和批处理场景提供了更丰富的功能。

Volcano Job 的作用

  1. 多任务类型支持

    • 支持在一个作业中定义多种不同类型的任务(task
    • 每种任务类型可以有不同的镜像、资源需求和副本数
  2. 生命周期管理

    • 支持在作业生命周期的不同阶段执行特定命令
    • 包括启动前、运行中、完成后等阶段
  3. 高级调度策略

    • 支持指定最小可用数量(minAvailable
    • 支持指定队列、优先级和调度策略
  4. 容错和恢复机制

    • 提供多种重启策略(RestartPolicy
    • 支持在任务失败时的不同处理方式

Volcano Job 配置示例

下面是一个TensorFlow分布式训练任务的Volcano Job配置示例:

apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: tensorflow-training
spec:
minAvailable: 3
schedulerName: volcano
queue: ml-jobs
policies:
- event: PodEvicted
action: RestartJob
- event: PodFailed
action: RestartJob
tasks:
- replicas: 1
name: ps
template:
spec:
containers:
- image: tensorflow/tensorflow:latest
name: tensorflow
command: ["python", "/app/ps.py"]
resources:
requests:
cpu: 2
memory: 4Gi
- replicas: 2
name: worker
template:
spec:
containers:
- image: tensorflow/tensorflow:latest-gpu
name: tensorflow
command: ["python", "/app/worker.py"]
resources:
requests:
cpu: 4
memory: 8Gi
nvidia.com/gpu: 1

Volcano Job 的特性

  1. 多任务类型

    • 在上面的示例中,定义了两种任务类型:ps(参数服务器)和 worker(工作节点)
    • 每种类型有不同的副本数和资源需求
  2. 事件处理策略

    • 定义了当 Pod 被驱逐或失败时重启整个作业的策略
    • 可以根据不同事件类型执行不同的操作
  3. 队列和调度器指定

    • 指定使用 volcano 调度器和 ml-jobs 队列
    • 确保作业在正确的资源池中运行

Volcano Job 的实际应用场景

  1. 分布式机器学习

    • TensorFlowPyTorch 等分布式训练任务
    • 支持参数服务器和工作节点的协调调度
  2. 大数据处理

    • SparkFlink 等大数据处理框架
    • 支持MasterWorker节点的组织管理
  3. MPI 并行计算

    • 高性能计算和科学模拟
    • 支持多节点协同计算

Volcano Job 为复杂的分布式工作负载提供了完整的生命周期管理和调度能力,是 Volcano 系统中最强大的资源类型之一。

参考资料