RayJob 快速入门#

先决条件#

  • KubeRay v0.6.0 或更高版本

    • KubeRay v0.6.0 或 v1.0.0:Ray 1.10 或更高版本。

    • 强烈建议使用 KubeRay v1.1.1 或更高版本:Ray 2.8.0 或更高版本。

什么是 RayJob?#

RayJob 管理两个方面

  • RayCluster:RayCluster 自定义资源管理 Ray 集群中的所有 Pod,包括一个头 Pod 和多个 worker Pod。

  • 作业 (Job):一个 Kubernetes 作业 (Job) 运行 ray job submit 命令将 Ray 作业提交到 RayCluster。

RayJob 提供什么?#

使用 RayJob,KubeRay 会自动创建 RayCluster 并在集群就绪后提交作业。您还可以配置 RayJob,使其在 Ray 作业完成后自动删除 RayCluster。

为了更好地理解以下内容,您应该了解以下概念的区别:

  • RayJob:由 KubeRay 提供的 Kubernetes 自定义资源定义。

  • Ray 作业 (job):Ray 作业是一个打包的 Ray 应用程序,可以在远程 Ray 集群上运行。有关更多详细信息,请参阅本文档

  • 提交器 (Submitter):提交器是一个 Kubernetes 作业 (Job),它运行 ray job submit 命令将 Ray 作业提交到 RayCluster。

RayJob 配置#

  • RayCluster 配置

    • rayClusterSpec - 定义用于运行 Ray 作业的 RayCluster 自定义资源。

    • clusterSelector - 使用现有的 RayCluster 自定义资源来运行 Ray 作业,而不是创建新的。有关示例配置,请参阅 ray-job.use-existing-raycluster.yaml

  • Ray 作业配置

    • entrypoint - 提交器运行 ray job submit --address ... --submission-id ... -- $entrypoint 命令将 Ray 作业提交到 RayCluster。

    • runtimeEnvYAML (可选):运行时环境,描述 Ray 作业运行所需的依赖项,包括文件、软件包、环境变量等。以多行 YAML 字符串形式提供配置。示例

      spec:
        runtimeEnvYAML: |
          pip:
            - requests==2.26.0
            - pendulum==2.1.2
          env_vars:
            KEY: "VALUE"
      

    有关更多详细信息,请参阅运行时环境(KubeRay 1.0.0 版本新增)

    • jobId (可选):定义 Ray 作业的提交 ID。如果未提供,KubeRay 会自动生成一个。有关提交 ID 的更多详细信息,请参阅Ray 作业 CLI API 参考

    • metadata (可选):有关 --metadata-json 选项的更多详细信息,请参阅Ray 作业 CLI API 参考

    • entrypointNumCpus / entrypointNumGpus / entrypointResources (可选):有关更多详细信息,请参阅Ray 作业 CLI API 参考

    • backoffLimit (可选,1.2.0 版本新增):指定标记此 RayJob 失败之前的重试次数。每次重试都会创建一个新的 RayCluster。默认值为 0。

  • 提交配置

    • submissionMode (可选):submissionMode 指定 RayJob 如何将 Ray 作业提交到 RayCluster。在“K8sJobMode”模式下,KubeRay operator 会创建一个提交器 Kubernetes Job 来提交 Ray 作业。在“HTTPMode”模式下,KubeRay operator 会向 RayCluster 发送请求来创建 Ray 作业。默认值为“K8sJobMode”。

    • submitterPodTemplate (可选):定义提交器 Kubernetes Job 的 Pod 模板。此字段仅在 submissionMode 为“K8sJobMode”时有效。

      • RAY_DASHBOARD_ADDRESS - KubeRay operator 会将此环境变量注入到提交器 Pod 中。该值是 $HEAD_SERVICE:$DASHBOARD_PORT

      • RAY_JOB_SUBMISSION_ID - KubeRay operator 会将此环境变量注入到提交器 Pod 中。该值是 RayJob 的 RayJob.Status.JobId

      • 示例:ray job submit --address=http://$RAY_DASHBOARD_ADDRESS --submission-id=$RAY_JOB_SUBMISSION_ID ...

      • 有关更多详细信息,请参阅 ray-job.sample.yaml

    • submitterConfig (可选):提交器 Kubernetes Job 的额外配置。

      • backoffLimit (可选,1.2.0 版本新增):标记提交器 Job 失败之前的重试次数。默认值为 2。

  • 自动资源清理

    • shutdownAfterJobFinishes (可选):确定 Ray 作业完成后是否回收 RayCluster。默认值为 false。

    • ttlSecondsAfterFinished (可选):仅当 shutdownAfterJobFinishes 为 true 时有效。KubeRay operator 会在 Ray 作业完成后 ttlSecondsAfterFinished 秒删除 RayCluster 和提交器。默认值为 0。

    • activeDeadlineSeconds (可选):如果 RayJob 未能在 activeDeadlineSeconds 内将其 JobDeploymentStatus 转换为 CompleteFailed,则 KubeRay operator 会将 JobDeploymentStatus 转换为 Failed,原因标记为 DeadlineExceeded

    • DELETE_RAYJOB_CR_AFTER_JOB_FINISHES (可选,1.2.0 版本新增):为 KubeRay operator 设置此环境变量,而不是为 RayJob 资源设置。如果您将此环境变量设置为 true,并且也将 shutdownAfterJobFinishes 设置为 true,则 RayJob 自定义资源本身将被删除。请注意,KubeRay 会删除由 RayJob 创建的所有资源,包括 Kubernetes Job。

  • 其他

    • suspend (可选):如果 suspend 为 true,KubeRay 会删除 RayCluster 和提交器。请注意,Kueue 也通过修改此字段来实现调度策略。如果您使用 Kueue 调度 RayJob,请避免手动更新此字段。

    • deletionPolicy (可选,v1.3.0 alpha 版本新增):指示 RayJob 完成后删除哪些资源。有效值包括 DeleteClusterDeleteWorkersDeleteSelfDeleteNone。如果未设置,删除策略基于 spec.shutdownAfterJobFinishes。此字段需要启用 RayJobDeletionPolicy 功能门限。

      • DeleteCluster - 作业完成后删除 RayCluster 自定义资源及其 Pod 的删除策略。

      • DeleteWorkers - 作业完成后仅删除 worker Pod 的删除策略。

      • DeleteSelf - 作业完成后删除 RayJob 自定义资源(及所有相关资源)的删除策略。

      • DeleteNone - 作业完成后不删除任何资源的删除策略。

示例:使用 RayJob 运行简单的 Ray 作业#

步骤 1:使用 Kind 创建 Kubernetes 集群#

kind create cluster --image=kindest/node:v1.26.0

步骤 2:安装 KubeRay operator#

按照RayCluster 快速入门通过 Helm repository 安装最新的稳定版 KubeRay operator。

步骤 3:安装 RayJob#

kubectl apply -f https://raw.githubusercontent.com/ray-project/kuberay/v1.3.0/ray-operator/config/samples/ray-job.sample.yaml

步骤 4:验证 Kubernetes 集群状态#

# Step 4.1: List all RayJob custom resources in the `default` namespace.
kubectl get rayjob
NAME            JOB STATUS   DEPLOYMENT STATUS   RAY CLUSTER NAME                 START TIME             END TIME   AGE
rayjob-sample                Running             rayjob-sample-raycluster-7965c   2025-04-09T10:29:17Z              117s
# Step 4.2: List all RayCluster custom resources in the `default` namespace.
kubectl get raycluster
NAME                             DESIRED WORKERS   AVAILABLE WORKERS   CPUS   MEMORY   GPUS   STATUS   AGE
rayjob-sample-raycluster-7965c   1                 1                   400m   0        0      ready    117s
# Step 4.3: List all Pods in the `default` namespace.
# The Pod created by the Kubernetes Job will be terminated after the Kubernetes Job finishes.
kubectl get pods --sort-by='.metadata.creationTimestamp'
NAME                                                      READY   STATUS    RESTARTS   AGE
kuberay-operator-6bc45dd644-tlsfn                         1/1     Running   0          2m26s
rayjob-sample-raycluster-7965c-head-n6nj8                 1/1     Running   0          117s
rayjob-sample-raycluster-7965c-small-group-worker-nlzwx   1/1     Running   0          117s
rayjob-sample-74pmj                                       1/1     Running   0          2s
# Step 4.4: Check the status of the RayJob.
# The field `jobStatus` in the RayJob custom resource will be updated to `SUCCEEDED` and `jobDeploymentStatus`
# should be `Complete` once the job finishes.
kubectl get rayjobs.ray.io rayjob-sample -o jsonpath='{.status.jobStatus}'
SUCCEEDED
kubectl get rayjobs.ray.io rayjob-sample -o jsonpath='{.status.jobDeploymentStatus}'
Complete

KubeRay operator 根据 rayClusterSpec 创建 RayCluster 自定义资源,并创建一个提交器 Kubernetes Job 来将 Ray 作业提交到 RayCluster。在本示例中,entrypointpython /home/ray/samples/sample_code.py,而 sample_code.py 是存储在 Kubernetes ConfigMap 中并挂载到 RayCluster 头 Pod 的 Python 脚本。由于 shutdownAfterJobFinishes 的默认值为 false,因此 Ray 作业完成后,KubeRay operator 不会删除 RayCluster 或提交器。

步骤 5:检查 Ray 作业的输出#

kubectl logs -l=job-name=rayjob-sample
2025-04-09 03:31:23,810	INFO worker.py:1654 -- Connecting to existing Ray cluster at address: 10.244.0.6:6379...
2025-04-09 03:31:23,818	INFO worker.py:1832 -- Connected to Ray cluster. View the dashboard at 10.244.0.6:8265 
test_counter got 1
test_counter got 2
test_counter got 3
test_counter got 4
test_counter got 5
2025-04-09 03:31:32,204	SUCC cli.py:63 -- -----------------------------------
2025-04-09 03:31:32,204	SUCC cli.py:64 -- Job 'rayjob-sample-jrrd2' succeeded
2025-04-09 03:31:32,204	SUCC cli.py:65 -- -----------------------------------

entrypoint 使用的 Python 脚本 sample_code.py 是一个简单的 Ray 脚本,它执行计数器增量函数 5 次。

步骤 6:删除 RayJob#

kubectl delete -f https://raw.githubusercontent.com/ray-project/kuberay/v1.3.0/ray-operator/config/samples/ray-job.sample.yaml

步骤 7:创建一个将 shutdownAfterJobFinishes 设置为 true 的 RayJob#

kubectl apply -f https://raw.githubusercontent.com/ray-project/kuberay/v1.3.0/ray-operator/config/samples/ray-job.shutdown.yaml

ray-job.shutdown.yaml 定义了一个 RayJob 自定义资源,其中 shutdownAfterJobFinishes: truettlSecondsAfterFinished: 10。因此,KubeRay operator 会在 Ray 作业完成后 10 秒删除 RayCluster。请注意,提交器作业不会被删除,因为它包含 Ray 作业日志,并且完成后不占用任何集群资源。此外,由于提交器作业拥有指向 RayJob 的所有者引用,因此当 RayJob 最终被删除时,它也会清理提交器作业。

步骤 8:检查 RayJob 状态#

# Wait until `jobStatus` is `SUCCEEDED` and `jobDeploymentStatus` is `Complete`.
kubectl get rayjobs.ray.io rayjob-sample-shutdown -o jsonpath='{.status.jobDeploymentStatus}'
Complete
kubectl get rayjobs.ray.io rayjob-sample-shutdown -o jsonpath='{.status.jobStatus}'
SUCCEEDED

步骤 9:检查 KubeRay operator 是否删除 RayCluster#

# List the RayCluster custom resources in the `default` namespace. The RayCluster
# associated with the RayJob `rayjob-sample-shutdown` should be deleted.
kubectl get raycluster
NAME                                      DESIRED WORKERS   AVAILABLE WORKERS   CPUS   MEMORY   GPUS   STATUS   AGE
rayjob-sample-shutdown-raycluster-pfqsf   1                 1                   400m   0        0      ready    45s

步骤 10:清理#

kind delete cluster

下一步#