由浅入深理解Volcano-Scheduler调度器

https://ericamblog.oss-cn-shanghai.aliyuncs.com/all/understand%20-volcano-scheduler-from-zero-title.png

前言

很久前就想整理的一篇文章,结果鸽了很久,终于得闲来完成。

前段时间,由于公司项目的原因,第一次接触到调度功能的开发。初次接触时,云里雾里,很多东西都是在做的过程中逐渐串在一起后才恍然大悟。后来,基于这次开发经验,也在公司内部组织了一次技术分享,帮助内部的小伙伴上手调度开发。本篇文章主要是记录经验分享,如果其中存在错误,欢迎大家指正。

基础知识

1.device-plugin简介

Kubernetes 作为一个自动化容器编排系统,在调度 pod 的时候会根据容器需要的资源进行节点的选择,节点的选择会分为预选和优选阶段。预选阶段会根据所有节点上剩余的资源量与 pod 需要的资源量进行对比,选出能够满足需求的节点。通常情况下,这里的资源都会包括 CPU 和 Memory ,就像下面这样:

1
2
3
4
5
6
7
resources:
  requests:
    memory: "64Mi"
    cpu: "250m"
  limits:
    memory: "128Mi"
    cpu: "500m"

当涉及到AI作业时, pod 便会需要 GPU 资源,并借助 Kubernetes 的调度器将容器调度到有空余 GPU 资源的节点。 在 1.11 版本之前的 Kubernetes 中,提供了 alpha.kubernetes.io/nvidia-gpu 的资源名称来帮助我们根据 GPU 资源调度。但是这也带来了一些问题:

  • Kubernetes 需要维护 NVIDIA GPU 相关的代码,增加了维护成本。

  • NVIDIA GPU 方面的专家不一定熟悉 Kubernetes ,这不符合让最擅长的人做最擅长的事的原则。

  • 除了 NVIDIA GPU ,还会有其他的计算资源需要支持。

因此, Kubernetes 在 1.8 版本引入了 device plugin 机制,将第三方的计算资源通过插件的方式引入 Kubernetes ,并且由第三方厂商自行维护。 所以,device-plugin的作用简要概括便是:将计算卡的资源字段(gpu/mlu等)向kubelet注册,并实时对节点资源监听,完成pod申请资源时gpu相关资源的绑定。

不同任务调度组件
不同任务调度组件

2.device-plugin工作时序图

device-plugin工作时序图
device-plugin工作时序图

每个device-plugin都是通过daemonset的方式,以pod的形式运行在每个节点上。

device-plugin的核心工作流程很简单:

  • 通过unix socket接口与kubelet建立连接关系,然后向其注册资源名称(例如gpu等)
  • 然后通过ListAndWatch接口,扫描节点上的device资源,然后发送健康/不健康的device资源,令kubelet感知。
  • 用户任务创建pod时,kubelet根据节点状态进行pod调度,为其分配device。(例如一台节点还剩余5张gpu卡,kubelet为一个2卡任务分配0卡和3卡)
  • device-plugin接收到kubelet的分配请求,调用Allocate接口函数完成资源分配。

以上便是device-plugin的核心工作流程。万变不离其宗,虽然不同device-plugin实现的功能不同,但都是可以通过先定位核心流程然后再发散去理解的。

kubernetes - device plugin的rpc接口

kubernetes 提供了 rpc 接口,方便向 kubelet 注册硬件资源。 device-plugin 为了实现和 kubelet 的通信,需要实现接口。

每个device-plugin项目都会包含与Kubelet的连接注册函数,以及下述五个rpc接口函数。

通过其可以基本了解:

  • 注册资源字段

  • 如何持续监听节点上的device

  • device分配策略。

  • ……………

然后根据项目功能逐步了解其他函数设计。

device-plugin的rpc接口函数
device-plugin的rpc接口函数

Volcano-Scheduler调度器

kubernetes deault scheduler

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

default scheduler
default scheduler

volcano scheduler

待写…./(ㄒoㄒ)/~~

0%