KubeRay 源码阅读:从 Operator 主备切换到 Ray 服务恢复

KubeRay 源码阅读:从 Operator 主备切换到 Ray 服务恢复

💡 原文中文,约10300字,阅读约需25分钟。
📝

内容提要

本文分析 KubeRay Operator 的主备切换与 Ray 服务恢复。选主通过 Lease 竞争,默认仅一个副本,需配置多副本才有备用。新 leader 依赖已有资源重新协调,但无 fencing 机制,在途请求可能重复执行;控制面失联时无法补 Pod 或回写状态。worker 丢失可补建,但 actor 内存难恢复;head 丢失后 GCS 元数据需 Redis 容错才能恢复。RayService 蓝绿切换非原子操作,不保证请求零失败。

🔎

延伸解读

选主开启不等于高可用:副本数才是关键

KubeRay 默认启用选主,但 Helm chart 默认只部署一个 Operator 副本。这意味着进程退出后没有备用实例立即接管,协调工作中断。要实现主备切换,必须显式设置 replicas 大于 1。此外,Deployment 使用 Recreate 更新策略,升级时会先终止旧 Pod 再创建新 Pod,即使多副本也无法保证升级期间持续有实例协调。因此,高可用部署需要同时考虑副本数和更新策略。

无 fencing 机制:在途请求可能重复执行

KubeRay 依赖 Lease 选主,但 client-go 不提供 fencing 保证。旧 leader 发出的请求若已被 API Server 或 Ray Dashboard 接收,租约变化不会撤销这些请求或回滚副作用。新 leader 重新协调时,可能重复执行相同操作,例如重复创建同名 Job(可能遇到 AlreadyExists)。若业务要求 exactly-once,需要接收端实现幂等键或事务,不能仅依赖 Operator 主备切换。

GCS 容错有条件:Redis 后端与数据保留

head 节点承载 GCS,默认内存存储下,head 丢失会导致元数据丢失,重建 head 无法恢复原集群状态。启用 Redis 容错需配置 gcsFaultToleranceOptions.backend: redis 和 redisAddress,KubeRay 会注入环境变量。恢复要求 Redis 数据仍在、可访问,并使用相同存储命名空间(默认以 RayCluster UID 隔离)。但 Redis 路径默认启用清理,删除集群时会删除对应数据,外部 Redis 不等于永久归档。

RayService 蓝绿切换:非原子操作,不保证零失败

RayService 蓝绿升级时,Controller 先更新 head Service 的 selector,再更新 serve Service,最后提升 pending 为 active。这些步骤不是跨资源事务,第二次更新失败可能留下部分切换状态。即使切换成功,Service 变更传播到实际转发路径需要时间,在途长请求、连接断开和客户端重试行为各异。若 active 已故障而 pending 未就绪,准备过程无法补回已中断的请求。因此,不能将这种切换视为零中断。

Q&A

KubeRay Operator 默认开启了选主,为什么实际只有一个实例在运行?

因为 Helm chart 的 values.yaml 中 replicas 默认为 1,虽然 leaderElectionEnabled 为 true,但只部署一个副本,没有备用实例。要有多副本需显式设置 replicas: 2。

KubeRay Operator 主备切换时,旧 leader 已经发出的请求会被新 leader 撤销吗?

不会。client-go 不提供 fencing 机制,租约变化不会撤销已被 API Server 或 Ray Dashboard 接收的请求,也不会回滚外部副作用。在途请求可能重复执行,需要接收端幂等键或事务来保证 exactly-once。

KubeRay 中 worker Pod 丢失后,actor 的内存状态能自动恢复吗?

不能自动恢复。KubeRay 会根据期望配置补建 worker Pod,但 actor 的 max_restarts 默认为零,即使允许重启,也需要应用自己实现检查点等机制来恢复内存状态。

Ray 集群的 head 节点丢失后,GCS 元数据怎样才能恢复?

需要配置 GCS 容错,将元数据存储到外部 Redis。设置 gcsFaultToleranceOptions.backend: redis 和 redisAddress 后,KubeRay 会注入 RAY_REDIS_ADDRESS 等参数,GCS 重启时从 Redis 加载元数据。恢复要求 Redis 数据仍在、可访问,并使用相同存储命名空间。

RayService 蓝绿切换能保证请求零失败吗?

不能。切换涉及两次顺序的 Service 更新,不是原子操作,第二次更新失败可能留下部分切换状态。Service 变更传播、在途长请求、连接断开和客户端重试都会影响请求,因此不能保证零失败。

当 Kubernetes 控制面失联时,KubeRay Operator 的备用实例能接管吗?

不能。主备都无法访问 API Server 时,备用无法更新 Lease,leader 也无法续约,CR 和 Pod 的查询写入同样受阻。已有 Ray 计算可能继续,但补建 Pod、扩容和状态回写会受影响。

🏷️

标签

➡️

继续阅读