KubeRay 与 Apache YuniKorn 集成指南:Kubernetes 多租户环境下的 Ray 集群细粒度调度与 Gang Scheduling
KubeRay 与 Apache YuniKorn 集成指南Kubernetes 多租户环境下的 Ray 集群细粒度调度与 Gang Scheduling【免费下载链接】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 的 Kubernetes 生态KubeRay中接入 Apache YuniKorn——一个轻量、通用、面向云原生环境的容器编排资源调度器为 Ray head/worker Pod 提供多租户环境下的细粒度资源共享与**全有或全无All-or-Nothing的 gang scheduling成组调度**能力。读完本文你将掌握 YuniKorn 的安装、KubeRay operator 的启用方式、队列queue配置、必要的标签设置以及如何通过 YuniKorn 仪表盘观察 Ray 应用从 Accepted 到 Running 的完整调度过程并理解为什么宁可排队等待全部资源、也不部分调度的语义能避免分布式训练集群出现资源碎片化。为什么需要 YuniKorn多租户与成组调度Apache YuniKorn 是一个轻量级、通用的容器编排系统资源调度器。它面向大规模、多租户、云原生环境能够为混合负载包括无状态的批处理负载与有状态的服务提供统一、跨平台的调度体验对各类工作负载进行细粒度的资源共享。在 Ray 的场景中一个 RayCluster 通常由一个 head Pod 和若干 worker Pod 组成。默认的 Kubernetes 调度器逐 Pod 独立调度这会导致一个问题当集群剩余资源只够放下 head 或部分 worker 时Pod 会被部分调度整个 RayCluster 处于不完整状态分布式训练任务如依赖全部节点到齐的 Horovod 等只能空等资源。YuniKorn 通过 gang scheduling 语义解决了这一问题要么整个 RayCluster 的 Pod 全部获得资源要么一个都不调度直到队列中有足够容纳全部 Pod 的资源为止。KubeRay 对 Apache YuniKorn 的集成正是为了让 Ray 的 head/worker Pod 在多租户 Kubernetes 环境中获得这种更高效、更可预期的调度行为。注意该特性要求 KubeRay 版本为 1.2.2 或更新目前处于 alpha 测试阶段。Step 1使用 Kind 创建 Kubernetes 集群在终端中执行以下命令创建一个本地 Kubernetes 集群用于实验kind create clusterStep 2安装 Apache YuniKorn在启用 KubeRay 与 YuniKorn 的集成之前需要先在 Kubernetes 集群上成功安装 Apache YuniKorn。安装完成后YuniKorn 会通过 Helm 在yunikorn命名空间下创建若干组件其中包括后续配置队列时需要用到的 ConfigMapyunikorn-defaults。请参考 Apache YuniKorn 官方文档中的 Get Started 部分完成安装。Step 3安装带 Apache YuniKorn 支持的 KubeRay operator使用 Helm 安装 KubeRay operator 时通过命令行参数指定批量调度器batch scheduler为 YuniKornhelm install kuberay-operator kuberay/kuberay-operator --version 1.7.0 --set batchScheduler.nameyunikorn--set batchScheduler.nameyunikorn这一参数让 KubeRay operator 在创建 RayCluster 的 Pod 时自动为它们打上与 YuniKorn 协作所需的标签与注解详见 Step 4从而将调度权交给 YuniKorn。从 KubeRay 的配置惯例看可对比同一文档目录下的 volcano.md批量调度器是在operator 级别统一配置的v1.3.0 之后无需再在 RayCluster 上单独添加ray.io/scheduler-name标签调度器选择完全由 operator 启动参数或 Helm values 控制。如果你更习惯声明式配置也可以在 Helm values 中设置batchScheduler.name: yunikorn效果等价。Step 4使用 Apache YuniKorn 实现 Gang Scheduling以下示例演示 KubeRay 如何配合 YuniKorn 对 RayCluster 自定义资源进行 gang scheduling。自 KubeRay 1.6.0 起KubeRay 同样支持对 RayJob 自定义资源进行 gang scheduling。4.1 创建容量为 4 CPU / 6Gi 内存的队列执行以下命令编辑 YuniKorn 的配置 ConfigMapkubectl edit configmap -n yunikorn yunikorn-defaults该 ConfigMap 由 Apache YuniKorn Helm chart 在安装时自动创建。在data键下新增一个queues.yaml配置项编辑后的 ConfigMap 应如下所示apiVersion: v1 kind: ConfigMap metadata: # ConfigMap 的元数据此处省略 data: queues.yaml: | partitions: - name: default queues: - name: root queues: - name: test submitacl: * parent: false resources: guaranteed: memory: 6G vcore: 4 max: memory: 6G vcore: 4保存并退出编辑器。该配置创建了一个名为root.test的队列容量为 4 CPU 与 6Gi 内存。配置要点说明submitacl: *允许所有用户向该队列提交应用便于测试环境快速验证parent: false该队列不是父队列可以直接承载应用resources.guaranteedYuniKorn 为队列预留的保证资源量此处为 6G 内存 4 vcore只要集群资源允许队列总能获得这部分资源resources.max队列可使用的资源上限硬约束本例与 guaranteed 一致表示该队列独占这 4 CPU / 6Gi 资源。4.2 创建第一个 RayCluster接下来创建一个 RayClusterhead 节点 1 CPU 2GiB 内存两个 worker 各 1 CPU 1GiB 内存合计 3 CPU 与 4GiB 内存# 路径kuberay/ray-operator/config/samples # 在 RayCluster 自定义资源上配置供 Apache YuniKorn 调度器进行 gang scheduling 的标签 # - ray.io/gang-scheduling-enabled设为 true 以启用 gang scheduling。 # - yunikorn.apache.org/app-id设置为该应用在 Kubernetes 中的唯一标识跨命名空间唯一。 # - yunikorn.apache.org/queue设置为 Apache YuniKorn 中某个队列的名称。 wget https://raw.githubusercontent.com/ray-project/kuberay/master/ray-operator/config/samples/ray-cluster.yunikorn-scheduler.yaml kubectl apply -f ray-cluster.yunikorn-scheduler.yaml查看 KubeRay operator 创建的 RayCluster$ kubectl describe raycluster test-yunikorn-0 Name: test-yunikorn-0 Namespace: default Labels: ray.io/gang-scheduling-enabledtrue yunikorn.apache.org/app-idtest-yunikorn-0 yunikorn.apache.org/queueroot.test Annotations: none API Version: ray.io/v1 Kind: RayCluster Metadata: Creation Timestamp: 2024-09-29T09:52:30Z Generation: 1 Resource Version: 951 UID: cae1dbc9-5a67-4b43-b0d9-be595f21ab85 # 其余字段省略注意 RayCluster 上的三个标签这是 KubeRay 与 YuniKorn 协作的关键契约标签取值示例作用ray.io/gang-scheduling-enabledtrue是否启用 gang schedulingyunikorn.apache.org/app-idtest-yunikorn-0应用的全局唯一标识用于将同一 Ray 集群的多个 Pod 归组yunikorn.apache.org/queueroot.test应用提交到的 YuniKorn 队列注意只有当你需要 gang scheduling 时才需要设置ray.io/gang-scheduling-enabled标签。如果未设置该标签YuniKorn 仍会正常调度该 Ray 集群只是不强制执行 gang scheduling即退化为普通逐 Pod 调度。由于队列容量为 4 CPU 与 6GiB 内存而该集群只需要 3 CPU 与 4GiB 内存资源应能顺利调度成功$ kubectl get pods NAME READY STATUS RESTARTS AGE test-yunikorn-0-head-98fmp 1/1 Running 0 67s test-yunikorn-0-worker-worker-42tgg 1/1 Running 0 67s test-yunikorn-0-worker-worker-467mn 1/1 Running 0 67s4.3 通过 YuniKorn 仪表盘验证调度结果通过端口转发访问 Apache YuniKorn 仪表盘kubectl port-forward svc/yunikorn-service 9889:9889 -n yunikorn然后在浏览器中访问http://localhost:9889/#/applications查看正在运行的应用4.4 添加第二个 RayCluster观察 Gang Scheduling 排队接下来添加另一个 RayClusterhead 与 worker 配置完全一致仅更换名称# 将名称替换为 test-yunikorn-1 sed s/test-yunikorn-0/test-yunikorn-1/ ray-cluster.yunikorn-scheduler.yaml | kubectl apply -f-现在test-yunikorn-1的所有 Pod 都处于Pending状态$ kubectl get pods NAME READY STATUS RESTARTS AGE test-yunikorn-0-head-98fmp 1/1 Running 0 4m22s test-yunikorn-0-worker-worker-42tgg 1/1 Running 0 4m22s test-yunikorn-0-worker-worker-467mn 1/1 Running 0 4m22s test-yunikorn-1-head-xl2r5 0/1 Pending 0 71s test-yunikorn-1-worker-worker-l6ttz 0/1 Pending 0 71s test-yunikorn-1-worker-worker-vjsts 0/1 Pending 0 71s tg-test-yunikorn-1-headgroup-vgzvoot0dh 0/1 Pending 0 69s tg-test-yunikorn-1-worker-eyti2bn2jv 1/1 Running 0 69s tg-test-yunikorn-1-worker-k8it0x6s73 0/1 Pending 0 69s观察点Apache YuniKorn 会为 gang scheduling 创建带tg-前缀的 Pod。这些tg-前缀 Pod 是 YuniKorn 用于跟踪应用成组状态的内部标记出现它们即表示 YuniKorn 正在对该 Ray 集群执行成组调度逻辑。回到http://localhost:9889/#/applications可以看到test-yunikorn-1处于Accepted状态但尚未运行为什么第二个集群的 Pod 不调度新集群总共需要 3 CPU 与 4GiB 内存而队列剩余容量只有 1 CPU 与 2GiB 内存。虽然理论上可以放下其中的一个 Pod但 YuniKorn 在队列有足够空间容纳全部Pod 之前不会放置该集群的任何 Pod。这正是 gang scheduling 的价值所在如果不使用 YuniKorn 的 gang schedulingKubeRay 会先放置其中一个 Pod导致集群被部分分配而部分分配的 Ray 集群无法真正对外提供服务反而白白占用资源。4.5 释放资源观察第二个集群恢复调度删除第一个 RayCluster释放队列资源kubectl delete raycluster test-yunikorn-0现在有足够的资源调度整个 Pod 集合第二个集群的所有 Pod 全部转为Running状态$ kubectl get pods NAME READY STATUS RESTARTS AGE test-yunikorn-1-head-xl2r5 1/1 Running 0 3m34s test-yunikorn-1-worker-worker-l6ttz 1/1 Running 0 3m34s test-yunikorn-1-worker-worker-vjsts 1/1 Running 0 3m34s4.6 清理资源删除第二个 RayCluster完成实验清理kubectl delete raycluster test-yunikorn-1深入理解KubeRay 双调度器分层与排障思路要正确使用 YuniKorn 集成需要理解 Ray on Kubernetes 中存在的两层调度器详见 scheduling.mdKubernetes / YuniKorn 层决定每个 Pod 跑在哪台机器上读取容器 spec 中的资源请求、节点选择器、污点、亲和性以及队列容量等约束。当 Pod 无法被放置时表现为Pending。Ray 层决定每个 task 与 actor 运行在哪个 Ray 节点上读取ray.remote中声明的逻辑资源。当 task/actor 无法放置时表现为任务挂起而 Pod 正常运行。两层是堆叠而非并列关系Ray 只能分配 Kubernetes 已经授予 Pod 的容量。因此在 YuniKorn 集成环境下排查调度问题时可以从 Pod 状态入手快速定位Pod 全部 Running 但 task/actor 挂起问题在 Ray 层Pod 卡在Pending问题在 Kubernetes/YuniKorn 层此时应执行kubectl describe pod pod-name查看调度事件或到 YuniKorn 仪表盘检查应用是否因队列容量不足而处于Accepted/Queued状态。另外需要注意 KubeRay 派生逻辑资源的方式KubeRay 读取主 Ray 容器的 CPU、内存、GPUlimits作为 Pod 的逻辑容量CPU 向上取整为整数500m会被视为 1 个逻辑 CPU并忽略内存与 GPU 的 requests。因此在使用 YuniKorn 队列做容量规划时建议将容器的 requests 与 limits 设为一致使两层调度器看到相同的资源数值避免出现Kubernetes 认为健康、YuniKorn 队列认为已满的认知偏差。总结关键项配置/行为前置条件KubeRay ≥ 1.2.2alpha已安装 Apache YuniKorn启用方式helm install kuberay-operator kuberay/kuberay-operator --version 1.7.0 --set batchScheduler.nameyunikorn队列配置编辑yunikorn-defaultsConfigMap 中的queues.yaml定义guaranteed/max资源启用 gang scheduling设置ray.io/gang-scheduling-enabledtrue可选app-id、queue标签RayJob 支持KubeRay ≥ 1.6.0 支持对 RayJob 的 gang scheduling验证手段kubectl get pods、YuniKorn 仪表盘kubectl port-forward svc/yunikorn-service 9889:9889 -n yunikorn核心价值队列级细粒度资源共享 成组调度避免 Ray 集群被部分调度而浪费资源通过本指南的四个步骤你可以在多租户 Kubernetes 集群中让 YuniKorn 接管 Ray Pod 的调度用队列实现租户间资源隔离与配额用 gang scheduling 保证 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创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Spring Cloud Alibaba Sidecar 实战指南:借助 Nacos 将 Node.js 等异构语言服务无缝接入 Spring Cloud 微服务体系

Spring Cloud Alibaba Sidecar 实战指南:借助 Nacos 将 Node.js 等异构语言服务无缝接入 Spring Cloud 微服务体系

Spring Cloud Alibaba Sidecar 实战指南:借助 Nacos 将 Node.js 等异构语言服务无缝接入 Spring Cloud 微服务体系 【免费下载链接】spring-cloud-alibaba Spring Cloud Alibaba provides a one-stop solution for application development for the distributed sol…

2026/9/19 15:47:05 阅读更多 →
基于Java Web的企业人事管理系统:JSP+Servlet+SqlServer实现

基于Java Web的企业人事管理系统:JSP+Servlet+SqlServer实现

简介:这是一份基于Java的企业人事管理系统毕业设计文档,面向计算机相关专业学生、Java入门开发者以及需要参考人事管理信息化的项目人员,可帮助读者快速把握基于Web的人事管理系统从需求到实现的完整设计路径。内容围绕系统分析、总体设计、详…

2026/9/19 15:47:05 阅读更多 →
嵌入式人工智能:让传感器具备本地决策能力

嵌入式人工智能:让传感器具备本地决策能力

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 15:47:05 阅读更多 →

最新新闻

OneUptime 集成 Discord:用内置工作流组件将事故通知推送到频道

OneUptime 集成 Discord:用内置工作流组件将事故通知推送到频道

OneUptime 集成 Discord:用内置工作流组件将事故通知推送到频道 【免费下载链接】oneuptime Complete open-source monitoring and observability platform. 项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime 导读 本指南讲解如何在 OneUptime …

2026/9/19 16:38:28 阅读更多 →
Qt 5.14.2 ARM交叉编译踩坑全记录:从工具链到上板部署

Qt 5.14.2 ARM交叉编译踩坑全记录:从工具链到上板部署

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 16:38:28 阅读更多 →
CANN opbase 算子开发指南:IsComplexType 复数数据类型判断接口详解

CANN opbase 算子开发指南:IsComplexType 复数数据类型判断接口详解

CANN opbase 算子开发指南:IsComplexType 复数数据类型判断接口详解 【免费下载链接】opbase 本项目是CANN算子库的基础框架库,为算子提供公共依赖文件和基础调度能力。 项目地址: https://gitcode.com/cann/opbase 导读 IsComplexType 是 CANN …

2026/9/19 16:38:28 阅读更多 →
Unity视频播放插件AVPro Video免费版与收费版选型指南

Unity视频播放插件AVPro Video免费版与收费版选型指南

在Unity项目里做视频播放,绕不开的一个插件就是AVPro Video。我最早接触它是在一个展厅互动项目上,当时用Unity自带的VideoPlayer播放4K宣传片,在PC上跑得好好的,一打包到安卓一体机就各种卡顿、音画不同步,折腾了整整…

2026/9/19 16:38:28 阅读更多 →
Hugo 菜单遍历方法全解析:ByName、ByWeight、Limit、Reverse 实战指南

Hugo 菜单遍历方法全解析:ByName、ByWeight、Limit、Reverse 实战指南

Hugo 菜单遍历方法全解析:ByName、ByWeight、Limit、Reverse 实战指南 【免费下载链接】hugo The world’s fastest framework for building websites. 项目地址: https://gitcode.com/gh_mirrors/hu/hugo Hugo 的 Menu 类型提供了一组用于遍历菜单条目&…

2026/9/19 16:38:28 阅读更多 →
容灾备份核心指南:RPO/RTO、架构选型与演练落地

容灾备份核心指南:RPO/RTO、架构选型与演练落地

简介:容灾备份通用基础知识培训PPT课件面向IT运维、数据中心管理人员及企业业务连续性负责人,系统讲解灾备的定义、作用、衡量标准(RTO与RPO)以及实现方法,帮助初学者快速建立灾备知识框架。课件内容涵盖数据中心面临的…

2026/9/19 16:37:27 阅读更多 →

日新闻

BP神经网络时序预测:滑窗长度与多窗口平均策略

BP神经网络时序预测:滑窗长度与多窗口平均策略

简介:面向机器学习、深度学习与数据建模学习者的一份完整研究文献,聚焦BP神经网络在农业产量预测中的应用。文档以1980—2018年全国棉花产量为样本,系统讲解数据归一化处理、激活函数原理、多层神经网络结构搭建及训练流程,展示敏…

2026/9/19 0:00:30 阅读更多 →
Transformer训练实时监控实战:基于MindSpore的损失曲线可视化方案

Transformer训练实时监控实战:基于MindSpore的损失曲线可视化方案

上个月调一个Deformable DETR模型,在单卡上要跑将近两天。第二天早上我下意识打开终端翻日志,发现loss从凌晨两点就开始往上爬,一路从0.8涨到1.35,整整六个小时没人发现。那六个小时的训练不仅白跑,还霸占着卡——等于…

2026/9/19 0:00:30 阅读更多 →
OpenCloud 中的 Go 类型安全转换库 spf13/cast:从零值回退到泛型 API 的完整实战指南

OpenCloud 中的 Go 类型安全转换库 spf13/cast:从零值回退到泛型 API 的完整实战指南

OpenCloud 中的 Go 类型安全转换库 spf13/cast:从零值回退到泛型 API 的完整实战指南 【免费下载链接】opencloud 🌤️ OpenCloud is the open source platform for file management, sharing and collaboration. Simple and sovereign. 项目地址: htt…

2026/9/19 0:00:30 阅读更多 →

周新闻

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验 【免费下载链接】ai The AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and ag…

2026/9/19 3:59:36 阅读更多 →
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化

Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化

Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化 【免费下载链接】refine A React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility. 项目地址: https://gitcode.com/GitH…

2026/9/19 3:53:08 阅读更多 →
Flutter应用改名全指南:从Android到iOS的配置与工具实践

Flutter应用改名全指南:从Android到iOS的配置与工具实践

刚接一个外包项目时,甲方要求把工程里临时用的应用名改成正式产品名。我本来觉得“改名”这种小事,打开配置文件改一行不就完了?结果真动手才发现,Flutter项目里“应用名称”根本不是一处配置,而是一整套散落在 Androi…

2026/9/19 4:02:43 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/16 22:31:27 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/15 21:39:18 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/16 22:32:59 阅读更多 →