为 AKS 上的 Ray 工作负载配置 Kueue 队列

在本文中,你将在 Azure Kubernetes 服务 (AKS) 上为 Ray 工作负载配置 Kueue 准入控制。 Kueue 对 RayJob 提交进行准入控制:作业创建时会带有 suspend: true 和队列标签。 Kueue 在配额可用时通过设置 suspend: false来承认它们,这会触发 KubeRay 运算符创建 Ray 群集。

提供两种队列配置。 选择适合你的使用场景的选项:

Configuration 它演示的内容
单个队列 一个带有反压的 ClusterQueue - 一个工作负荷运行,下一个等待
团队队列 同一共享 cohort 中的两个 ClusterQueue,包含每个团队的配额、借用和抢占

Important

AKS 文档和示例中都提到了开源软件。 您部署的软件被排除在 AKS 服务级别协议、有限保修和 Azure 支持之外。 将开源技术与 AKS 一起使用时,请查阅相应社区和项目维护者提供的支持选项来制定计划。

Microsoft 将负责生成我们在 AKS 上部署的开源包。 该责任包括拥有构建、扫描、签名、验证和快速修复流程的完整所有权,并掌控容器镜像中的二进制文件。 如需了解详细信息,请参阅 AKS 漏洞管理AKS 支持范围

先决条件

创建命名空间和服务帐户

导航到克隆存储库中的队列配置模块:

cd <path-to-cloned-repo>/AKS/examples/kueue-and-ray-on-aks/2-kueue-queues
kubectl apply -f manifests/00-namespace.yaml
kubectl apply -f <(terraform -chdir=../1-infrastructure/terraform output -raw ray_workload_sa_yaml)

验证服务帐户是否具有工作负荷标识注释:

kubectl -n ray get serviceaccount ray-workload -o yaml

输出应包含azure.workload.identity/client-idazure.workload.identity/tenant-id批注,允许 Ray Pod 在没有凭据的情况下访问Azure Blob 存储。

创建 ResourceFlavors

ResourceFlavors 描述群集中可用的节点类型。 创建两种风格 - default (任何节点) 和 gpu (NVIDIA 加速器节点):

kubectl apply -f manifests/10-resource-flavors.yaml

验证:

kubectl get resourceflavors

预期输出:

NAME      AGE
default   1m
gpu       1m

gpu flavor 针对带有标签 accelerator=nvidia 的节点,而该标签会由 AKS 自动应用到 GPU 节点池。

选项 A:配置单个队列

单队列配置会创建一个 ClusterQueue,其配额按同一时间仅支持一个工作负载的规模进行设置。 当配额已全部用完时,下一次提交将一直处于待处理状态,直到前一个提交完成。

kubectl apply -f manifests/20-single-queue.yaml

验证 ClusterQueue 和 LocalQueue:

kubectl get clusterqueue cluster-queue
kubectl -n ray get localqueue default

预期输出:

NAME            COHORT   PENDING WORKLOADS
cluster-queue            0
NAME      CLUSTERQUEUE    PENDING WORKLOADS   ADMITTED WORKLOADS
default   cluster-queue   0                   0

检查配置的配额:

kubectl get clusterqueue cluster-queue -o jsonpath='{.spec.resourceGroups}' | python3 -m json.tool

默认配额设置为一次可容纳此解决方案中的一个工作负载:96 个 CPU、768 Gi 内存、8 个 GPU。

选项 B:配置启用借用功能的团队队列

团队队列配置将 GPU 节点拆分为两个团队,每个团队都有自己的 ClusterQueue,通过共享队列进行连接:

kubectl apply -f manifests/30-team-queues.yaml

Important

选择选项 A 或选项 B,而不是同时选择。 若要在它们之间切换,请先删除活动配置:

kubectl delete -f manifests/20-single-queue.yaml

验证:

kubectl get clusterqueues
kubectl -n ray get localqueues

预期输出:

NAME        COHORT          PENDING WORKLOADS
team-a-cq   shared-cohort   0
team-b-cq   shared-cohort   0
NAME     CLUSTERQUEUE    PENDING WORKLOADS   ADMITTED WORKLOADS
team-a   team-a-cq       0                   0
team-b   team-b-cq       0                   0

注释

工作负荷示例默认为 QUEUE_NAME=default与选项 A 匹配。如果选择了选项 B,请设置 export QUEUE_NAME=team-aexport QUEUE_NAME=team-b在每个 工作负荷目录中运行 source env.example 之前。

每个团队获得 4 个 borrowingLimit GPU,保证其值为 4,因此当另一个团队处于空闲状态时,团队最多可以使用 8 个 GPU。 关键行为:

Scenario 发生的情况
团队 A 提交,团队 B 空闲 团队 A 获得全部 8 块 GPU(4 块自有的 + 4 块借来的)
团队 B 提交,而团队 A 使用 8 Kueue 抢占了 A 团队借用的 GPU,B 团队获得了其有保障的 4 个 GPU
两个团队都忙 每个团队都使用其有保证的 4 个 GPU

Troubleshooting

症状 原因 修复
工作负荷保持挂起状态 配额已用尽 等待正在运行的工作负荷完成,或在 ClusterQueue 中增加nominalQuota
LocalQueue not found 错误的队列名称标签 验证 kueue.x-k8s.io/queue-name 标签是否与现有 LocalQueue 名称匹配
ResourceFlavor 与节点不匹配 缺少节点标签 检查 GPU 节点是否具有 accelerator=nvidia 标签 kubectl get nodes --show-labels
Kueue 控制器未运行 Helm 发布问题 通过 kubectl -n kueue-system logs deploy/kueue-controller-manager 进行检查

有关完整的清单详细信息,请参阅存储库中的 2-kueue-queues 目录

清理资源

若要删除 Kueue 队列配置(保留群集和运算符):

kubectl delete -f manifests/20-single-queue.yaml   # or 30-team-queues.yaml
kubectl delete -f manifests/10-resource-flavors.yaml
kubectl delete -f manifests/00-namespace.yaml

注释

ray删除命名空间会删除该命名空间中的所有工作负荷、LocalQueues 和 ServiceAccount。 ClusterQueues 和 ResourceFlavors 是集群级别的,必须单独删除。 若要拆除整个基础结构,请参阅 在 AKS 上部署 Ray 和 Kueue 的基础结构

后续步骤

在配置的队列上运行工作负荷示例。 步骤 1-2 和步骤 3-4 是独立的对:

  1. 微调极光天气模型
  2. 使用 Ray Serve 提供微调的极光模型 (需要步骤 1)
  3. 使用 Ray 训练 LLM
  4. 使用 Ray 运行批处理推理 (需要步骤 3)