在 Kubernetes 上部署#

本节将帮助您

  • 了解如何安装和使用 KubeRay operator。

  • 了解如何使用 RayService 部署 Ray Serve 应用程序。

  • 了解如何监控和更新您的应用程序。

在 Kubernetes 上部署 Ray Serve 提供了 Ray Serve 的可扩展计算能力以及 Kubernetes 的运维优势。这种组合还允许您与可能正在 Kubernetes 上运行的现有应用程序集成。在 Kubernetes 上运行时,请使用 RayService 控制器,该控制器来自 KubeRay

注意:Anyscale 是一个托管的 Ray 解决方案,它提供高可用性、高性能的自动伸缩、多云集群、Spot 实例支持等开箱即用的功能。

一个 RayService CR 将多节点 Ray 集群及其上的 Serve 应用程序封装到一个 Kubernetes Manifest 中。可以使用标准的 kubectl 命令来部署、升级和获取应用程序状态。本节将介绍如何在 Kubernetes 上部署、监控和升级 文本 ML 示例

安装 KubeRay Operator#

请按照 KubeRay 快速入门指南 进行操作,以

  • 安装 kubectlHelm

  • 准备 Kubernetes 集群

  • 部署 KubeRay Operator

设置 RayService 自定义资源 (CR)#

KubeRay 控制器运行后,通过创建和更新 RayService CR (示例) 来管理您的 Ray Serve 应用程序。

RayService CR 中的 spec 部分下,设置以下字段:

serveConfigV2:表示 Ray Serve 用于部署应用程序的配置。使用 serve build 打印 Serve 配置,然后直接复制粘贴到您的 Kubernetes 配置RayService CR 中。

rayClusterConfig:使用 RayCluster CR YAML 文件中的 spec 字段内容填充此字段。有关更多详细信息,请参阅 KubeRay 配置

提示

为了提高应用程序的可靠性,尤其是在处理可能需要很长时间才能下载的大型依赖项时,请考虑在镜像的 Dockerfile 中包含这些依赖项,以便在 Pod 启动后即可使用它们。

部署 Serve 应用程序#

创建 RayService 时,KubeRay 控制器首先使用提供的配置创建一个 Ray 集群。然后,一旦集群运行起来,它将使用 REST API 将 Serve 应用程序部署到该集群。控制器还会创建一个 Kubernetes Service,可用于将流量路由到 Serve 应用程序。

要查看示例,请部署 文本 ML 示例。该示例的 Serve 配置嵌入在 此示例 RayService CR 中。将此 CR 本地保存到一个名为 ray-service.text-ml.yaml 的文件中。

注意

$ curl -o ray-service.text-ml.yaml https://raw.githubusercontent.com/ray-project/kuberay/2ba0dd7bea387ac9df3681666bab3d622e89846c/ray-operator/config/samples/ray-service.text-ml.yaml

为了部署示例,我们只需使用 kubectl apply 应用 CR。这将创建底层的 Ray 集群,包括 head 和 worker 节点 pod(有关 Ray 集群的更多详细信息,请参阅 Ray 集群关键概念),以及可用于查询我们应用程序的服务。

$ kubectl apply -f ray-service.text-ml.yaml

$ kubectl get rayservices
NAME                SERVICE STATUS   NUM SERVE ENDPOINTS
rayservice-sample   Running          1

$ kubectl get pods
NAME                                                          READY   STATUS    RESTARTS   AGE
rayservice-sample-raycluster-7wlx2-head-hr8mg                 1/1     Running   0          XXs
rayservice-sample-raycluster-7wlx2-small-group-worker-tb8nn   1/1     Running   0          XXs

$ kubectl get services
NAME                                          TYPE        CLUSTER-IP        EXTERNAL-IP   PORT(S)                                         AGE
rayservice-sample-head-svc                    ClusterIP   None              <none>        10001/TCP,8265/TCP,6379/TCP,8080/TCP,8000/TCP   XXs
rayservice-sample-raycluster-7wlx2-head-svc   ClusterIP   None              <none>        10001/TCP,8265/TCP,6379/TCP,8080/TCP,8000/TCP   XXs
rayservice-sample-serve-svc                   ClusterIP   192.168.145.219   <none>        8000/TCP                                        XXs

请注意,上面的 rayservice-sample-serve-svc 是可用于向 Serve 应用程序发送查询的服务——这将在下一节中使用。

查询应用程序#

一旦 RayService 正在运行,我们就可以通过 KubeRay 控制器创建的服务通过 HTTP 查询它。该服务可以直接从集群内部查询,但要从您的笔记本电脑访问它,您需要配置一个 Kubernetes Ingress 或使用下面的端口转发。

$ kubectl port-forward service/rayservice-sample-serve-svc 8000
$ curl -X POST -H "Content-Type: application/json" localhost:8000/summarize_translate -d '"It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief"'
c'était le meilleur des temps, c'était le pire des temps .

获取应用程序状态#

RayService 运行时,KubeRay 控制器会持续监控它,并将相关的状态更新写入 CR。您可以使用 kubectl describe 查看应用程序的状态。这包括集群状态、诸如健康检查失败或重启等事件,以及 serve status 报告的应用程序级别状态。

$ kubectl get rayservices
NAME                AGE
rayservice-sample   7s

$ kubectl describe rayservice rayservice-sample
...
Status:
  Active Service Status:
    Ray Cluster Status:
      Available Worker Replicas:  1
      Desired CPU:                2500m
      Desired GPU:                0
      Desired Memory:             4Gi
      Desired TPU:                0
      Desired Worker Replicas:    1
      Endpoints:
        Client:     10001
        Dashboard:  8265
        Metrics:    8080
        Redis:      6379
        Serve:      8000
      Head:
        Pod IP:             10.48.99.153
        Pod Name:           rayservice-sample-raycluster-7wlx2-head-dqv7t
        Service IP:         10.48.99.153
        Service Name:       rayservice-sample-raycluster-7wlx2-head-svc
      Last Update Time:     2025-04-28T06:32:13Z
      Max Worker Replicas:  5
      Min Worker Replicas:  1
      Observed Generation:  1
  Observed Generation:      1
  Pending Service Status:
    Application Statuses:
      text_ml_app:
        Health Last Update Time:  2025-04-28T06:39:02Z
        Serve Deployment Statuses:
          Summarizer:
            Health Last Update Time:  2025-04-28T06:39:02Z
            Status:                   HEALTHY
          Translator:
            Health Last Update Time:  2025-04-28T06:39:02Z
            Status:                   HEALTHY
        Status:                       RUNNING
    Ray Cluster Name:                 rayservice-sample-raycluster-7wlx2
    Ray Cluster Status:
      Desired CPU:     0
      Desired GPU:     0
      Desired Memory:  0
      Desired TPU:     0
      Head:
  Service Status:  Running
Events:
  Type    Reason   Age                      From                   Message
  ----    ------   ----                     ----                   -------
  Normal  Running  2m15s (x29791 over 16h)  rayservice-controller  The Serve applicaton is now running and healthy.

更新应用程序#

要更新 RayService,请修改 Manifest 并使用 kubectl apply 进行应用。可以发生两种类型的更新:

  • 应用程序级别更新:当仅更改 Serve 配置选项时,更新将在同一 Ray 集群上就地应用。这支持轻量级更新,例如向上或向下扩展部署,或修改自动伸缩参数。有关更多信息,请参阅 轻量级更新

  • 集群级别更新:当更改 RayCluster 配置选项(例如更新集群的容器镜像)时,可能会导致集群级别更新。在这种情况下,将启动一个新集群,并将应用程序部署到其中。一旦新集群准备就绪,Kubernetes Service 将被更新以指向新集群,并且前一个集群将被终止。应用程序应该不会有任何停机时间,但请注意,这需要 Kubernetes 集群足够大,以便可以调度两个 Ray 集群。

示例:Serve 配置更新#

在上面的文本 ML 示例中,将 Translator 在 Serve 配置中的语言更改为德语。

  - name: Translator
    num_replicas: 1
    user_config:
      language: german

现在要更新应用程序,我们应用修改后的 Manifest:

$ kubectl apply -f ray-service.text-ml.yaml

$ kubectl describe rayservice rayservice-sample
...
  Serve Deployment Statuses:
    text_ml_app_Translator:
      Health Last Update Time:  2023-09-07T18:21:36Z
      Last Update Time:         2023-09-07T18:21:36Z
      Status:                   UPDATING
...

查询应用程序以查看不同的德语翻译。

$ curl -X POST -H "Content-Type: application/json" localhost:8000/summarize_translate -d '"It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief"'
Es war die beste Zeit, es war die schlimmste Zeit .

更新 RayCluster 配置#

更新 RayCluster 配置的过程与更新 Serve 配置相同。例如,我们可以在 Manifest 中将工作节点数更新为 2。

workerGroupSpecs:
  # the number of pods in the worker group.
  - replicas: 2
$ kubectl apply -f ray-service.text-ml.yaml

$ kubectl describe rayservice rayservice-sample
...
  pendingServiceStatus:
    appStatus: {}
    dashboardStatus:
      healthLastUpdateTime: "2022-07-18T21:54:53Z"
      lastUpdateTime: "2022-07-18T21:54:54Z"
    rayClusterName: rayservice-sample-raycluster-bshfr
    rayClusterStatus: {}
...

在状态中,您可以看到 RayService 正在准备一个待定集群。待定集群健康后,它将成为活动集群,并且前一个集群将被终止。

自动伸缩#

您可以通过在 Serve 配置中设置自动伸缩字段来配置 Serve 应用程序的自动伸缩。在此处 Serve 自动伸缩指南 中了解有关配置选项的更多信息。

要在 KubeRay 集群中启用自动伸缩,您需要将 enableInTreeAutoscaling 设置为 True。此外,还有其他选项可用于配置自动伸缩行为。有关更多详细信息,请参阅此处的文档 此处

注意

在大多数用例中,建议启用 Kubernetes 自动伸缩以充分利用集群中的资源。如果您正在使用 GKE,可以使用 Autopilot Kubernetes 集群。有关说明,请参阅 创建 Autopilot 集群。对于 EKS,您可以通过利用 Cluster Autoscaler 来启用 Kubernetes 集群自动伸缩。有关详细信息,请参阅 AWS 上的 Cluster Autoscaler。要了解 Kubernetes 自动伸缩与 Ray 自动伸缩之间的关系,请参阅 Ray 自动伸缩与 Kubernetes Cluster Autoscaler

负载均衡器#

设置 Ingress 以使用负载均衡器公开您的 Serve 应用程序。请参阅 此配置

注意

  • Ray Serve 在每个节点上运行 HTTP 代理,允许您使用 /-/routes 作为节点健康检查的端点。

  • Ray Serve 使用端口 8000 作为默认的 HTTP 代理流量端口。您可以通过在 Serve 配置中设置 http_options 来更改端口。有关更多详细信息,请参阅 此处

监控#

使用 Ray Dashboard 监控您的 Serve 应用程序。

注意

  • 为了对 Serve 中的应用程序部署失败进行故障排除,您可以运行 kubectl logs -f <kuberay-operator-pod-name>(例如,kubectl logs -f kuberay-operator-7447d85d58-lv7pf)来检查 KubeRay Operator 日志。KubeRay Operator 日志包含有关 Serve 应用程序部署事件和 Serve 应用程序健康检查的信息。

  • 您还可以检查控制器日志和部署日志,它们位于 head 节点 pod 和 worker 节点 pod 的 /tmp/ray/session_latest/logs/serve/ 目录下。这些日志包含有关特定部署失败原因和自动伸缩事件的信息。

后续步骤#

请参阅 添加端到端容错能力,以了解有关 Serve 的故障条件以及如何防范它们的更多信息。