Kubernetes + Ray + Volcano:云原生AI训练调度体系的工程实践

引言:当大模型遇上Kubernetes的"能力边界"
千亿参数大模型的训练,动辄需要数百张GPU连续运行数周,每秒TB级的AllReduce通信,单次checkpoint可达数百GB。这种计算密集型、通信密集型、状态敏感、容错成本高 的工作负载,对调度系统提出了远超传统微服务的严苛要求。
在这里插入图片描述
Kubernetes已成为云原生基础设施的事实标准,但默认调度器在面对AI训练任务时,暴露出了三个致命短板:
- 不支持Gang Scheduling :分布式训练要求一组Pod"要么全部启动,要么一个都不启动"。默认调度器逐个调度Pod,部分Worker启动后Head未调度即导致整个训练任务死锁
- 拓扑感知缺失 :默认策略倾向于打散Pod(Spread),而AI训练恰恰需要亲和性调度,将通信频繁的Worker集中在同一机架甚至同一节点,以减少跨节点通信延迟
- 调度吞吐量不足:当集群规模达到数千节点、数万Pod时,默认调度器Pending队列堆积,任务启动延迟达到分钟级
Volcano + KubeRay 的组合,正是为解决这三个问题而生的系统性方案。Volcano是CNCF首个且唯一的官方容器批处理系统,提供Kubernetes原生调度器所不具备的批量调度、Gang调度和网络拓扑感知调度等能力;KubeRay则是在Kubernetes上自动化部署和管理Ray集群的Operator。三者的分工清晰明确:Kubernetes提供资源底座,Ray执行分布式计算,Volcano负责高性能调度。
一、环境搭建:从零部署KubeRay + Volcano
1.1 环境要求
部署前确保满足以下条件:
- 已安装Volcano的Kubernetes集群正常运行(Kubernetes 1.35及以上版本)
- 具备集群管理员权限
1.2 安装Volcano
bash
# 使用Helm安装Volcano
helm repo add volcano https://volcano-sh.github.io/helm-charts
helm install volcano volcano/volcano -n volcano-system --create-namespace
验证Volcano调度器是否正常运行:
bash
kubectl get pods -n volcano-system
1.3 安装支持Volcano的KubeRay Operator
从KubeRay v1.5.1版本开始,所有KubeRay资源(RayJob、RayCluster和RayService)均支持Volcano的高级调度特性。安装时需通过--set batchScheduler.name=volcano启用Volcano集成:
bash
helm install kuberay-operator kuberay/kuberay-operator \
--version 1.5.1 \
--set batchScheduler.name=volcano
1.4 部署RayCluster
下载官方示例配置并部署:
bash
curl -LO https://raw.githubusercontent.com/ray-project/kuberay/v1.5.1/ray-operator/config/samples/ray-cluster.volcano-scheduler.yaml
kubectl apply -f ray-cluster.volcano-scheduler.yaml
验证部署状态:
bash
kubectl get pods -l ray.io/cluster=raycluster-volcano
二、调度原理:Volcano为Ray带来了什么
2.1 Gang Scheduling:解决"All or Nothing"的死锁困境
Gang调度是Volcano最核心的能力。它要求一个作业的所有任务同时启动,适用于分布式训练、大数据等场景。
在KubeRay与Volcano的集成中,gang调度的实现逻辑如下:
- 启用自动扩缩容时 :使用
minReplicas进行gang调度 - 禁用自动扩缩容时:使用期望的副本数进行gang调度
这确保了在支持灵活扩缩容行为的同时,gang调度约束能够得到正确维护。
在KubeRay中,通过以下标签配置Volcano调度:
| 标签 | 描述 |
|---|---|
ray.io/priority-class-name |
为Pod调度分配Kubernetes优先级类 |
volcano.sh/queue-name |
指定资源提交的Volcano队列 |
volcano.sh/network-topology-mode |
配置网络拓扑感知调度模式 |
volcano.sh/network-topology-highest-tier-allowed |
设置调度允许的最高网络层级 |
一个典型的配置示例:
yaml
apiVersion: ray.io/v1
kind: RayCluster
metadata:
name: raycluster-volcano
labels:
volcano.sh/queue-name: "training-queue"
spec:
rayVersion: '2.40.0'
headGroupSpec:
rayStartParams:
dashboard-host: '0.0.0.0'
template:
spec:
containers:
- name: ray-head
image: rayproject/ray:2.40.0
resources:
limits:
nvidia.com/gpu: 1
workerGroupSpecs:
- groupName: worker-group
replicas: 3
minReplicas: 3
rayStartParams: {}
template:
spec:
containers:
- name: ray-worker
image: rayproject/ray:2.40.0
resources:
limits:
nvidia.com/gpu: 1
2.2 网络拓扑感知调度:NVL72场景的杀手锏
在NVL72等超大规模分布式训练场景中,多个GPU通过NVLink域互联,要求同一训练任务的Worker必须部署在同一个低延迟域内,而非分散到集群各处。
Volcano v1.14引入了subgroup-level的二级分组能力,支持:
- 将PodGroup内的Pod划分为多个子组
- 配置子组级别的gang调度
- 确保子组内的Pod调度到同一个网络拓扑域(如同一个HyperNode)
在Volcano调度体系中,针对NVL72这类拓扑/块级作业,调度分为三个层次:
- Gang层:Head和Worker一起启动
- 作业级拓扑:整个分配落在同一个粗粒度层级内
- 分段级拓扑:每个Worker段必须落在同一个NVLink域内
KubeRay已经通过PodGroup和network-topology支持了前两层,而第三层(per-segment topology)正在通过subGroupPolicy字段的引入来实现。
对于高性能组,可以要求特定工作组调度到同一HyperNode内以保证低延迟通信;标准组则可能只需要同区域或同可用区即可。这种差异化的拓扑约束,使得调度器能够独立满足每个组特定的性能域要求。
2.3 Gang粒度抢占:v1.15的里程碑
Volcano v1.15.0引入的Gang-Aware Preemption,解决了AI训练场景下最棘手的资源抢占问题。
在传统Kubernetes调度中,抢占以单个Pod为单位决策。当资源紧张时,调度器可能从多个正在运行的训练任务中各抢一个Pod------表面上释放了资源,实际上既打断了多个任务,发起抢占的Gang也未必能凑齐minAvailable成功启动。
v1.15.0的改进体现在两个层面:
被抢占方侧 :以Job/Gang为粒度组织被抢占候选,区分冗余副本 (超出minAvailable的部分)和关键副本,优先驱逐冗余副本------驱逐它们不会打断任务。
抢占方侧 :逐步累计可释放的资源,当累计量足以覆盖抢占方Gang的整体需求时,先做放置模拟------在释放后的资源视图上验证抢占方Gang能否整体调度成功------只有模拟通过才真正执行驱逐。
这一机制从根本上避免了"抢了一堆Pod,但谁都没跑起来"的尴尬局面。
2.4 Volcano Job方式:另一种部署选择
除了KubeRay Operator方式,Volcano还提供了通过Volcano Job配合Ray插件直接部署Ray集群的方式。
Ray插件负责三件事:
- 配置Ray集群中Head和Worker节点的启动命令
- 为Ray Head节点开放GCS、Ray Dashboard和Client Server三个端口
- 创建映射到Ray Head节点容器端口的Service
部署示例:
yaml
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: ray-cluster-job
spec:
minAvailable: 3
schedulerName: volcano
plugins:
ray: []
svc: []
policies:
- event: PodEvicted
action: RestartJob
queue: default
tasks:
- replicas: 1
name: head
template:
spec:
containers:
- name: head
image: rayproject/ray:latest-py311-cpu
resources: {}
restartPolicy: OnFailure
- replicas: 2
name: worker
template:
spec:
containers:
- name: worker
image: rayproject/ray:latest-py311-cpu
resources: {}
restartPolicy: OnFailure
两种方式都可以充分利用Volcano的gang调度和网络拓扑感知调度能力。KubeRay Operator方式更适合需要自动化管理Ray集群生命周期的场景 ,而Volcano Job方式则更轻量、更适合一次性任务。
三、生产实践:常见问题与调优
3.1 多调度器共存
如果需要某些Job使用Volcano、其他Job使用默认调度器,必须部署多个独立的KubeRay Operator实例 ,每个配置不同的batchScheduler.name:
bash
# 部署使用Volcano的Operator
helm install kuberay-operator-volcano kuberay/kuberay-operator \
--namespace volcano-ray \
--set batchScheduler.name=volcano
# 部署使用默认调度器的Operator
helm install kuberay-operator-default kuberay/kuberay-operator \
--namespace default-ray \
--set batchScheduler.name=
3.2 RayJob的PodGroup生命周期管理
当RayJob到达终态(Complete/Failed)时,VolcanoBatchScheduler会删除PodGroup以释放队列资源 。需要注意的是,目前存在一个已知问题:RayJob挂起时可能导致Volcano PodGroup泄漏,占用队列资源,生产环境中需关注此问题并及时清理。
3.3 不同Worker组的差异化优先级
对于不同的Worker组,可以配置不同的Pod优先级:
yaml
workerGroupSpecs:
- groupName: worker-high-priority
replicas: 2
template:
metadata:
labels:
ray.io/priority-class-name: "high-priority"
spec:
containers:
- name: ray-worker
image: rayproject/ray:2.40.0
resources:
limits:
nvidia.com/gpu: 1
- groupName: worker-low-priority
replicas: 2
template:
metadata:
labels:
ray.io/priority-class-name: "best-effort"
spec:
containers:
- name: ray-worker
image: rayproject/ray:2.40.0
resources:
limits:
nvidia.com/gpu: 1
3.4 队列与资源配额管理
Volcano支持多层级队列结构和资源继承:
yaml
apiVersion: scheduling.volcano.sh/v1beta1
kind: Queue
metadata:
name: training-queue
spec:
weight: 1
reclaimable: true
capability:
cpu: 100
memory: 200Gi
nvidia.com/gpu: 50
通过队列可以实现多租户资源隔离和优先级控制,确保不同团队的训练任务互不干扰。
四、总结
Kubernetes + Ray + Volcano的技术组合,是针对大规模、高性能AI工作负载的系统性解决方案:
| 组件 | 职责 | 核心价值 |
|---|---|---|
| Kubernetes | 资源底座 | 容器编排、服务发现、声明式API |
| Ray | 分布式计算引擎 | 分布式训练、超参数调优、模型服务 |
| Volcano | 高性能调度器 | Gang调度、拓扑感知、队列管理、Gang粒度抢占 |
三者通过KubeRay Operator 实现深度集成,KubeRay负责Ray集群的自动化生命周期管理,Volcano负责提供高性能调度能力。从Gang调度解决死锁困境,到网络拓扑感知优化NVL72等超大规模训练,再到v1.15的Gang粒度抢占------Volcano正在从批处理工具演进为AI-Native的统一调度平台。
对于正在构建云原生AI基础设施的团队而言,这套组合的价值已经过CNCF社区和大量生产环境的验证。它不是简单的"三个开源项目堆叠",而是一个定位清晰、分工明确、协同高效的AI工作负载运行平台。