侧边栏壁纸
博主头像
lance

不为失败找借口,只为成功找方法。

  • 累计撰写 28 篇文章
  • 累计创建 0 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

Volcano批量计算平台.md

lance
2025-03-19 / 0 评论 / 0 点赞 / 67 阅读 / 3,083 字
温馨提示:
本文最后更新于 2025-05-04,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

基本概念

Volcano是基于Kubernetes的高性能批量计算平台,目前支持几乎所有的主流计算框架,包括MindSpore、TensorFlow、Kubeflow、MPI、PyTorch、飞浆、Spark、HOROVOD 等。

img

背景

  • 需要部署多套 operator ;
  • 不同框架对作业管理、并行计算等要求不同;
  • 计算密集高,资源需求波动大,需要高级调度能力;

目的

  • 统一容器基础设施,提高资源利用率
  • 通用作业管理、队列Fair-share, Gang, bin-pack等高级调度算法
  • 简化运维管理

整体架构

Volcano利用声明式的CRD定义我们的API,主要有3个核心的API,Volcano Job、PodGroup、Queue。Volcano Job 是对高性能任务的通用定义,PodGroup提供了Job中Task的管理能力,Queue 为任务的分类提供了基础。

img

img

Queue

  • Queue的概念源于 Yarn,它是Cluster 级别的资源对象,可为其声明资源配额,也可由多namespace 共享,并且提供 soft isolation;

PodGroup

  • PodGroup是任务的分组,它与 queue 绑定,占用队列的资源。它与 Volcano Job 是一对一的关系;也可为其声明 Scheduling 条件;

Volcano Job

  • 它是批量计算作业的定义,支持定义作业所属队列、生命周期策略、任务模板以及持久卷等信息;

Volcano 核心组件主要包含三个:Admission、ControllerManager、Scheduler 。Admission对Volcano CRD API提供校验能力;ControllerManager负责对Volcano CRD进行资源管理; Scheduler对任务提供丰富的调度能力。

Job 工作流程

  1. 用户创建一个 Volcano 作业
  2. Volcano Admission 拦截作业的创建请求,并进行合法性校验
  3. Kubernetes 持久化存储 Volcano Job 到 ETCD
  4. ControllerManager 通过 List-Watch 机制观察到Job 资源的创建,创建任务(Pod)
  5. Scheduler 负责任务的调度,绑定 Node
  6. Kubelet Watch 到 Pod的创建,接管 Pod 的运行
  7. ControllerManager 监控所有任务的运行状态,保证所有的任务在期望的状态下运行

Volcano Scheduler

Volcano Scheduler 负责 Pod 调度的组件(在功能上可以对比下k8s原生的调度器kube-scheduler)它由一系列action 和plugin 组成 。action定义了调度各环节中需要执行的动作;plugin根据不同场景提供了action 中算法的具体实现细节。Volcano Scheduler具有高度的可扩展性,可以根据需要实现自己的action和plugin。

img

Volcano scheduler的工作流程如下:

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

actions

https://github.com/volcano-sh/volcano/tree/master/pkg/scheduler/actions action 是触发执行 plugin 的动作。

如果参照k8s scheduleraction相当于preFilter、Fileter、PostFilter、PreBind、Bind、PostBind等这些动作。

  • enqueue

Enqueue action负责通过一系列的过滤算法筛选出符合要求的待调度任务并将它们送入待调度队列。经过这个action,任务的状态将由pending变为inqueue。

  • allocate

Allocate action负责通过一系列的预选和优选算法筛选出最适合的节点。

  • preempt

Preempt action负责根据优先级规则为同一队列中高优先级任务执行抢占调度。

  • reclaim

Reclaim action负责当一个新的任务进入待调度队列,但集群资源已不能满足该任务所在队列的要求时,根据队列权重回收队列应得资源。

  • backfill

backfill action负责将处于pending状态的任务尽可能的调度下去以保证节点资源的最大化利用。

plugins

https://github.com/volcano-sh/volcano/tree/master/pkg/scheduler/plugins 举例一些常用的 plugins 实现方式。 插件有两个关键方法OnSessionOpenOnSessionClose, 用于在session开始和结束时执行。

  • gang

gang plugin 认为未处于 ready 状态(包括 Binding、Bound、Running、Allocated、Succeed、Pipelined)的任务具有更高的优先级。它会检查假如驱逐某些任务回收队列部分应得资源后,该任务所属的 Job 中任务的运行数量是否满足 minAvailable 的要求,以决定是否执行驱逐动作。

  • conformance

conformance plugin 认为命名空间 kube-system 下的任务具有更高的优先级。这些任务不能被抢占。

  • DRF

DRF plugin 认为占用资源较少的任务具有更高的优先级。它会尝试计算已分配给抢占者和被抢占者的资源总量,并在抢占者资源资源份额更少时触发抢占行为。

  • nodeorder

nodeorder plugin 通过一系列维度的打分算法,算出针对某个任务时所有的节点的得分情况。得分最高的节点被认为是针对该任务最合适的节点。

  • predicates

predictions plugin 通过一系列维度的评估算法,决定某个任务是否适合被绑定到某个节点。

  • priority

priority plugin 用于比较两个 job 或任务的优先级。它通过比较 job.spec.priorityClassName 来决定哪个job的优先级更高。对于两个任务,它会依次比较 task.priorityClassName、task.createTime、task.id in order来决定谁的优先级更高。

配置

# kubectl get configmap volcano-scheduler-configmap -nvolcano-system -oyaml 
apiVersion: v1
data:
volcano-scheduler.conf: |
actions: "enqueue, allocate, backfill"
tiers:
- plugins:
  - name: priority
  - name: gang
  - name: conformance
- plugins:
  - name: drf
  - name: predicates
  - name: proportion
  - name: nodeorder
  - name: binpack
kind: ConfigMap
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
  {"apiVersion":"v1","data":{"volcano-scheduler.conf":"actions: \"enqueue, allocate, backfill\"\ntiers:\n- plugins:\n  - name: priority\n  - name: gang\n  - name: conformance\n- plugins:\n  - name: drf\n  - name: predicates\n  - name: proportion\n  - name: nodeorder\n  - name: binpack\n"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"volcano-scheduler-configmap","namespace":"volcano-system"}}
creationTimestamp: "2020-08-15T04:01:02Z"
name: volcano-scheduler-configmap
namespace: volcano-system
resourceVersion: "266"
selfLink: /api/v1/namespaces/volcano-system/configmaps/volcano-scheduler-configmap
uid: 1effe4d6-126c-42d6-a3a4-b811075c30f5

在 volcano-scheduler.conf 中主要包括 actions 和 tiers 两部分。在 actions 中,使用逗号作为分隔符配置各需要执行的 action 。需要注意的是,action 的配置顺序就是 scheduler 的执行顺序。Volcano 本身不会对 action 顺序的合理性进行检查。tiers 中配置的 plugin 列表即为注册到 scheduler 中的 plugin。plugin 中实现的算法将会被 action 调用。

核心调度算法

  • Gang Scheduling
  • Fair Share
  • Preempt & Reclaim
  • Reserve & Backfill
  • Topology Aware Scheduling
  • GPU Sharing

默认调度

默认调度主要是依据各个pod创建时设置的request值,可能导致以下问题:

  • 业务实际负载需要的资源远大于创建时指定的request值,导致节点部署过密,影响业务运行稳定性;
  • 业务实际负载需要的资源小于创建时候指定的request值,导致节点部署稀疏,造成资源浪费

节点真实负载感知调度

默认调度器基于上述调度策略的主要原因是,k8s自己没有真实去获取节点真实资源消耗,导致无法实现更合理的资源调度。开源Prometheus可以获取到各个节点的真实负载情况,基于volcano调度插件的能力可以实现基于应用能够基于真实负载调度,在资源满足的情况下,Pod优先被调度至真实负载低的节点,集群各节点负载趋于均衡。

  • 支持基于节点使用的调度;
  • 过滤使用率高于用户定义的使用阈值的节点;
  • 优先处理节点使用情况的节点,并将pod调度到使用率较低的节点;



当前的基于分配率的调度模式在一些场景下会带来各个节点资源使用率不均衡的现象,如部分节点高分配率、低使用率等。v1.6.0版本中Volcano借助Prometheus采集的集群节点负载数据进行调度决策,保证各个节点使用率最大程度均衡,同时允许用户配置节点cpu,memory的上限值,防止部分节点使用率过高导致节点异常。更多详情可参考 https://github.com/volcano-sh/volcano/issues/1777,调度策略配置样例如下:

actions: "enqueue, allocate, backfill"  
tiers:
  - plugins:
      - name: priority
      - name: gang
      - name: conformance
      - name: usage  # usage based scheduling plugin
        enablePredicate: false  # If the value is false, new pod scheduling is not disabled when the node load reaches the threshold. If the value is true or left blank, new pod scheduling is disabled.
        arguments:
          usage.weight: 5
          cpu.weight: 1
          memory.weight: 1
          thresholds:
            cpu: 80    # The actual CPU load of a node reaches 80%, and the node cannot schedule new pods.
            mem: 70    # The actual Memory load of a node reaches 70%, and the node cannot schedule new pods.
  - plugins:
      - name: overcommit
      - name: drf
      - name: predicates
      - name: proportion
      - name: nodeorder
      - name: binpack
metrics:                               # metrics server related configuration
  type: prometheus                     # Optional, The metrics source type, prometheus by default, support "prometheus", "prometheus_adapt" and "elasticsearch"
  address: http://192.168.0.10:9090    # Mandatory, The metrics source address
  interval: 30s                        # Optional, The scheduler pull metrics from Prometheus with this interval, 30s by default
  tls:                                 # Optional, The tls configuration
    insecureSkipVerify: "false"        # Optional, Skip the certificate verification, false by default
  elasticsearch:                       # Optional, The elasticsearch configuration
    index: "custom-index-name"         # Optional, The elasticsearch index name, "metricbeat-*" by default
    username: ""                       # Optional, The elasticsearch username
    password: ""                       # Optional, The elasticsearch password
    hostnameFieldName: "host.hostname" # Optional, The elasticsearch hostname field name, "host.hostname" by default

高阶调度算法

默认打开调度器算法

Volcano 是一个统一的融合调度系统,不仅支持 AI、BigData 等计算类作业,也支持微服务工作负载,兼容 Kubernetes 默认调度器的 PodTopologySpread、NodeAffinity、PodAffinity 等调度插件,Kubernetes 默认调度插件能力在 Volcano 中默认开启。自 Volcano 1.8 版本开始,Kubernetes 默认调度插件可以通过配置文件的方式自由选择打开和关闭,默认全部打开,如果选择关闭部分插件,比如:关闭 PodTopologySpread 和 VolumeZone 插件,可以在 predicate 插件中将对应的值设置为 false,配置如下:

actions:"allocate, backfill, preempt"tiers:-plugins:-name:priority-name:gang-name:conformance-plugins:-name:drf-name:predicatesarguments:predicate.VolumeZoneEnable:falsepredicate.PodTopologySpreadEnable:false-name:proportion-name:nodeorder

支持 ClusterAutoscaler

在 Kubernetes 平台中,Volcano 除了作为批量计算业务的调度器之外,也被越来越多的用作通用服务的调度器。Node 水平伸缩(ClusterAutoscaler)是 Kubernetes 的核心功能之一,在面对用户业务量激增和节省运行成本方面发挥重要作用。Volcano 优化作业调度等相关逻辑,增强与 ClusterAutoscaler 的兼容互动能力,主要为以下两个方面:

  • 调度阶段进入 pipeline 状态的 pod 及时触发扩容
  • 候选节点分梯度打分,减少集群 terminating pod 对调度负载的影响,避免 pod 进入无效 pipeline 状态,从而导致集群误扩容

支持精细化管理 Node 资源

当节点中由于某种原因比如 device-plugin 上报信息异常,出现节点的某种资源总量小于已分配资源量时,Volcano 认为该节点数据不一致,会隔离节点,停止向该节点调度任何新的工作负载。在 1.8 版本中,对于节点资源进行精细化管理,比如:当节点的 GPU 总资源容量小于已分配资源量时,申请 GPU 资源的 pod 禁止再调度至该节点,申请非 GPU 资源的作业,将仍然允许正常向该节点调度。

0

评论区