使用kubebuilder编写自己的MPI Operator

上次篇文章总结了MPI Operator需要做的事情,以及手动部署的实践。我们既然都可以手动部署出worker了,干脆再进一步,将该过程用代码实现,写一个MPI Operator。Github

动机

目前的MPI Operator还存在哪些不足?

  1. 代码较多。大概4000+行,本身属于kubeflow子项目,存在较多kubeflow依赖。不过该Operator的核心功能并不复杂。
  2. 缺少对于缺失Pod的恢复操作。代码中,看上去是ReplicaSet控制Worker/Launcher Pod,实际上是Operator单独控制Pod,源码中以Pod为单位进行Create,而非ReplicaSet。原因可能是ReplicaSet无法控制名字生成,从而无法事先写好ConfigMap中的hostfile。因此,只要有一个worker pod启动失败了,那么就需要手动删除MPIJob(触发Operator删除所有Pod),再重新Create MPIJob。
  3. 缺少根据MPIJob的修改更新Pod的控制操作。如果想修改MPIJob任务(比如修改workers执行的命令),同样也要手动删除现有MPIJob,再重新Create新的MPIJob。相比于ConfigMap,RBAC有Update,源码位置,Worker没有,源码位置。原因是Pod能修改的部分非常有限,一般做法是删除Pod再重建Pod,而这些操作通过Update Pod的控制器来触发(比如ReplicaSet,StatefulSet)。
  4. 一些不影响使用的小问题。比如上一篇文章中我们发现的一些不必要的配置,如kubectl-delivery中生成的hosts文件等。比如缺乏对于ConfigMap,ServiceAccount等资源的回收。比如等待所有workers就绪的功能可以交给Operator来实现,而非kubectl-delivery。

我正好这几天学习了kubebuilder,尝试重构一下MPI Operator代码,写一个简化版的,学习其流程,以便之后做一些自定义的修改。

需求与做法

Operator本质上是用代码来自动化部署与管理yaml,按照我们手动部署的思路来就行

  1. 我想利用operator框架(如kubebuilder)来实现它,并且不使用kubeflow相关的依赖,而且尽量简单,目前该项目的go代码大概在800行之内,并且由于新建ConfigMap,RBAC(Role,RoleBinding,ServiceAccount)重复代码较多,实际逻辑部分的代码比较少也比较简单。

  2. 添加Worker Pod自动滚动更新(不包括Launcher Pod),也即当用户修改MPIJob中Workers对应的信息,比如修改了command,我们需要检测到这一点,并让workers pod可以滚动更新,同时还需保证workers pod的名字可以事先写入hostfile中,实现方式:

    1. 通过一个控制器StatefulSet控制Workers Pod,而非直接控制Workers Pod,保证名字
    2. 当MPIJob更新时,会调用Reconcile函数,其中会Update workers对应的StatefulSet,从而让Pod滚动更新
  3. 添加自动恢复(Worker statefulset与Launcher pod)。我们需要察觉StatefulSet或Pod缺失,并重新Create。以便如果想重新跑任务可以直接手动删除Launcher Pod,如果想重新拉取最新代码,可以手动删除Worker StatefulSet等。做法:

    1. 给每个MPIJob添加了周期性检测,比如周期为1分钟调用一次Reconcile函数
    2. 在Reconcile函数中,发现缺失资源,则根据最新MPIJob内容新建资源
  4. 添加等待Worker StatefulSet就绪才生成并运行Launcher Pod的功能。因为Worker Pod上通常需要安装一些运行环境,如requirements.txt,或者git clone代码,此时不能生成Launcher Pod执行任务。做法是在新建Launcher Pod之前检测Worker StatefulSet的Status,直到ReadyReplicas数量等于workers数量。

  5. 删除一些不必要的配置

    1. 删除worker pod中的kubexec.sh挂载(我不确定。它似乎不影响horovodrun,却影响mpirun)

    2. 删除kubectl-delivery中两个功能:

      1. 等待workers就绪。这个放到Operator中实现
      2. 在/opt/kube文件夹下生成hosts文件

      只保留其复制kubectl的功能(只需在Dockerfile中写即可)


使用kubebuilder编写自己的MPI Operator
https://fffffaraway.github.io/2022/07/27/write-mpi-operator/
Author
Song Wei
Posted on
July 27, 2022
Licensed under