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,包括一个 head Pod 和多个 worker Pod。
Job:Kubernetes Job 运行
ray job submit命令将 Ray 作业提交到 RayCluster。
RayJob 提供什么?#
使用 RayJob,KubeRay 会在集群准备就绪时自动创建一个 RayCluster 并提交一个作业。您还可以配置 RayJob 以在 Ray 作业完成后自动删除 RayCluster。
为了更好地理解以下内容,您应该了解以下概念的区别:
RayJob:KubeRay 提供的 Kubernetes 自定义资源定义。
Ray 作业:Ray 作业是可运行在远程 Ray 集群上的打包的 Ray 应用程序。有关更多详细信息,请参阅本文档。
Submitter:Submitter 是一个 Kubernetes Job,它运行
ray job submit命令将 Ray 作业提交到 RayCluster。
RayJob 配置#
RayCluster 配置
rayClusterSpec- 定义用于运行 Ray 作业的 **RayCluster** 自定义资源。clusterSelector- 使用现有的 **RayCluster** 自定义资源来运行 Ray 作业,而不是创建新的。有关示例配置,请参阅ray-job.use-existing-raycluster.yaml。
Ray 作业配置
entrypoint- Submitter 运行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(可选,v1.2.0 版本添加):指定在将此 RayJob 标记为失败之前重试的次数。每次重试都会创建一个新的 RayCluster。默认值为 0。
提交配置
submissionMode(可选):指定 RayJob 如何将 Ray 作业提交到 RayCluster。有三种可能的值,默认为K8sJobMode。K8sJobMode:KubeRay operator 创建一个 submitter Kubernetes Job 来提交 Ray 作业。HTTPMode:KubeRay operator 向 RayCluster 发送请求以创建 Ray 作业。InteractiveMode:KubeRay operator 等待用户将作业提交到 RayCluster。此模式当前为 alpha 版本,KubeRay kubectl 插件依赖于它。SidecarMode:KubeRay operator 将一个容器注入到 Ray head Pod 中以提交 Ray 作业。此模式不支持clusterSelector、submitterPodTemplate和submitterConfig,并且要求 head Pod 的重启策略为Never。
submitterPodTemplate(可选):定义 submitter Kubernetes Job 的 Pod 模板。此字段仅在submissionMode为 “K8sJobMode” 时有效。RAY_DASHBOARD_ADDRESS- KubeRay operator 将此环境变量注入到 submitter Pod。值为$HEAD_SERVICE:$DASHBOARD_PORT。RAY_JOB_SUBMISSION_ID- KubeRay operator 将此环境变量注入到 submitter Pod。值为 RayJob 的RayJob.Status.JobId。示例:
ray job submit --address=http://$RAY_DASHBOARD_ADDRESS --submission-id=$RAY_JOB_SUBMISSION_ID ...有关更多详细信息,请参阅ray-job.sample.yaml。
submitterConfig(可选):Submitter Kubernetes Job 的其他配置。backoffLimit(可选,v1.2.0 版本添加):在将 submitter Job 标记为失败之前重试的次数。默认值为 2。
自动资源清理
shutdownAfterJobFinishes(可选):确定 Ray 作业完成后是否回收 RayCluster。默认值为 false。ttlSecondsAfterFinished(可选):仅当shutdownAfterJobFinishes为 true 时生效。KubeRay operator 在 Ray 作业完成后ttlSecondsAfterFinished秒后删除 RayCluster 和 submitter。默认值为 0。activeDeadlineSeconds(可选):如果 RayJob 未能在activeDeadlineSeconds内将JobDeploymentStatus转换为Complete或Failed,KubeRay operator 会将JobDeploymentStatus转换为Failed,并将原因报告为DeadlineExceeded。DELETE_RAYJOB_CR_AFTER_JOB_FINISHES(可选,v1.2.0 版本添加):为 KubeRay operator 设置此环境变量,而不是为 RayJob 资源设置。如果您将此环境变量设置为 true,并且shutdownAfterJobFinishes也设置为 true,则 RayJob 自定义资源本身也会被删除。请注意,KubeRay 会删除 RayJob 创建的所有资源,包括 Kubernetes Job。
其他
suspend(可选):如果suspend为 true,KubeRay 会删除 RayCluster 和 submitter。请注意,Kueue 也通过修改此字段来实现调度策略。如果您使用 Kueue 来调度 RayJob,请避免手动更新此字段。deletionStrategy(可选,v1.5.1 版本 alpha):配置 RayJob 进入终止状态后的自动清理。此字段需要启用RayJobDeletionPolicy功能门。支持两种互斥的样式:基于规则 (推荐):将
deletionRules定义为由特定条件触发的删除操作列表。每个规则指定:policy:执行的删除操作 —DeleteCluster(删除整个 RayCluster 及其 Pod)、DeleteWorkers(仅删除 worker Pod)、DeleteSelf(删除 RayJob 和所有关联资源) 或DeleteNone(不删除)。condition:基于jobStatus(SUCCEEDED或FAILED) 和可选的ttlSeconds延迟来触发删除。此方法支持灵活的多阶段清理策略(例如,在成功时立即删除 worker,然后在 300 秒后删除集群)。
基于规则的模式与
shutdownAfterJobFinishes和全局ttlSecondsAfterFinished不兼容。请改用每个规则的condition.ttlSeconds。有关示例配置,请参阅ray-job.deletion-rules.yaml。
旧版 (已弃用):定义
onSuccess和onFailure策略。此方法已弃用,将在 v1.6.0 中移除。强烈建议迁移到deletionRules。旧版模式可以与
shutdownAfterJobFinishes和全局ttlSecondsAfterFinished结合使用。
有关详细的 API 规范,请参阅KubeRay API 参考。
示例:使用 RayJob 运行一个简单的 Ray 作业#
步骤 1:使用 Kind 创建 Kubernetes 集群#
kind create cluster --image=kindest/node:v1.26.0
步骤 2:安装 KubeRay operator#
按照KubeRay Operator 安装,通过 Helm 仓库安装最新的稳定版 KubeRay operator。
步骤 3:安装 RayJob#
kubectl apply -f https://raw.githubusercontent.com/ray-project/kuberay/v1.5.1/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
# [Example output]
# NAME JOB STATUS DEPLOYMENT STATUS RAY CLUSTER NAME START TIME END TIME AGE
# rayjob-sample SUCCEEDED Complete rayjob-sample-qnftt 2025-06-25T16:21:21Z 2025-06-25T16:22:35Z 6m53s
# Step 4.2: List all RayCluster custom resources in the `default` namespace.
kubectl get raycluster
# [Example output]
# NAME DESIRED WORKERS AVAILABLE WORKERS CPUS MEMORY GPUS STATUS AGE
# rayjob-sample-qnftt 1 1 400m 0 0 ready 7m48s
# 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
# [Example output]
# kuberay-operator-755f666c4b-wbcm4 1/1 Running 0 8m32s
# rayjob-sample-n2vj5 0/1 Completed 0 7m18ss => Pod created by a Kubernetes Job
# rayjob-sample-qnftt-head 1/1 Running 0 8m14s
# rayjob-sample-qnftt-small-group-worker-4f5wz 1/1 Running 0 8m14s
# 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}'
# [Expected output]: "SUCCEEDED"
kubectl get rayjobs.ray.io rayjob-sample -o jsonpath='{.status.jobDeploymentStatus}'
# [Expected output]: "Complete"
KubeRay operator 根据 rayClusterSpec 创建一个 RayCluster 自定义资源,并创建一个 submitter Kubernetes Job,将 Ray 作业提交到 RayCluster。在此示例中,entrypoint 是 python /home/ray/samples/sample_code.py,而 sample_code.py 是存储在挂载到 RayCluster head Pod 的 Kubernetes ConfigMap 中的 Python 脚本。由于 shutdownAfterJobFinishes 的默认值为 false,因此 KubeRay operator 在 Ray 作业完成后不会删除 RayCluster 或 submitter。
步骤 5:检查 Ray 作业的输出#
kubectl logs -l=job-name=rayjob-sample
# [Example output]
# 2025-06-25 09:22:27,963 INFO worker.py:1654 -- Connecting to existing Ray cluster at address: 10.244.0.6:6379...
# 2025-06-25 09:22:27,977 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-06-25 09:22:31,719 SUCC cli.py:63 -- -----------------------------------
# 2025-06-25 09:22:31,719 SUCC cli.py:64 -- Job 'rayjob-sample-zdxm6' succeeded
# 2025-06-25 09:22:31,719 SUCC cli.py:65 -- -----------------------------------
用于 entrypoint 的 Python 脚本 sample_code.py 是一个简单的 Ray 脚本,它执行计数器递增函数 5 次。
步骤 6:删除 RayJob#
kubectl delete -f https://raw.githubusercontent.com/ray-project/kuberay/v1.5.1/ray-operator/config/samples/ray-job.sample.yaml
步骤 7:创建设置为 shutdownAfterJobFinishes 为 true 的 RayJob#
kubectl apply -f https://raw.githubusercontent.com/ray-project/kuberay/v1.5.1/ray-operator/config/samples/ray-job.shutdown.yaml
ray-job.shutdown.yaml 定义了一个 RayJob 自定义资源,其中 shutdownAfterJobFinishes: true 和 ttlSecondsAfterFinished: 10。因此,KubeRay operator 在 Ray 作业完成后 10 秒后删除 RayCluster。请注意,submitter Job 不会被删除,因为它包含 Ray 作业日志,并且在完成后不使用任何集群资源。此外,由于 submitter Job 的所有者引用指向 RayJob,因此 RayJob 在最终被删除时也会清理 submitter Job。
步骤 8:检查 RayJob 状态#
# Wait until `jobStatus` is `SUCCEEDED` and `jobDeploymentStatus` is `Complete`.
kubectl get rayjobs.ray.io rayjob-sample-shutdown -o jsonpath='{.status.jobDeploymentStatus}'
kubectl get rayjobs.ray.io rayjob-sample-shutdown -o jsonpath='{.status.jobStatus}'
步骤 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
步骤 10:清理#
# Step 10.1: Delete the RayJob
kubectl delete -f https://raw.githubusercontent.com/ray-project/kuberay/v1.5.1/ray-operator/config/samples/ray-job.shutdown.yaml
# Step 10.2: Delete the KubeRay operator
helm uninstall kuberay-operator
# Step 10.3: Delete the Kubernetes cluster
kind delete cluster