部署到 Kubernetes#

本节旨在帮助你

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

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

  • 理解如何监控和更新你的应用程序。

将 Ray Serve 部署到 Kubernetes 可以利用 Ray Serve 的可扩展计算能力和 Kubernetes 的运维优势。这种结合还可以让你与可能在 Kubernetes 上运行的现有应用程序集成。在 Kubernetes 上运行时,请使用 KubeRay 中的 RayService 控制器。

注意: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 的文件中。

注意

  • 示例中的 RayService 为了演示目的使用了非常低的 numCpus 值。在生产环境中,请为 Serve 应用程序提供更多资源。在此处了解更多关于如何配置 KubeRay 集群的信息:此处

  • 如果你在部署期间必须安装依赖项,可以将它们添加到部署代码中的 runtime_env 中。在此处了解更多信息:此处

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

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

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

$ kubectl get rayservices
NAME                AGE
rayservice-sample   7s

$ kubectl get pods
NAME                                                      READY   STATUS    RESTARTS   AGE
service-sample-raycluster-454c4-worker-small-group-b6mmg  1/1     Running   0          XXs
kuberay-operator-7fbdbf8c89-4lrnr                         1/1     Running   0          XXs
rayservice-sample-raycluster-454c4-head-krk9d             1/1     Running   0          XXs

$ kubectl get services

rayservice-sample-head-svc                         ClusterIP   ...        8080/TCP,6379/TCP,8265/TCP,10001/TCP,8000/TCP,52365/TCP   XXs
rayservice-sample-raycluster-454c4-dashboard-svc   ClusterIP   ...        52365/TCP                                                 XXs
rayservice-sample-raycluster-454c4-head-svc        ClusterIP   ...        8000/TCP,52365/TCP,8080/TCP,6379/TCP,8265/TCP,10001/TCP   XXs
rayservice-sample-serve-svc                        ClusterIP   ...        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:
    Application Statuses:
      text_ml_app:
        Health Last Update Time:  2023-09-07T01:21:30Z
        Last Update Time:         2023-09-07T01:21:30Z
        Serve Deployment Statuses:
          text_ml_app_Summarizer:
            Health Last Update Time:  2023-09-07T01:21:30Z
            Last Update Time:         2023-09-07T01:21:30Z
            Status:                   HEALTHY
          text_ml_app_Translator:
            Health Last Update Time:  2023-09-07T01:21:30Z
            Last Update Time:         2023-09-07T01:21:30Z
            Status:                   HEALTHY
        Status:                       RUNNING
    Dashboard Status:
      Health Last Update Time:  2023-09-07T01:21:30Z
      Is Healthy:               true
      Last Update Time:         2023-09-07T01:21:30Z
    Ray Cluster Name:           rayservice-sample-raycluster-kkd2p
    Ray Cluster Status:
      Head:
  Observed Generation:  1
  Pending Service Status:
    Dashboard Status:
    Ray Cluster Status:
      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 示例中,将 Serve 配置中的 Translator 语言更改为德语:

  - 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 正在准备一个 pending cluster。pending cluster 健康后,它会成为 active cluster,并且之前的集群会被终止。

自动扩缩容#

你可以通过在 Serve 配置中设置 autoscaling 字段来为你的 Serve 应用程序配置自动扩缩容。在Serve 自动扩缩容指南中了解更多配置选项。

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

注意

在大多数用例中,建议启用 Kubernetes 自动扩缩容以充分利用集群资源。如果你使用 GKE,可以使用 AutoPilot Kubernetes 集群。有关说明,请参阅创建 AutoPilot 集群。对于 EKS,你可以使用 Cluster Autoscaler 启用 Kubernetes 集群自动扩缩容。有关详细信息,请参阅AWS 上的 Cluster Autoscaler。要了解 Kubernetes 自动扩缩容与 Ray 自动扩缩容之间的关系,请参阅Ray Autoscaler 与 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 应用程序健康检查的信息。

  • 你还可以查看控制器日志和部署日志,它们位于头节点 pod 和工作节点 pod 的 /tmp/ray/session_latest/logs/serve/ 下。这些日志包含有关特定部署失败原因和自动扩缩容事件的信息。

下一步#

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