第 10 篇|总结:从 KubeRay 与 Volcano 看 Operator 设计

第 10 篇|总结:从 KubeRay 与 Volcano 看 Operator 设计

💡 原文中文,约6400字,阅读约需16分钟。
📝

内容提要

本文总结KubeRay与Volcano源码阅读:用户提交RayJob后,KubeRay创建RayCluster及head、worker Pod,集群就绪后由submitter经Ray Jobs API提交程序。启用Volcano时,先写PodGroup,再在Pod上标注调度器与组信息,由Volcano负责Pod绑定。KubeRay协调、Volcano调度与Ray运行时三套循环通过Kubernetes对象和Ray API衔接,各自独立重试。恢复依赖可重建状态链,高可用需分层看待。

🔎

延伸解读

三套控制循环的独立性与衔接

KubeRay协调循环、Volcano调度循环和Ray运行时循环各自独立运行,通过Kubernetes对象和Ray API衔接。KubeRay观察RayJob、RayCluster和Pod,通过Reconcile收敛资源;Volcano Scheduler周期性建立Session,处理Pod绑定和资源竞争;Ray运行时在集群内执行task和actor。三者没有共享进程内状态,允许独立重试,但状态交接点需要仔细核对。

状态分层与恢复边界

源码中事件、状态和正在执行的工作分属不同层次。Kubernetes API中的spec、status、owner reference是持久化事实,Controller重启后可重新读取;informer cache、工作队列、expectations属于进程内状态,可丢失并从对象重建;Ray的GCS、对象存储保存计算侧状态。恢复能否继续,取决于推进流程所需信息是否仍可从对应状态源取得。

调度结论的层次性

Volcano的PodGroup、Gang、Queue等机制只解决Pod调度条件。PodGroup满足minMember不等于所有worker已运行;Queue获得份额不等于节点被永久划给某组;RayCluster Ready更不等于用户程序成功完成。每一项状态只回答其所在层次的问题,不能跨层推断。

源码阅读的适用边界

基于固定版本源码,可以确认控制路径、对象创建顺序和协作字段,但协调延迟、吞吐、恢复时间、资源利用率等仍需部署或实验确认。源码说明判断条件,时间、容量和稳定性数据需在目标环境测量。阅读时应区分版本条件,不用当前实现替代其他版本行为。

❓

Q&A

从提交 RayJob 到用户程序真正运行,中间经历了哪些主要阶段?

主要阶段包括:使用者提交 RayJob;KubeRay 根据 RayJob 创建专用 RayCluster;RayCluster Controller 创建 head、worker Pod 和 Service;集群 Ready 后 KubeRay 创建 submitter Kubernetes Job;submitter 连接 Ray Dashboard 的 Jobs API 提交入口命令;程序进入 Ray 的任务、Actor 和资源调度体系执行。启用 Volcano 时,还会在创建 RayCluster 前写入 PodGroup,并在 Pod 上标注调度器与组信息。

KubeRay、Volcano 和 Ray 运行时这三套控制循环是如何协作的?

三套循环通过 Kubernetes 对象和 Ray API 依次衔接,各自独立重试。KubeRay Controller 观察 RayJob、RayCluster 和 Pod,通过 Reconcile 收敛 Kubernetes 资源;Volcano Scheduler 周期性建立 Session,处理一组 Pod 能否获得节点及多作业资源竞争;Ray 运行时在集群内部根据可用资源执行 task 和 actor,并通过 Ray Jobs API 管理用户程序提交与状态。它们不共享进程内状态,KubeRay 与 Volcano 通过 PodGroup、Pod 字段和 RayCluster status 交接信息,submitter 再通过 Ray Jobs API 跨入 Ray 运行时边界。

启用 Volcano 后,KubeRay 与 Volcano 之间通过哪些字段或对象协作?

启用 Volcano 时,创建 RayCluster 之前先写入 PodGroup;创建 Pod 时再写入 schedulerName、PodGroup 名和成员角色。Volcano 接管 Pod 获得节点的过程,但不会替 KubeRay 判断 RayCluster 是否 Ready,也不会替 Ray 执行用户程序。PodGroup 表达最低成员和资源需求,Pod 上的字段表达调度器选择与组关系,RayCluster status 表达 KubeRay 观察到的集群状态。

KubeRay Operator 重启后,协调状态是如何恢复的?

Operator 重启后会重新 list/watch Kubernetes 对象,再从 spec、status、label、owner reference 和实际子资源恢复协调。进程内队列和锁可以丢失,因为它们能从对象状态重新建立。若推进下一步所需的信息只存在于已丢失的进程内状态,恢复链就会中断。

KubeRay 的高可用需要从哪些层面分别考虑?

高可用要按层拆开:Leader Election 解决多个 Operator 副本中谁写控制面;Kubernetes 控制面是否可用、Ray head 和 GCS 是否恢复、RayService 是否能切换服务集群,是另外几层条件。某一层恢复,不代表正在执行的计算或外部请求已经恢复。

Volcano 的 PodGroup、Gang、Queue 等概念在完整调度流程中分别起什么作用?

PodGroup 把多个 Pod 表达为一组,minResources 在 enqueue 阶段参与资源准入,minMember 参与 Gang 的提交判断。Gang 判断发生在试分配过程中,条件不满足时可撤销本轮 Statement 中的尝试,避免只绑定一部分成员。Queue 组织多组作业的资源竞争,weight、capability、request、allocated 和 deserved 共同影响 Queue 还能否继续使用资源。DRF 等策略决定检查顺序,节点 predicates 最终确认某个具体 Node 能否接纳 Pod。preempt 和 reclaim 选出需要释放的成员后,资源还要等待 Pod 实际退出才能重新用于绑定。

基于固定版本源码,哪些结论可以确认,哪些还需要部署或实验验证?

可以从源码确认的包括:Controller 的 watch、队列、Reconcile 和重试路径;RayJob、RayCluster、PodGroup 和成员 Pod 的创建顺序;Leader Election、状态写回和对象重建所依赖的信息;Gang、Queue 份额、抢占与回收的源码条件;KubeRay 与 Volcano 通过哪些字段协作;submitter 何时创建以及它怎样进入同一个 PodGroup。仍需部署或实验确认的包括:特定集群规模下的协调延迟与吞吐;安装版本、CRD、Webhook 与 Kubernetes 版本的实际兼容性;控制面故障时的真实恢复时间;具体工作负载下的排队时间和资源利用率;Admission 注入、Pod overhead 等环境差异造成的最终资源请求;用户代码、依赖包、存储和结果提交的可靠性。

🏷️

标签

➡️

继续阅读