使用 ArgoCD 部署 Ray 集群#
本指南提供了使用 ArgoCD 在 Kubernetes 上部署 Ray 集群的分步方法。ArgoCD 是一个声明式的 GitOps 工具,它使您能够通过自动化同步、版本控制和回滚功能来管理 Git 存储库中的 Ray 集群配置。当跨不同环境管理多个 Ray 集群、实施审计跟踪和审批工作流或维护基础架构即代码实践时,此方法特别有价值。对于单集群开发或快速实验等更简单的用例,直接使用 kubectl 或 Helm 部署可能已足够。您可以在 此处 阅读有关 ArgoCD 优势的更多信息。
本示例演示了如何利用 ArgoCD 的 GitOps 功能自动管理集群,来部署 KubeRay Operator 和一个带有三个不同工作节点组的 RayCluster。
先决条件#
在继续本指南之前,请确保您拥有以下条件
具有运行 Ray 工作负载所需资源的 Kubernetes 集群。
已配置
kubectl以访问您的 Kubernetes 集群。(可选)在您的 Kubernetes 集群上已安装 ArgoCD。
(可选)在本地计算机上已安装 ArgoCD CLI(推荐,便于管理应用程序。根据您的环境,可能需要端口转发和登录)。
(可选)可以访问 ArgoCD UI 或 API 服务器。
步骤 1:部署 KubeRay Operator CRD#
首先,部署 KubeRay Operator 所需的自定义资源定义 (CRD)。创建一个名为 ray-operator-crds.yaml 的文件,内容如下:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: ray-operator-crds
namespace: argocd
spec:
project: default
destination:
server: https://kubernetes.default.svc
namespace: ray-cluster
source:
repoURL: https://github.com/ray-project/kuberay
targetRevision: v1.5.1 # update this as necessary
path: helm-chart/kuberay-operator/crds
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- Replace=true
应用 ArgoCD 应用程序
kubectl apply -f ray-operator-crds.yaml
等待 CRD 应用程序同步并变为健康状态。您可以使用以下命令检查状态:
kubectl get application ray-operator-crds -n argocd
最终应显示类似如下内容:
NAME SYNC STATUS HEALTH STATUS
ray-operator-crds Synced Healthy
或者,如果您已安装 ArgoCD CLI,则可以等待应用程序
argocd app wait ray-operator-crds
步骤 2:部署 KubeRay Operator#
在安装完 CRD 后,部署 KubeRay Operator 本身。创建一个名为 ray-operator.yaml 的文件,内容如下:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: ray-operator
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/ray-project/kuberay
targetRevision: v1.5.1 # update this as necessary
path: helm-chart/kuberay-operator
helm:
skipCrds: true # CRDs are already installed in Step 1
destination:
server: https://kubernetes.default.svc
namespace: ray-cluster
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
请注意 Helm 配置中的 skipCrds: true 设置。这是必需的,因为 CRD 已在步骤 1 中单独安装。
应用 ArgoCD 应用程序
kubectl apply -f ray-operator.yaml
等待 Operator 应用程序同步并变为健康状态。您可以使用以下命令检查状态:
kubectl get application ray-operator -n argocd
最终应显示以下输出:
NAME SYNC STATUS HEALTH STATUS
ray-operator Synced Healthy
或者,如果您已安装 ArgoCD CLI
argocd app wait ray-operator
验证 KubeRay Operator Pod 是否正在运行
kubectl get pods -n ray-cluster -l app.kubernetes.io/name=kuberay-operator
步骤 3:部署 RayCluster#
现在,部署一个启用了自动伸缩功能且具有三个不同工作节点组的 RayCluster。创建一个名为 raycluster.yaml 的文件,内容如下:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: raycluster
namespace: argocd
spec:
project: default
destination:
server: https://kubernetes.default.svc
namespace: ray-cluster
ignoreDifferences:
- group: ray.io
kind: RayCluster
name: raycluster-kuberay
namespace: ray-cluster
jqPathExpressions:
- .spec.workerGroupSpecs[].replicas
source:
repoURL: https://ray-project.github.io/kuberay-helm/
chart: ray-cluster
targetRevision: "1.5.1"
helm:
releaseName: raycluster
valuesObject:
image:
repository: docker.io/rayproject/ray
tag: latest
pullPolicy: IfNotPresent
head:
rayStartParams:
num-cpus: "0"
enableInTreeAutoscaling: true
autoscalerOptions:
version: v2
upscalingMode: Default
idleTimeoutSeconds: 600 # 10 minutes
env:
- name: AUTOSCALER_MAX_CONCURRENT_LAUNCHES
value: "100"
worker:
groupName: standard-worker
replicas: 1
minReplicas: 1
maxReplicas: 200
rayStartParams:
resources: '"{\"standard-worker\": 1}"'
resources:
requests:
cpu: "1"
memory: "1G"
additionalWorkerGroups:
additional-worker-group1:
image:
repository: docker.io/rayproject/ray
tag: latest
pullPolicy: IfNotPresent
disabled: false
replicas: 1
minReplicas: 1
maxReplicas: 30
rayStartParams:
resources: '"{\"additional-worker-group1\": 1}"'
resources:
requests:
cpu: "1"
memory: "1G"
additional-worker-group2:
image:
repository: docker.io/rayproject/ray
tag: latest
pullPolicy: IfNotPresent
disabled: false
replicas: 1
minReplicas: 1
maxReplicas: 200
rayStartParams:
resources: '"{\"additional-worker-group2\": 1}"'
resources:
requests:
cpu: "1"
memory: "1G"
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
应用 ArgoCD 应用程序
kubectl apply -f raycluster.yaml
等待 RayCluster 应用程序同步并变为健康状态。您可以使用以下命令检查状态:
kubectl get application raycluster -n argocd
或者,如果您已安装 ArgoCD CLI
argocd app wait raycluster
验证 RayCluster 是否正在运行
kubectl get raycluster -n ray-cluster
这将显示类似如下内容:
NAME DESIRED WORKERS AVAILABLE WORKERS CPUS MEMORY GPUS STATUS AGE
raycluster-kuberay 3 3 ... ... ... ready ...
您应该会看到 head Pod 和 worker Pod
kubectl get pods -n ray-cluster
显示类似如下内容:
NAME READY STATUS RESTARTS AGE
kuberay-operator-6c485bc876-28dnl 1/1 Running 0 11d
raycluster-kuberay-additional-worker-group1-n45rc 1/1 Running 0 5d21h
raycluster-kuberay-additional-worker-group2-b2455 1/1 Running 0 2d18h
raycluster-kuberay-head 2/2 Running 0 5d21h
raycluster-kuberay-standard-worker-worker-bs8t8 1/1 Running 0 5d21h
理解 ArgoCD 中的 Ray 自动伸缩#
确定要忽略的字段#
RayCluster 应用程序配置中的 ignoreDifferences 部分对于正确的自动伸缩至关重要。要确定需要忽略哪些字段,您可以检查 RayCluster 资源以识别在运行时动态更改的字段。
首先,描述 RayCluster 资源以查看其完整的规范
kubectl describe raycluster raycluster-kuberay -n ray-cluster
或者,以 YAML 格式获取资源,以查看确切的字段路径
kubectl get raycluster raycluster-kuberay -n ray-cluster -o yaml
查找被控制器或自动伸缩器修改的字段。对于 Ray,自动伸缩器会修改每个工作节点组规范下的 replicas 字段。您将看到类似以下的输出:
spec:
workerGroupSpecs:
- replicas: 5 # This value changes dynamically
minReplicas: 1
maxReplicas: 200
groupName: standard-worker
# ...
当 ArgoCD 检测到所需状态(在 Git 中)与实际状态(在集群中)之间的差异时,它将在 UI 或通过 CLI 中显示这些差异。
argocd app diff raycluster
如果您看到控制器(如自动伸缩器)管理的字段重复出现差异,则这些字段是 ignoreDifferences 的候选。
配置 ignoreDifferences#
RayCluster 应用程序配置中的 ignoreDifferences 部分会告知 ArgoCD 要忽略哪些字段。如果没有此设置,ArgoCD 和 Ray 自动伸缩器可能会发生冲突,导致在动态请求工作节点时出现意外行为(例如,使用 ray.autoscaler.sdk.request_resources)。具体来说,当请求 N 个工作节点时,自动伸缩器可能不会启动预期数量的工作节点,因为 ArgoCD 可能会将副本计数恢复到应用程序清单中定义的原始值。
推荐的方法是使用 jqPathExpressions,它会自动处理任意数量的工作节点组。
ignoreDifferences:
- group: ray.io
kind: RayCluster
name: raycluster-kuberay
namespace: ray-cluster
jqPathExpressions:
- .spec.workerGroupSpecs[].replicas
此配置告诉 ArgoCD 忽略所有工作节点组的 replicas 字段的差异。 jqPathExpressions 字段使用带有数组通配符([])的 JQ 语法,这意味着在添加或删除工作节点组时,您无需更新配置。
注意:name 和 namespace 必须与您的 RayCluster 资源名称和命名空间匹配。如果您已自定义这些值,请单独验证。
备选方案:使用 jsonPointers
如果您偏好显式配置,则可以使用 jsonPointers 替代
ignoreDifferences:
- group: ray.io
kind: RayCluster
name: raycluster-kuberay
namespace: ray-cluster
jsonPointers:
- /spec/workerGroupSpecs/0/replicas
- /spec/workerGroupSpecs/1/replicas
- /spec/workerGroupSpecs/2/replicas
使用 jsonPointers 时,您必须按索引明确列出每个工作节点组:
/spec/workerGroupSpecs/0/replicas- 第一个工作节点组(默认的worker组)/spec/workerGroupSpecs/1/replicas- 第二个工作节点组(additional-worker-group1)/spec/workerGroupSpecs/2/replicas- 第三个工作节点组(additional-worker-group2)
如果您添加或删除工作节点组,则 **必须** 相应地更新此列表。索引对应于 RayCluster 规范中工作节点组的出现顺序,默认的 worker 组位于索引 0,additionalWorkerGroups 则按其定义顺序排列。
有关这两种方法的更多详细信息,请参阅 ArgoCD diff 自定义文档。
通过忽略这些差异,ArgoCD 允许 Ray 自动伸缩器在不受干扰的情况下动态管理工作节点副本。
步骤 4:访问 Ray Dashboard#
要访问 Ray Dashboard,请端口转发 head 服务
kubectl port-forward -n ray-cluster svc/raycluster-kuberay-head-svc 8265:8265
在浏览器中导航到 https://:8265 以查看 Ray Dashboard。
自定义配置#
您可以通过修改 raycluster.yaml 文件中的 valuesObject 部分来自定义 RayCluster 配置:
镜像:更改
repository和tag以使用不同的 Ray 版本。工作节点组:通过修改
additionalWorkerGroups部分来添加或删除工作节点组。自动伸缩:调整
minReplicas、maxReplicas和idleTimeoutSeconds以控制自动伸缩行为。资源:修改
rayStartParams为工作节点组分配自定义资源。
进行更改后,将它们提交到您的 Git 存储库。如果启用了自动同步,ArgoCD 将自动将更改同步到您的集群。
备选方案:将所有内容部署到一个文件中#
如果您希望一次性部署所有组件,可以将所有三个 ArgoCD 应用程序合并到一个文件中。创建一个名为 ray-argocd-all.yaml 的文件,内容如下:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: ray-operator-crds
namespace: argocd
spec:
project: default
destination:
server: https://kubernetes.default.svc
namespace: ray-cluster
source:
repoURL: https://github.com/ray-project/kuberay
targetRevision: v1.5.1 # update this as necessary
path: helm-chart/kuberay-operator/crds
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- Replace=true
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: ray-operator
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/ray-project/kuberay
targetRevision: v1.5.1 # update this as necessary
path: helm-chart/kuberay-operator
helm:
skipCrds: true # CRDs are installed in the first Application
destination:
server: https://kubernetes.default.svc
namespace: ray-cluster
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: raycluster
namespace: argocd
spec:
project: default
destination:
server: https://kubernetes.default.svc
namespace: ray-cluster
ignoreDifferences:
- group: ray.io
kind: RayCluster
name: raycluster-kuberay # ensure this is aligned with the release name
namespace: ray-cluster # ensure this is aligned with the namespace
jqPathExpressions:
- .spec.workerGroupSpecs[].replicas
source:
repoURL: https://ray-project.github.io/kuberay-helm/
chart: ray-cluster
targetRevision: "1.4.1"
helm:
releaseName: raycluster # this affects the ignoreDifferences field
valuesObject:
image:
repository: docker.io/rayproject/ray
tag: latest
pullPolicy: IfNotPresent
head:
rayStartParams:
num-cpus: "0"
enableInTreeAutoscaling: true
autoscalerOptions:
version: v2
upscalingMode: Default
idleTimeoutSeconds: 600 # 10 minutes
env:
- name: AUTOSCALER_MAX_CONCURRENT_LAUNCHES
value: "100"
worker:
groupName: standard-worker
replicas: 1
minReplicas: 1
maxReplicas: 200
rayStartParams:
resources: '"{\"standard-worker\": 1}"'
resources:
requests:
cpu: "1"
memory: "1G"
additionalWorkerGroups:
additional-worker-group1:
image:
repository: docker.io/rayproject/ray
tag: latest
pullPolicy: IfNotPresent
disabled: false
replicas: 1
minReplicas: 1
maxReplicas: 30
rayStartParams:
resources: '"{\"additional-worker-group1\": 1}"'
resources:
requests:
cpu: "1"
memory: "1G"
additional-worker-group2:
image:
repository: docker.io/rayproject/ray
tag: latest
pullPolicy: IfNotPresent
disabled: false
replicas: 1
minReplicas: 1
maxReplicas: 200
rayStartParams:
resources: '"{\"additional-worker-group2\": 1}"'
resources:
requests:
cpu: "1"
memory: "1G"
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
在此示例中,请注意使用了 jqPathExpressions 方法。
一次应用所有三个应用程序
kubectl apply -f ray-argocd-all.yaml
这种单文件方法对于快速部署很方便,但前面各节中的分步方法可以更好地了解部署过程,并且更容易排除故障。