Kuberay
插件简介
Kuberay是一个Kubernetes原生插件,用于在Kubernetes集群(包括CCE Standard/Turbo集群)上管理和运行Ray分布式计算框架。Ray是一个高性能的分布式计算库,常用于机器学习、强化学习和数据处理等场景。Kuberay的目标是将Ray与Kubernetes深度集成,使得用户可以轻松地在Kubernetes上部署、管理和扩展Ray Cluster。
Kuberay是一个Kubernetes Operator,它通过自定义资源定义(CRD)管理Ray Cluster的生命周期。它提供了以下核心功能:
- Ray Cluster的部署:通过声明式的方式定义Ray Cluster的配置,Kuberay会自动创建和管理Ray的Head节点和Worker节点。
- 自动扩缩容:根据工作负载的需求,动态调整Ray Cluster的Worker Pod数量。
- 资源管理:与Kubernetes的资源管理机制(如 CPU、内存、GPU 等)无缝集成。
- 故障恢复:自动监控Ray Cluster的健康状态,并在节点故障时进行恢复。
- 日志和监控:集成Kubernetes的日志和监控工具,方便用户调试和优化Ray应用。
约束限制
- CCE集群(Standard/Turbo)版本在v1.27及以上。
- 该特性当前正处于上线阶段,已发布区域请以控制台实际为准。
计费说明
如果您需要访问Ray Dashboard,则需要为集群中任一节点绑定EIP。其中,EIP需要涉及一定费用,具体请参见EIP价格计算器。
安装插件
- 登录CCE控制台,单击集群名称进入集群。
- 单击左侧导航栏的“插件中心”,在右侧找到Kuberay插件,单击“安装”。
- 在安装插件页面,进行“规格配置”。您可以根据需求设置CPU配额和内存配额。
- CPU配额:CPU资源单位为核,可以使用带单位后缀(m)的整数表达,例如100m。
表1 CPU配额说明 参数
示例
说明
CPU申请
100m
表示容器的最小CPU需求。
CPU限制
500m
表示容器能使用的CPU最大值。当CPU使用率超出设置的CPU限制值时,该实例可能会被重启进而影响插件的正常使用。
- 内存配额:内存资源默认单位为字节,可以使用带单位后缀(Mi)的整数来表达,例如100Mi。管理500个Ray Pod需要大约500MB内存,您可以根据内存的使用情况进行调整。
表2 内存配额说明 参数
示例
说明
内存申请
100Mi
表示容器的最小内存需求。
内存限制
500Mi
表示容器能使用的内存最大值。当内存使用率超出设置的内存限制值时,该实例可能会被重启进而影响插件的正常使用。
- CPU配额:CPU资源单位为核,可以使用带单位后缀(m)的整数表达,例如100m。
- 进行“参数配置”,具体请参见表3 参数配置说明。
表3 参数配置说明 参数
示例
说明
插件安装的命名空间
default
表示安装Kuberay插件的命名空间,支持自定义,默认为default。
批调度器
不使用
是否使用外部调度器对Ray Job进行批量调度,默认为不使用。
- 不使用:表示不使用外部调度器对Ray Job进行批量调度。
- Volcano调度器:使用Volcano调度器对Ray Job进行批量调度。使用Volcano作为批调度器时,若无自建Volcano,建议安装Volcano调度器插件,具体请参见Volcano调度器。
服务端口
8080
表示Kuberay对外提供服务的端口,默认为8080。
- 单击“安装”。当该插件状态为“运行中”时,则说明插件安装成功。
组件说明
容器组件 |
说明 |
资源类型 |
---|---|---|
kuberay-operator |
进行Ray的部署和生命周期的管理。 |
Deployment |
使用示例
本示例基于Kuberay插件,为您提供两种提交Ray作业的方式,具体工作流程和应用场景请参见表5。更多Kuberay的用法,可参考官网文档。
提交方式 |
说明 |
---|---|
通过Ray Cluster提交作业 |
您需要首先创建一个Ray Cluster,再登录该Ray Cluster的Head节点的Pod中,提交相关作业。Head节点会将作业自动分发给Worker节点,由Worker节点执行对应作业。 |
通过Ray Job提交作业 |
您可以通过Ray Job将Python脚本直接挂载至Ray Cluster的Head节点,Head节点将作业自动分发给Worker节点完成作业,本示例中的创建Ray Job的Yaml文件大致含义如下,您可以根据实际情况进行调整。
|
- 在已有的ECS中安装kubectl,并使用kubectl连接集群,具体操作请参见通过kubectl连接集群。
- 执行以下命令,创建YAML文件my-rayjob.yaml,用于配置Ray Job,文件名称可自定义。
vim my-rayjob.yaml
在使用Ray官方镜像时,可能由于网络原因拉取失败。建议将该镜像提前上传至SWR镜像仓库,并将文件内容中的镜像地址替换为SWR中的镜像地址。关于镜像上传SWR镜像仓库的详细步骤,请参见使用docker命令将镜像迁移至SWR。
文件内容如下:
apiVersion: ray.io/v1 kind: RayJob # 资源类型为Ray Job metadata: name: my-rayjob spec: # 定义Ray Job的规格,包括任务入口点、运行时环境和Ray Cluster配置 entrypoint: python /home/ray/samples/sample_code.py # 指定任务的入口点命令,这里是运行一个Python脚本 runtimeEnvYAML: | env_vars: # 定义任务运行时环境变量 counter_name: "test_counter" rayClusterSpec: # 用于定义Ray Cluster配置 headGroupSpec: # 定义Ray Cluster的Head节点配置 rayStartParams: {} template: spec: containers: - name: ray-head image: rayproject/ray:2.41.0 ports: - containerPort: 6379 name: gcs-server - containerPort: 8265 # Ray dashboard name: dashboard - containerPort: 10001 name: client resources: limits: cpu: "1" requests: cpu: "200m" volumeMounts: - mountPath: /home/ray/samples name: code-sample volumes: - name: code-sample configMap: name: ray-job-code-sample items: - key: sample_code.py path: sample_code.py workerGroupSpecs: # 定义 Ray Cluster的Worker节点配置 - replicas: 1 minReplicas: 1 maxReplicas: 5 groupName: small-group rayStartParams: {} template: spec: containers: - name: ray-worker image: rayproject/ray:2.41.0 resources: limits: cpu: "1" requests: cpu: "200m" --- # 定义具体工作,里面包含一个Python脚本sample_code.py,该脚本实现了一个简单的分布式计数器 apiVersion: v1 kind: ConfigMap metadata: name: ray-job-code-sample data: sample_code.py: | import ray import os ray.init() @ray.remote class Counter: def __init__(self): # Used to verify runtimeEnv self.name = os.getenv("counter_name") assert self.name == "test_counter" self.counter = 0 def inc(self): self.counter += 1 def get_counter(self): return "{} got {}".format(self.name, self.counter) counter = Counter.remote() for _ in range(1000): ray.get(counter.inc.remote()) print(ray.get(counter.get_counter.remote()))
- 执行以下命令,系统将会创建Ray Job和ConfigMap(用于存放作业代码) 资源。
kubectl create -f my-rayjob.yaml
回显如下,表示资源创建成功。
rayjob.ray.io/my-rayjob created configmap/ray-job-code-sample created
- 依次执行以下命令,检查Ray Job的部署情况。
- 执行以下命令,检查Ray Cluster是否创建成功。
kubectl get pod
回显结果如下,则说明创建成功。其中,“my-rayjob-raycluster-4464z-head-hb5qx”表示Head Pod,“my-rayjob-raycluster-4464z-small-group-worker-csqb2”表示Worker Pod,“my-rayjob-x2tv6”用来查看作业的执行情况。如果“my-rayjob-x2tv6”的STATUS为Completed,则说明作业已完成。
NAME READY STATUS RESTARTS AGE my-rayjob-raycluster-4464z-head-hb5qx 1/1 Running 0 24s my-rayjob-raycluster-4464z-small-group-worker-csqb2 1/1 Running 0 24s my-rayjob-x2tv6 1/1 Running 0 4s
- 查看Ray Job的状态。
kubectl get rayjob
回显结果如下,则说明作业仍在进行中。如果JOB STATUS为SUCCEEDED,则说明作业已完成。
NAME JOB STATUS DEPLOYMENT STATUS RAY CLUSTER NAME START TIME END TIME AGE my-rayjob RUNNING Running my-rayjob-raycluster-4464z 2025-02-10T07:16:26Z 28
- 执行以下命令,查看作业的具体执行情况。
kubectl logs my-rayjob-x2tv6
回显结果如下:
2025-02-21 03:32:23,631 INFO cli.py:36 -- Job submission server address: http://my-rayjob-raycluster-4464z-head-svc.default.svc.cluster.local:8265 2025-02-21 03:32:24,142 SUCC cli.py:60 -- -------------------------------------------- 2025-02-21 03:32:24,143 SUCC cli.py:61 -- Job 'my-rayjob-x2tv6' submitted successfully 2025-02-21 03:32:24,143 SUCC cli.py:62 -- -------------------------------------------- 2025-02-21 03:32:24,143 INFO cli.py:286 -- Next steps 2025-02-21 03:32:24,143 INFO cli.py:287 -- Query the logs of the job: 2025-02-21 03:32:24,143 INFO cli.py:289 -- ray job logs my-rayjob-x2tv6 2025-02-21 03:32:24,143 INFO cli.py:291 -- Query the status of the job: 2025-02-21 03:32:24,143 INFO cli.py:293 -- ray job status my-rayjob-x2tv6 2025-02-21 03:32:24,143 INFO cli.py:295 -- Request the job to be stopped: 2025-02-21 03:32:24,143 INFO cli.py:297 -- ray job stop my-rayjob-x2tv6 2025-02-21 03:32:24,147 INFO cli.py:304 -- Tailing logs until the job exits (disable with --no-wait): 2025-02-21 03:32:25,011 INFO worker.py:1429 -- Using address 172.20.0.10:6379 set in the environment variable RAY_ADDRESS 2025-02-21 03:32:25,012 INFO worker.py:1564 -- Connecting to existing Ray cluster at address: 172.20.0.10:6379... 2025-02-21 03:32:25,017 INFO worker.py:1740 -- Connected to Ray cluster. View the dashboard at 172.20.0.10:8265 test_counter got 1 test_counter got 2 test_counter got 3 test_counter got 4 ...
- 执行以下命令,检查Ray Cluster是否创建成功。
- 您可以在Ray Dashboard中实时监控和管理Ray Cluster的状态、资源使用情况和作业执行情况。
- 获取Ray Cluster中Head Pod的标签,使2中新建的Service能够识别并绑定Pod。请将“my-rayjob-raycluster-4464z-head-hb5qx”替换为您的Head Pod名称。
kubectl describe pod my-rayjob-raycluster-4464z-head-hb5qx
回显结果如下,建议使用“my-rayjob-raycluster-4464z-head”作为标签。
... Labels: app.kubernetes.io/created-by=kuberay-operator app.kubernetes.io/name=kuberay ray.io/cluster=my-rayjob-raycluster-4464z ray.io/group=headgroup ray.io/identifier=my-rayjob-raycluster-4464z-head ray.io/is-ray-node=yes ray.io/node-type=head ...
- 执行以下命令,创建YAML文件ray-dashboard.yaml,用于配置NodePort的Service,文件名称可自定义。该Service主要用于对外暴露服务,进而可以从浏览器直接访问Ray Dashboard。
vim ray-dashboard.yaml
文件内容如下:
apiVersion: v1 kind: Service metadata: name: ray-dashboard labels: ray.io/identifier: my-rayjob-raycluster-4464z-head namespace: default spec: ports: - name: cce-service-0 port: 8265 # 访问Service的端口,设置为8265 protocol: TCP # 访问Service的协议,支持TCP和UDP targetPort: 8265 # Service访问目标容器的端口,此端口与容器中运行的应用强相关,必须为8265 selector: # 标签选择器 ray.io/identifier: my-rayjob-raycluster-4464z-head externalTrafficPolicy: Cluster type: NodePort # Service的类型,NodePort表示在通过节点端口访问
- 执行以下命令,创建Service。
kubectl create -f ray-dashboard.yaml
回显结果如下,则说明Service创建成功。
service/ray-dashboard created
- 执行以下命令,查看该Service的节点端口信息。
kubectl get services
回显结果如下,其中32638即为节点端口。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ray-dashboard NodePort 10.247.147.102 <none> 8265:32638/TCP 8s
- 在浏览器中输入“http://<集群任一节点的EIP>:32638”,访问Ray Dashboard页面。请确保集群中存在节点已绑定EIP,您可以在CCE控制台单击对应集群名称,在“节点管理 > 节点页面”,单击对应节点名称进入ECS页面绑定EIP,具体可参考绑定弹性公网IP。
如果访问界面类似图3 Ray Dashboard,则说明访问成功。您可以根据Ray Dashboard实时监控和管理Ray Cluster的状态、资源使用情况和作业执行情况。例如,您可以在Recent jobs模块查看作业执行状况。
- 获取Ray Cluster中Head Pod的标签,使2中新建的Service能够识别并绑定Pod。请将“my-rayjob-raycluster-4464z-head-hb5qx”替换为您的Head Pod名称。
- 依次执行以下步骤,删除相关资源。
- 删除Ray Job相关资源。
kubectl delete -f my-rayjob.yaml
回显结果如下:
rayjob.ray.io "my-rayjob" deleted configmap "ray-job-code-sample" deleted
- 删除Service资源。
kubectl delete -f ray-dashboard.yaml
回显结果如下:
service "ray-dashboard" deleted
- 删除Ray Job相关资源。
常见问题
在CCE中卸载Kuberay插件时,Ray Cluster、Ray Job和Ray Service的CRD会残留在集群中。您可以参考以下步骤进行处理:
- 在已连接集群的ECS中,执行以下命令,查找与Ray相关的CRD。
kubectl get crd | grep ray
回显结果如下,则说明存在两个相关的CRD。
rayclusters.ray.io 2025-02-01T12:00:00Z rayjobs.ray.io 2025-02-01T12:00:00Z rayservices.ray.io 2025-02-01T12:00:00Z
- 执行以下命令,依次删除相关资源。命令中的“rayclusters.ray.io”、“rayjobs.ray.io”和“rayservices.ray.io”可替换为您残留的CRD名称。
kubectl delete crd rayclusters.ray.io kubectl delete crd rayjobs.ray.io kubectl delete crd rayservices.ray.io
回显结果如下,则说明资源已删除。
customresourcedefinition.apiextensions.k8s.io "rayclusters.ray.io" deleted customresourcedefinition.apiextensions.k8s.io "rayjobs.ray.io" deleted customresourcedefinition.apiextensions.k8s.io "rayservices.ray.io" deleted