本系列文章阅读KubeRay与Volcano源码。Ray以task和actor表达分布式计算,Kubernetes以Pod管理容器部署;KubeRay通过CRD和Operator管理RayCluster、RayJob等资源,Volcano提供Gang成组调度与队列资源共享。系列共十篇:前五篇追踪RayJob从提交到Pod运行的协调与恢复,后四篇引入Volcano分析批调度。
本文沿一次 RayJob 提交过程追踪 KubeRay 源码:RayJob Controller 根据 spec.rayClusterSpec 创建专用 RayCluster,RayCluster Controller 再创建 head 与 worker Pod;集群就绪后以 K8sJobMode 创建 submitter Job,通过 Ray Jobs API 提交入口程序并跟踪状态,结束后按 TTL 清理集群。
本文梳理 KubeRay 中 Pod 变化触发 Reconcile 的完整链路:kubelet 写入 Pod 状态,informer 缓存更新后由 handler 依据 owner reference 定位 RayCluster 并入队;Reconcile 重新读取对象,对比期望与现状后写回 status;RayJob 通过 Owns(RayCluster) 感知变化并提交作业。同时介绍 predicate 过滤、RequeueAfter 延时重排,以及排查事件未入队的方法。
KubeRay Operator 通过工作队列和协调协程管理大量 RayCluster。并发数限制同时执行的 Reconcile 轮数,默认 1,设为 2 则两个协程轮流处理不同对象。同一对象按键锁定,不会被并发处理。由于缓存滞后,需用 scale expectations 避免重复创建 Pod。版本冲突靠 resourceVersion 乐观并发检查处理。是否提高并发应依据队列积压、协调耗时和错误率等指标判断。
KubeRay Operator 重启后不依赖内存状态,而是通过 Kubernetes 中持久化的 spec、status 及已有资源恢复协调。RayJob 使用 jobDeploymentStatus 记录管理阶段,jobStatus 记录 Ray 作业状态。重启不会被记为失败或开启新执行轮次;若资源已创建但状态未写回,新 Operator 会根据 status 中的集群名和 submission ID 查找并复用已有资源。Ray 服务端以 submission ID 防止重复提交,但无法保证业务层面的 exactly-once。
本文分析 KubeRay Operator 的主备切换与 Ray 服务恢复。选主通过 Lease 竞争,默认仅一个副本,需配置多副本才有备用。新 leader 依赖已有资源重新协调,但无 fencing 机制,在途请求可能重复执行;控制面失联时无法补 Pod 或回写状态。worker 丢失可补建,但 actor 内存难恢复;head 丢失后 GCS 元数据需 Redis 容错才能恢复。RayService 蓝绿切换非原子操作,不保证请求零失败。
KubeRay Operator 通过 Volcano 适配器将 RayJob 转换为 PodGroup 等调度资源。适配器创建 PodGroup,设置 owner 引用、分组注解和 schedulerName;最低成员数不含 submitter 以避免启动死锁,但其资源仍提前计入。资源计算基于模板 requests,未涵盖 init 容器等。收尾时按存活集群重算需求,而非直接清零。
本文探讨了在Kubernetes环境中使用Ray分布式调试器的挑战与解决方案。通过将Code Server部署为Ray Head的Sidecar容器,成功解决了网络隔离问题,实现了无缝调试,简化了操作流程,并提供了实用的配置与使用指南。
完成下面两步后,将自动完成登录并继续当前操作。