4. Kubernetes基础回顾与KubeRay依赖

KubeRay 并不是一个脱离 Kubernetes 独立运行的调度系统,它本质上是一组自定义资源(CRD)加控制器(Controller)。RayCluster、RayJob、RayService 这些对象最终都要落到 Pod、Service、ConfigMap、Secret、PVC、RBAC 等原生对象上。理解这些原生对象在 KubeRay 部署中的实际作用,是排查“RayCluster 一直 Pending”“Head 起来了 Worker 连不上”“Dashboard 打不开”这类问题的前提。本节按对象逐个说明它们在 KubeRay 中的落点,并给出可观察的判断依据。

Pod:真正承载 Ray 进程的最小单元

一个 RayCluster 创建后,控制器会为 Head 节点生成 1 个 Pod,为每个 Worker Group 生成对应副本数的 Pod。这些 Pod 的容器里运行的是 ray start 命令,Head 容器通常带 --head --port=6379 --dashboard-host=0.0.0.0,Worker 容器带 --address=raycluster-xxx-head-svc:6379。因此 Pod 是 Ray 进程的实际宿主,Pod 的调度结果直接决定 Ray 集群能否成形。

排查时先看 Pod 状态与所在节点:

kubectl get pods -l ray.io/cluster=mycluster -o wide
kubectl describe pod mycluster-head-xxxxx | grep -A5 Events

如果 Head Pod 处于 Pending,常见原因是资源不足或节点选择器不匹配;如果 Running 但 Ready 为 0/1,则要看容器日志里 ray start 是否报端口占用或 GCS 启动失败。KubeRay 默认给 Head 容器暴露 6379(GCS)、8265(Dashboard)、10001(Client Server)等端口,这些端口在 Pod 内必须真实监听,否则 Service 转发过去也是拒绝连接。

Deployment 与 StatefulSet:KubeRay 自身与有状态组件的载体

KubeRay Operator 本身通常以 Deployment 形式部署在 kuberay-operator 命名空间,副本数 1 即可,它负责监听 RayCluster 等 CR 并调谐。而 Ray 集群的 Head/Worker 并不由 Deployment 管理,而是由 KubeRay 控制器直接创建 Pod,这是容易混淆的一点:RayCluster 不是 Deployment 的封装。如果集群里还部署了 Ray Serve 依赖的 Redis、或自建的对象存储,这些有状态组件才可能用 StatefulSet。区分清楚“谁管理谁”,才能知道扩缩容时该改 RayCluster 的 workerGroupSpecs.replicas,而不是去改某个 Deployment。

Service:Head 的稳定入口与 Worker 的发现地址

KubeRay 会为 Head 自动创建两个 Service:一个是普通 ClusterIP 的 *-head-svc,供 Worker 通过 DNS 连接 GCS;另一个是 *-head-svc 对应的 Dashboard/Client 访问入口。Worker 启动命令里的地址就是 Head Service 名,因此 Service 的 Endpoints 必须指向 Ready 的 Head Pod。若 Worker 日志出现 Connection refused 或 Failed to connect to GCS,先确认:

kubectl get svc mycluster-head-svc
kubectl get endpoints mycluster-head-svc

Endpoints 为空说明 Head Pod 未 Ready,Service 选不到后端,此时问题在 Pod 而不在 Service。要从集群外访问 Dashboard,可临时用 kubectl port-forward svc/mycluster-head-svc 8265:8265,生产环境则通过 Ingress 或 LoadBalancer 暴露,并配合认证。

ConfigMap 与 Secret:把 Ray 配置和凭据注入容器

Ray 集群常需要自定义 ray start 参数、环境变量、以及访问对象存储的密钥。KubeRay 支持在 RayCluster 的 headGroupSpec.template.spec 中像普通 Pod 一样挂载 ConfigMap 和 Secret。典型做法是把 RAY_LOG_TO_STDERR、RAY_object_store_memory 等放进 ConfigMap,把 S3/MinIO 的 AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY 放进 Secret,再通过 envFrom 注入。这样 Ray 任务代码里用 boto3 或 ray.data 读写对象存储时无需硬编码凭据。

Secret 默认是 base64 编码而非加密,生产环境应开启 etcd 加密或使用外部密钥管理,并限制 RBAC 读取权限。

PVC:让 Ray 的临时数据与模型缓存可持久

Ray 的 object store 默认在 Pod 本地磁盘,Pod 重建即丢失,这对无状态计算没问题。但当需要缓存大模型权重、复用数据集、或让 Head 保存 GCS 元数据快照时,就要挂 PVC。KubeRay 允许在 Pod 模板里声明 volumes 引用 PVC,并挂到 /tmp/ray 或自定义路径。注意:多个 Worker 同时挂同一个 ReadWriteMany PVC 才可共享;若 StorageClass 只支持 ReadWriteOnce,则每个 Pod 各挂各的,不能当作共享存储用。判断依据是 kubectl get pvc 的 STATUS 是否为 Bound,以及 Pod 事件里有没有 FailedMount。

RBAC:控制器与 Ray 任务操作集群的权限边界

KubeRay Operator 需要 ServiceAccount、ClusterRole、ClusterRoleBinding 才能创建和删除 Pod、Service、ConfigMap 等资源。如果安装时 RBAC 不完整,Operator 日志会出现 forbidden,表现为 RayCluster 创建后长时间没有 Pod 生成。此外,Ray 任务本身若要通过 ray.k8s 或 Kubernetes API 动态起 Pod,也需要给运行 Ray 的 ServiceAccount 绑定相应 Role。最小权限原则下,Operator 用 ClusterRole,业务 Ray 集群用命名空间级 Role 即可。

KubeRay 部署中 Kubernetes 原生对象的依赖关系 KubeRay Operator Deployment + SA 监听 RayCluster CR RBAC ClusterRole / Binding 授权创建 Pod/Service RayCluster CR headGroupSpec workerGroupSpecs Head Pod ray start --head GCS:6379 Dashboard:8265 Worker Pods ×N ray start --address 连接 Head GCS Head Service ClusterIP + DNS Endpoints → Head Pod ConfigMap / Secret 环境变量 / 凭据 envFrom 注入 PVC 模型缓存 / 数据集 挂载 /tmp/ray Operator 依据 RBAC 权限调谐 CR,生成 Pod/Service;配置与存储通过 Pod 模板注入

把对象串起来看一次部署

假设要部署一个 1 Head + 2 Worker 的 RayCluster,并让任务读取 MinIO 数据。实际操作顺序是:先确认 Operator 的 RBAC 已就绪(kubectl get clusterrole kuberay-operator),再创建 Secret 保存 MinIO 凭据,创建 ConfigMap 保存 Ray 环境变量,然后提交 RayCluster YAML,其中 workerGroupSpecs[0].replicas=2,Pod 模板里 envFrom 引用上述 ConfigMap/Secret,volumes 引用 PVC。提交后观察:

kubectl get raycluster mycluster
kubectl get pods -l ray.io/cluster=mycluster
kubectl get svc mycluster-head-svc
kubectl get endpoints mycluster-head-svc

判断成功的依据是:RayCluster 状态为 ready,Head 与 2 个 Worker Pod 均 Running 且 Ready,Head Service 的 Endpoints 至少包含 Head Pod IP。此时用 kubectl exec 进入 Head 执行 ray status,应看到 1 个 head 节点和 2 个 worker 节点,总 CPU/内存与 Worker 副本数匹配。若 Worker 数少于预期,检查 replicas 是否被 HPA 或手动改过,以及节点资源是否足够调度。

常见误区:把 RayCluster 当成 Deployment 去 kubectl scale。扩缩容应改 RayCluster 的 workerGroupSpecs.replicas 并重新 apply,由 KubeRay 控制器负责增删 Pod。

总结这些对象的职责边界:Pod 承载 Ray 进程,Service 提供 Head 的稳定发现入口,ConfigMap/Secret 注入配置与凭据,PVC 提供持久化存储,RBAC 决定 Operator 和任务能操作哪些资源,Deployment 只用于 Operator 自身等无状态控制面。把每个对象的“谁创建、谁消费、失败时看什么”对应清楚,KubeRay 的部署与排障就有了稳定的抓手。