(进阶) 理解 Kubernetes 环境下的 Ray 自动扩缩器#
我们描述了 Ray 自动扩缩器与 Kubernetes 生态系统中其他自动扩缩器之间的关系。
Ray 自动扩缩器 vs. 水平 Pod 自动扩缩器#
Ray 自动扩缩器负责调整 Ray 集群中 Ray 节点的数量。在 Kubernetes 中,每个 Ray 节点都以 Kubernetes Pod 的形式运行。因此,在 Kubernetes 环境下,Ray 自动扩缩器会调整 Ray Pod 的数量。从这个意义上说,Ray 自动扩缩器起的作用类似于 Kubernetes 的 水平 Pod 自动扩缩器 (HPA)。然而,以下特性区分了 Ray 自动扩缩器和 HPA。
负载指标基于应用语义#
水平 Pod 自动扩缩器根据 CPU 和内存等物理使用指标来决定扩缩。相比之下,Ray 自动扩缩器使用任务和 Actor 注释中表示的逻辑资源。例如,如果您的 RayCluster CR 中每个 Ray 容器规范都指定了 10 个 CPU 的限制,并且您提交了 20 个带有 @ray.remote(num_cpus=5) 注释的任务,则会创建 10 个 Ray Pod 来满足 100 个 CPU 的资源需求。在这方面,Ray 自动扩缩器类似于 Kubernetes 集群自动扩缩器,它根据容器资源请求中表示的逻辑资源来做出扩缩决策。
精细化的缩减控制#
为了适应 Ray 应用的状态性,Ray 自动扩缩器比水平 Pod 自动扩缩器拥有更精细化的缩减控制。除了确定期望的扩缩数量外,Ray 自动扩缩器还能精确选择要缩减的 Pod。然后,KubeRay 操作员会删除该 Pod。相比之下,水平 Pod 自动扩缩器只能减少副本数量,而无法精确控制删除哪些 Pod。对于 Ray 应用来说,缩减一个随机 Pod 可能会很危险。
架构:每个 Ray 集群一个 Ray 自动扩缩器#
水平 Pod 自动扩缩是由 Kubernetes 控制平面中的管理器集中控制的;该管理器控制许多 Kubernetes 对象的扩缩。相比之下,每个 Ray 集群都由其自己的 Ray 自动扩缩器进程管理,该进程作为 sidecar 容器运行在 Ray head Pod 中。这种设计选择是基于以下考虑
可扩展性。 自动扩缩每个 Ray 集群需要处理来自该 Ray 集群的大量资源数据。
简化的版本控制和兼容性。 自动扩缩器和 Ray 都是作为 Ray 仓库的一部分开发的。自动扩缩器和 Ray 核心之间的接口很复杂。为了支持运行不同 Ray 版本的多个 Ray 集群,因此最好匹配 Ray 和自动扩缩器的代码版本。每个 Ray 集群运行一个自动扩缩器并匹配代码版本可以确保兼容性。
Ray 自动扩缩器与 Kubernetes 集群自动扩缩器#
Ray 自动扩缩器和 Kubernetes 集群自动扩缩器 是互补的。在 Ray 自动扩缩器决定创建 Ray Pod 后,Kubernetes 集群自动扩缩器可以配置 Kubernetes 节点,以便放置该 Pod。类似地,在 Ray 自动扩缩器决定删除一个空闲 Pod 后,Kubernetes 集群自动扩缩器可以清理剩余的空闲 Kubernetes 节点。建议配置您的 RayCluster,使其每个 Kubernetes 节点最多只能容纳一个 Ray Pod。如果您遵循此模式,Ray 自动扩缩器的 Pod 扩缩事件将与集群自动扩缩器的节点扩缩事件大致一一对应。(我们说“大致”是因为 Ray Pod 可能在底层 Kubernetes 节点被缩减之前就被删除并替换为新的 Ray Pod。)
垂直 Pod 自动扩缩器#
Ray 自动扩缩器与 Kubernetes 垂直 Pod 自动扩缩器 (VPA) 之间没有关系,VPA 用于根据当前和过去的用量将单个 Pod 调整到合适的大小。如果您发现您的单个 Ray Pod 负载过高,有多种手动技术可以降低负载。一种方法是通过增加 ray.remote 注释中指定的资源要求,来安排每个节点上运行的任务/Actor 更少。例如,将 @ray.remote(num_cpus=2) 更改为 @ray.remote(num_cpus=4) 会使给定 Ray Pod 中能容纳的任务或 Actor 的数量减半。