第 6 章
集群编排与作业调度
前几章把硬件搭起来了:服务器、网络、存储、机房。这一章讲集群上线以后,谁在什么时候用哪几张卡。GPU 是集群里最贵的资源,调度做不好,要么大家抢卡,要么卡闲着没人用。
为什么需要调度
一个 GPU 集群通常有很多用户、很多团队共用,跑的作业形态也各不相同:
| 作业类型 | 特点 |
|---|---|
| 训练 | 批处理,跑几小时到几周,可能要几十上百张卡,跑完就结束 |
| 交互式开发 | Jupyter、调试,占卡时间长但实际计算少 |
| 推理服务 | 长期在线,随请求量扩缩 |
调度系统要解决这些问题:
- 排队:卡不够时作业排队,而不是互相抢;
- 公平与优先级:按团队配额分配资源,重要任务可以插队,必要时抢占低优先级作业;
- 成组调度(gang scheduling):一个要 64 张卡的分布式训练,必须 64 张卡同时到位才能开始。只分到 60 张就先占着,既跑不起来,又让别人用不了;
- 拓扑感知:多卡作业尽量分到有 NVLink 直连的卡上,多机作业尽量分到同一台 leaf 交换机下(第 3、4 章),通信才快;
- 隔离:一个作业不能影响别的作业,作业结束后资源干净地回收。
主流的调度系统有两大类:HPC 出身的 Slurm 和云原生出身的 Kubernetes。
容器:让环境跟着作业走
第 2 章讲过,驱动留在宿主机,CUDA 及以上打包进容器。放到集群里,这个做法更重要:几百个节点上的软件环境不可能手工维护一致,每个作业自带容器镜像,调度到哪个节点都能跑。
- Kubernetes 本来就以容器为单位运行;
- Slurm 原生是直接在节点上跑进程,NVIDIA 为它做了 Enroot(把容器镜像转成普通用户就能运行的沙箱)和 Pyxis(Slurm 插件,让
srun能直接指定容器镜像),让 Slurm 也能用 NGC 容器。
Slurm:HPC 出身的批处理调度
Slurm 是超算中心用了很多年的开源作业调度系统,TOP500 榜单前 10 和前 100 的超算里都有一半以上在用它。2025 年 12 月 NVIDIA 收购了 Slurm 的开发公司 SchedMD,并承诺 Slurm 继续开源、保持厂商中立。
架构
| 组件 | 跑在哪 | 作用 |
|---|---|---|
slurmctld | 管理节点 | 控制中心:维护队列、决定作业在哪跑 |
slurmd | 每个计算节点 | 接收任务、启动进程、汇报节点状态 |
slurmdbd | 管理节点 | 记账数据库:记录谁用了多少资源,公平调度按它算 |
节点按分区(partition)分组,相当于不同的队列,比如 GPU 分区、CPU 分区、调试分区。
常用命令
| 命令 | 作用 |
|---|---|
sinfo | 看分区和节点状态 |
squeue | 看队列里的作业 |
sbatch | 提交批处理脚本 |
srun | 直接运行一个任务(交互式或脚本内启动) |
scancel | 取消作业 |
sacct | 查作业的历史记录和资源用量 |
GPU 怎么申请
Slurm 把 GPU 当作一种通用资源(GRES),用 --gres=gpu:N 或 --gpus=N 申请。我在学校 HPC 上提交训练作业就是这么写的(完整脚本见 学校 HPC 使用指南):
#!/bin/bash
#SBATCH -J pytorch # 作业名
#SBATCH -p gpu # 提交到 GPU 分区
#SBATCH -N 1 # 1 个节点
#SBATCH -n 32 # 32 个 CPU 核
#SBATCH --gres=gpu:4 # 4 张 GPU
torchrun --standalone --nproc_per_node=4 train.py
几个和本章相关的点:
- 登录节点只用来提交,训练必须由 Slurm 分配到计算节点上跑;
- 分到的计算节点是干净的 shell,环境变量、conda 环境都要在脚本里重新加载;
--nproc_per_node必须和申请的 GPU 数一致,否则要么有卡闲着,要么进程抢不到卡;- 多机作业用
-N申请多个节点,Slurm 天然按"全部到位才开始"的方式分配,不需要额外的成组调度插件。
调度策略
- 优先级与公平分享(fair-share):最近用得多的用户,优先级会被调低;
- 回填(backfill):大作业在等资源时,如果有小作业能在它开始前跑完,就先让小作业用空出来的卡,提高利用率又不耽误大作业;
- 抢占:高优先级作业可以挂起或终止低优先级作业。
Kubernetes:云原生出身的编排
Kubernetes 本身的架构和资源管理在 CKA 合集 里讲,这里只讲 GPU 怎么接进 K8s。
Device Plugin
K8s 原生只认识 CPU 和内存,不认识 GPU。NVIDIA Device Plugin 以 DaemonSet 的形式在每个 GPU 节点上运行,向 kubelet 报告"这个节点有几张 GPU",GPU 就成了一种扩展资源 nvidia.com/gpu。Pod 在资源限制里申请:
apiVersion: v1
kind: Pod
metadata:
name: gpu-test
spec:
restartPolicy: Never
containers:
- name: cuda
image: nvcr.io/nvidia/pytorch:<版本>-py3
command: ["nvidia-smi"]
resources:
limits:
nvidia.com/gpu: 1 # 申请 1 张整卡
默认只能按整卡申请,不能申请半张卡。要共享一张卡,靠第 7 章的 MIG 或时间片。
GPU Operator
一个 GPU 节点要能跑 GPU Pod,得先装好驱动、Container Toolkit、Device Plugin,还要有监控。几百个节点手工装,版本很难统一。GPU Operator 把这些全部自动化,以容器的形式部署和升级:
| 组件 | 作用 |
|---|---|
| 驱动容器 | 在节点上安装 NVIDIA 驱动,不需要预先装进系统镜像 |
| Container Toolkit | 让容器运行时能使用 GPU |
| Device Plugin | 向 K8s 报告 GPU 资源 |
| GPU Feature Discovery | 给节点打标签:GPU 型号、显存大小、是否支持 MIG 等,方便按型号调度 |
| DCGM Exporter | 导出 GPU 监控指标给 Prometheus(第 7 章) |
| MIG Manager | 按配置自动切分 MIG |
网络这一侧有对应的 Network Operator,负责 RDMA 网卡的驱动和配置,让 Pod 能用上 InfiniBand 或 RoCE。
K8s 调度 AI 作业的短板
K8s 默认调度器是为无状态的在线服务设计的,一个一个 Pod 地调度,缺两样 AI 训练需要的东西:成组调度,以及多团队之间的队列和配额。常见的补法是换或加调度器:
- KAI Scheduler:NVIDIA 从 Run:ai 平台里拆出来、2025 年开源的调度器,支持成组调度、GPU 分片共享、分层队列;
- Volcano、Kueue:社区的批处理调度和作业排队方案。
Run:ai 是 NVIDIA 在 2024 年收购的 GPU 编排平台,建立在 K8s 之上,提供 GPU 资源池、按团队的配额和公平调度、分数 GPU 分配,以及资源使用的可视化。
Slurm 还是 Kubernetes
| Slurm | Kubernetes | |
|---|---|---|
| 出身 | 超算、HPC | 云原生、微服务 |
| 擅长 | 批处理训练、多机大作业 | 在线服务、推理、弹性扩缩 |
| 多机训练 | 原生支持全部到位再开始 | 需要额外调度器 |
| 容器 | 需要 Enroot + Pyxis | 原生 |
| 使用方式 | 写脚本、命令行提交 | 写 YAML、声明式 |
| 典型用户 | 研究人员、训练团队 | 平台工程、MLOps 团队 |
很多组织两套都有:训练集群用 Slurm,推理和平台服务用 Kubernetes。
集群管理:BCM 与 Mission Control
调度系统管的是"作业用哪几张卡"。再往下一层,还有人要管"这些节点本身":装系统、配网络、统一驱动版本、监控硬件健康、坏了的节点下线。这是集群管理软件的工作。
NVIDIA Base Command Manager(BCM),前身是 Bright Cluster Manager(NVIDIA 2022 年收购 Bright Computing):
- 裸机部署:从管理节点通过网络启动给计算节点装系统,所有节点用统一的镜像;
- 配置管理:驱动、软件、网络配置统一下发;
- 部署调度系统:一键搭好 Slurm 或 Kubernetes;
- 监控与健康检查:收集节点和 GPU 的指标,发现故障节点。
NVIDIA Mission Control 是更上层的"AI 工厂"运维软件,包含 BCM 的全部能力,再加上 Slurm 或 Run:ai 的作业调度,以及硬件故障的自动检测和恢复,主要面向 DGX SuperPOD 这类大规模集群。
另外还有 Base Command Platform,是 NVIDIA 托管的 SaaS 平台,用来在 DGX Cloud 上提交和管理 AI 作业。
不用 BCM 的话,NVIDIA 还有一个开源项目 DeepOps:一组 Ansible playbook,用来部署带 Slurm 或 Kubernetes 的 GPU 集群。思路和 GPU 服务器管理 合集里用 Ansible 管实验室服务器一样。
分层来看:
| 层 | 管什么 | 代表 |
|---|---|---|
| 集群管理 | 节点的系统、配置、健康 | BCM |
| 作业调度 | 作业用哪些资源、什么时候跑 | Slurm、Kubernetes + KAI、Run:ai |
| 全栈运维 | 以上全部,加自动故障恢复 | Mission Control |
MLOps(模型的版本管理、实验追踪、自动化流水线)建立在调度层之上,见第 2 章。
速查
| 词 | 一句话 |
|---|---|
| 成组调度 | 分布式作业的所有资源同时到位才开始 |
| Slurm | HPC 出身的批处理调度器,2025 年起属于 NVIDIA,仍开源 |
| slurmctld / slurmd / slurmdbd | 控制中心 / 节点守护进程 / 记账数据库 |
| GRES | Slurm 的通用资源,GPU 用 --gres=gpu:N 申请 |
| backfill | 小作业填进大作业等待的空档 |
| Enroot + Pyxis | 让 Slurm 跑容器 |
| Device Plugin | 让 K8s 认识 GPU(nvidia.com/gpu) |
| GPU Operator | 在 K8s 里自动部署驱动、Toolkit、Device Plugin、DCGM Exporter 等 |
| Network Operator | 在 K8s 里管理 RDMA 网卡 |
| KAI Scheduler | 从 Run:ai 开源出来的 K8s AI 调度器 |
| Run:ai | K8s 上的 GPU 资源池与配额管理平台 |
| BCM | 集群管理:装系统、统一配置、部署调度器、监控 |
| Mission Control | BCM + 调度 + 自动故障恢复的全栈运维软件 |