KubeRay RayJob 快速上手:在 Kubernetes 上按需拉起 Ray 集群并自动提交与回收 Ray 作业
2026/9/19 10:03:48 网站建设 项目流程

KubeRay RayJob 快速上手:在 Kubernetes 上按需拉起 Ray 集群并自动提交与回收 Ray 作业

【免费下载链接】rayRay is an AI compute engine. Ray consists of a core distributed runtime and a set of AI Libraries for accelerating ML workloads.项目地址: https://gitcode.com/gh_mirrors/ra/ray

本指南以当前 Ray 仓库中 rayjob-quick-start.md 为核心,系统讲解 KubeRay 的 RayJob 自定义资源:它如何把「RayCluster 集群生命周期」与「Ray 作业提交与执行」两个环节编排到一起,在作业就绪时自动提交、在作业完成后按策略自动回收集群资源。读完本文,你将掌握 RayJob 全部核心配置字段(提交模式、资源清理、删除策略等),并能用 10 个命令在 Kind 集群上完整跑通一个 RayJob 从创建、验证到清理的全流程。

前置条件与版本兼容性

使用 RayJob 需要满足 KubeRay 与 Ray 的版本搭配要求:

KubeRay 版本最低 Ray 版本说明
v0.6.0 / v1.0.0Ray 1.10+支持基础 RayJob 能力
v1.1.1 及以上(强烈推荐)Ray 2.8.0+推荐使用,功能更完整

部分高级特性还有额外版本门槛,例如SidecarSubmitterRestart特性门控要求KubeRay v1.7+、Ray v2.54.0+、Kubernetes v1.35+(详见 RayJob SidecarSubmitterRestart 指南)。本文的实操示例基于 KubeRay v1.7.0。

什么是 RayJob:一次理解三个易混淆的概念

KubeRay 的 RayJob 是一个 Kubernetes 自定义资源(CRD),它同时管理两个方面:

  • RayCluster:RayCluster 自定义资源管理一个 Ray 集群内的所有 Pod,包括一个 head Pod 和若干 worker Pod;
  • Job(submitter):一个 Kubernetes Job 负责执行ray job submit,把 Ray 作业提交到上面创建的 RayCluster 上。

理解以下三个概念的差异有助于阅读后文:

  • RayJob:由 KubeRay 提供的 Kubernetes 自定义资源定义,是本文的主角;
  • Ray job:一个打包好的 Ray 应用程序,可以运行在远端 Ray 集群上(对应 Ray 的 Jobs 概念);
  • Submitter:一个 Kubernetes Job,其入口即ray job submit命令,负责把 Ray job 提交进 RayCluster。

RayJob 能带来什么

借助 RayJob,KubeRay 会自动创建 RayCluster,并在集群就绪后自动提交 Ray 作业;同时你可以配置 RayJob,让它在 Ray 作业结束后自动删除 RayCluster。这带来两个典型价值:

  • 按需调度:提交任务时集群才创建,配合 Kueue 等批调度器可实现排队与抢占;
  • 资源回收:作业跑完自动销毁集群,避免空闲集群持续占用节点资源。

RayJob 配置详解

RayJob 的spec可以拆成四类配置:RayCluster 配置、Ray job 配置、提交配置、自动资源清理配置,外加少量其它字段。

RayCluster 配置

  • rayClusterSpec:定义用于运行 Ray 作业的RayCluster自定义资源。该字段与独立 RayCluster 资源的spec结构一致,包括rayVersionheadGroupSpecworkerGroupSpecs等。当前仓库中的 ray-cluster.complete.yaml 给出了一个字段最完整的 RayCluster 示例:head 组通过rayStartParams配置ray start参数(portdashboard-hostblocknum-cpusresources等),并通过template.spec.containers定义 head 容器镜像与资源;worker 组通过workerGroupSpecs列表定义,每组包含replicasgroupNamerayStartParams、Pod 模板等。RayJob 的rayClusterSpec结构与之完全一致。
  • clusterSelector:不新建集群,而是复用已存在的 RayCluster自定义资源来运行 Ray 作业(示例可参考 KubeRay 仓库ray-operator/config/samples/ray-job.use-existing-raycluster.yaml)。

Ray job 配置

  • entrypoint:submitter 实际执行的命令形如ray job submit --address ... --submission-id ... -- $entrypointentrypoint即你要运行的作业入口(例如python /home/ray/samples/sample_code.py)。

  • runtimeEnvYAML(可选,KubeRay v1.0.0 新增):描述 Ray 作业运行所需的运行时环境(依赖文件、pip 包、环境变量等),以多行 YAML 字符串形式提供。示例:

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

    更完整的 runtimeEnv 字段说明可参考 Ray 的 Runtime Environments 文档。

  • jobId(可选):指定 Ray 作业的 submission ID;未提供时由 KubeRay 自动生成。该 ID 对应ray job submit --submission-id的语义。

  • metadata(可选):对应ray job submit--metadata-json选项,用于给作业附加元数据。

  • entrypointNumCpus/entrypointNumGpus/entrypointResources(可选):为作业入口分配 CPU / GPU / 自定义资源配额。

  • backoffLimit(可选,v1.2.0 新增):RayJob 失败前允许重试的次数,每次重试都会新建一个 RayCluster,默认值为 0。注意它与 submitter 的backoffLimit(默认 2)含义不同。

提交配置

  • submissionMode(可选):指定 RayJob 向 RayCluster 提交作业的方式,默认值为K8sJobMode,共四种取值:

    取值机制备注
    K8sJobMode(默认)KubeRay operator 创建一个 submitter Kubernetes Job 来提交 Ray 作业与 Ray 镜像隔离,作业日志在 submitter 中
    HTTPModeKubeRay operator 直接向 RayCluster 发 HTTP 请求创建 Ray 作业无需额外提交容器
    InteractiveModeKubeRay operator 等待用户手动向 RayCluster 提交作业目前为 alpha,KubeRay kubectl 插件 依赖此模式
    SidecarModeKubeRay operator 在 Ray head Pod 内注入一个 sidecar 容器提交作业不支持clusterSelectorsubmitterPodTemplate,要求 head Pod 的restartPolicyNever

    SidecarMode的额外说明:启用SidecarSubmitterRestart特性门控(需 KubeRay v1.7+、Ray v2.54.0+、Kubernetes v1.35+)后,可用submitterConfig.backoffLimit限制 submitter sidecar 的重启次数。该模式下的提交容器与 head 容器同 Pod 通信(localhost),日志可直接输出到 STDOUT/STDERR,但副作用是提交者的生命周期与 head Pod 强耦合;当SidecarSubmitterRestart启用时,提交容器在容器级别使用OnFailure重启策略,重启后会先检查 Ray 作业状态:作业仍在运行则重新挂接日志流而不是重新提交。完整机制与版本偏差注意点参见 RayJob SidecarSubmitterRestart 指南。

  • submitterPodTemplate(可选):定义 submitter Kubernetes Job 的 Pod 模板,仅在submissionModeK8sJobMode时生效。KubeRay operator 会向 submitter Pod 注入两个环境变量:

    • RAY_DASHBOARD_ADDRESS:值为$HEAD_SERVICE:$DASHBOARD_PORT,即 head 服务地址与 dashboard 端口;
    • RAY_JOB_SUBMISSION_ID:值为RayJob.Status.JobId

    典型的提交命令示例:ray job submit --address=http://$RAY_DASHBOARD_ADDRESS --submission-id=$RAY_JOB_SUBMISSION_ID ...。更完整的示例可参考 KubeRay 仓库ray-operator/config/samples/ray-job.sample.yaml

  • submitterConfig(可选):submitter 的附加配置,K8sJobMode下始终生效;SidecarMode在启用SidecarSubmitterRestart时内部也会遵守backoffLimit,但该字段目前无法通过 RayJob 资源为SidecarMode设置(KubeRay 的校验 webhook 会拒绝)。

    • backoffLimit(可选,v1.2.0 新增):submitter 失败前的重试次数,默认值为 2。
  • SidecarSubmitterRestart(v1.7 中为 alpha,默认关闭):允许 submitter 容器在瞬时故障时就地重启,独立于 head Pod 的restartPolicy: Never。要求 Kubernetes v1.35+ 与 Ray v2.54.0+,完整的重启/重新挂接行为与版本偏差说明见上文提到的 Sidecar 指南。

自动资源清理配置

  • preRunningDeadlineSeconds(可选):若 RayJob 未能在该秒数内将JobDeploymentStatus转为Running,KubeRay operator 会将其转为Failed,原因为PreRunningDeadlineExceeded。默认值 0(不强制预运行期限)。
  • shutdownAfterJobFinishes(可选):Ray 作业结束后是否回收 RayCluster,默认值为false
  • ttlSecondsAfterFinished(可选):仅在shutdownAfterJobFinishes为 true 时生效。Ray 作业结束ttlSecondsAfterFinished秒后,operator 删除 RayCluster 与 submitter。默认值 0(立即删除)。
  • activeDeadlineSeconds(可选):若 RayJob 未能在该秒数内将JobDeploymentStatus转为CompleteFailed,operator 将其转为Failed,原因为DeadlineExceeded
  • DELETE_RAYJOB_CR_AFTER_JOB_FINISHES(可选,v1.2.0 新增):注意这是设置给 KubeRay operator 的环境变量,而非 RayJob 资源字段。若设为 true,且同时设置了shutdownAfterJobFinishes: true,则 RayJob 自定义资源本身也会被删除;KubeRay 会一并删除 RayJob 创建的所有资源(包括 Kubernetes Job)。

其它字段

  • suspend(可选):若为 true,KubeRay 会同时删除 RayCluster 与 submitter。注意 Kueue 也通过修改该字段实现调度策略,如果使用 Kueue 调度 RayJob,请避免手动修改此字段。

  • deletionStrategy(v1.5.1 为 alpha,v1.6.0 为 beta):配置 RayJob 进入终态后的自动清理,需要启用RayJobDeletionPolicy特性门控。支持两种互斥风格:

    • 规则式(Rules-based,推荐):通过deletionRules定义由特定条件触发的删除动作列表。每条规则包含:

      • policy:删除动作——DeleteCluster(删除整个 RayCluster 及其 Pod)、DeleteWorkers(只删除 worker Pod)、DeleteSelf(删除 RayJob 及所有关联资源)、DeleteNone(不删除);
      • condition:触发条件——基于jobStatusSUCCEEDEDFAILED)与可选的ttlSeconds延迟。

      这种方式支持灵活的多阶段清理,例如「作业成功时立即删除 worker,300 秒后再删除整个集群」。规则式与shutdownAfterJobFinishes及全局ttlSecondsAfterFinished不兼容,应改用规则内的condition.ttlSeconds。示例见 KubeRay 仓库ray-operator/config/samples/ray-job.deletion-rules.yaml

    • 传统式(Legacy,已废弃):同时定义onSuccessonFailure策略。该方式将在 v1.6.0 中移除,强烈建议迁移到deletionRules。传统式可与shutdownAfterJobFinishes及全局ttlSecondsAfterFinished组合使用。

    完整的 API 规范请参考 KubeRay CRD API reference。

实战:10 步在 Kind 上跑通一个 RayJob

以下步骤完整复现 RayJob 从创建到清理的全过程。

Step 1:用 Kind 创建 Kubernetes 集群

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

Step 2:安装 KubeRay operator

按照 KubeRay Operator Installation 安装最新稳定版 operator。推荐用 Helm 方式(v1.7.0):

helm repo add kuberay https://ray-project.github.io/kuberay-helm/ helm repo update kubectl create namespace ray-system helm install kuberay-operator kuberay/kuberay-operator --version 1.7.0 -n ray-system

KubeRay 也支持 Kustomize 安装:kubectl create -k "github.com/ray-project/kuberay/ray-operator/config/default?ref=v1.7.0" -n ray-system。安装后用kubectl get pods -n ray-system确认 operator Pod 处于 Running 状态。

Step 3:安装 RayJob 示例

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

该 YAML 位于 KubeRay 仓库ray-operator/config/samples/ray-job.sample.yaml,也可先下载到本地再kubectl apply -f

Step 4:验证 Kubernetes 集群状态

# Step 4.1:列出 default 命名空间下所有 RayJob 自定义资源 kubectl get rayjob # [示例输出] # 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:列出所有 RayCluster 自定义资源 kubectl get raycluster # [示例输出] # NAME DESIRED WORKERS AVAILABLE WORKERS CPUS MEMORY GPUS STATUS AGE # rayjob-sample-qnftt 1 1 400m 0 0 ready 7m48s # Step 4.3:列出 default 命名空间下所有 Pod # 由 Kubernetes Job 创建的 Pod 在 Job 结束后会被终止 kubectl get pods # [示例输出] # 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:检查 RayJob 状态 # 作业结束后,RayJob 的 jobStatus 字段会被更新为 SUCCEEDED,jobDeploymentStatus 应为 Complete 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 自定义资源,同时创建一个 submitter Kubernetes Job 向集群提交 Ray 作业。示例中entrypointpython /home/ray/samples/sample_code.py,该脚本存放在挂载到 head Pod 的 Kubernetes ConfigMap 中。由于shutdownAfterJobFinishes默认值为 false,作业结束后 operator不会删除 RayCluster 与 submitter。

Step 5:查看 Ray 作业输出

kubectl logs -l=job-name=rayjob-sample # [示例输出] # 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 -- -----------------------------------

日志显示作业先连接已有 Ray 集群(head 地址为10.244.0.6:6379,dashboard 为8265),随后执行计数器递增函数 5 次,最终ray jobCLI 报告作业成功。entrypoint使用的sample_code.py就是一个执行 5 次计数器递增函数的简单 Ray 脚本。

Step 6:删除 RayJob

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

Step 7:创建启用shutdownAfterJobFinishes的 RayJob

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

ray-job.shutdown.yaml定义的 RayJob 设置了shutdownAfterJobFinishes: truettlSecondsAfterFinished: 10,因此 operator 会在作业结束后10 秒删除 RayCluster。注意 submitter Job 不会被删除——它保存着 Ray 作业日志且完成后不占用集群资源;RayJob 通过 owner reference 关联 submitter,当 RayJob 最终被删除时,submitter 会随之清理。

Step 8:检查 RayJob 状态

# 等待 jobStatus 变为 SUCCEEDED、jobDeploymentStatus 变为 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}'

Step 9:确认 KubeRay operator 已删除 RayCluster

# 列出 default 命名空间下的 RayCluster,与 RayJob rayjob-sample-shutdown 关联的集群应已被删除 kubectl get raycluster

Step 10:清理环境

# Step 10.1:删除 RayJob kubectl delete -f https://raw.githubusercontent.com/ray-project/kuberay/v1.7.0/ray-operator/config/samples/ray-job.shutdown.yaml # Step 10.2:卸载 KubeRay operator helm uninstall kuberay-operator # Step 10.3:删除 Kubernetes 集群 kind delete cluster

状态机与关键实现逻辑小结

从上面的验证命令可以看到,RayJob 生命周期由两个状态字段共同刻画:

  • jobStatus:对应 Ray 作业本身的状态(如SUCCEEDED/FAILED/RUNNING),由提交结果反馈更新;
  • jobDeploymentStatus:对应 RayJob 资源的部署状态(如Running/Complete/Failed),由 operator 依据preRunningDeadlineSecondsactiveDeadlineSeconds、作业终态等条件推进。

理解这一点有助于正确组合配置:例如「作业成功立即删 worker、延迟删集群」的多阶段清理可以通过deletionRules实现;「严格按时回收」则依赖shutdownAfterJobFinishes+ttlSecondsAfterFinished;「杜绝作业跑完集群还挂着」则需要显式把shutdownAfterJobFinishes置为 true,因为其默认值为 false。

下一步学习路径

  • 批处理示例:RayJob Batch Inference Example(文中引用的 Kuberay 批处理推断示例)
  • 与 Kueue 配合:Priority Scheduling with RayJob and Kueue、Gang Scheduling with RayJob and Kueue
  • 集群细节:阅读 ray-cluster.complete.yaml 了解rayClusterSpec可用的完整字段
  • 进阶提交模式:RayJob SidecarSubmitterRestart 指南 与 KubeRay kubectl 插件

【免费下载链接】rayRay is an AI compute engine. Ray consists of a core distributed runtime and a set of AI Libraries for accelerating ML workloads.项目地址: https://gitcode.com/gh_mirrors/ra/ray

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询