本文提供 CentOS Stream 9 环境下安装配置 Slurm 的完整流程,覆盖单节点测试和多节点生产两种场景。示例以当前生产集群(gpu01 + login 双节点)为蓝本。
一、环境假设与目标架构 单节点(开发/测试)
项
值
控制节点 + 计算节点
node1
IP
127.0.0.1(本地)
多节点(生产)
项
值
控制节点 + 计算节点
gpu01(192.168.100.2)
纯计算节点
login
GPU
gpu01: 8 × V100,login: 无
认证
munge(所有节点共享同一 key)
二、系统基础准备 1. 设置主机名与 hosts 所有节点 执行:
1 2 3 4 5 hostnamectl set-hostname gpu01 hostnamectl set-hostname login
在每个节点 的 /etc/hosts 中加入其他节点的 IP:
1 2 3 4 cat >> /etc/hosts <<EOF 192.168.100.2 gpu01 # login 节点 IP 按实际填写 EOF
2. 关闭防火墙(测试环境建议) 1 systemctl disable --now firewalld
3. 关闭 SELinux(测试环境建议) 1 2 sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config setenforce 0
三、安装 Slurm 及依赖 所有节点 执行:
1 2 dnf install -y epel-release dnf install -y slurm slurm-slurmd slurm-slurmctld munge
slurm-slurmctld:控制守护进程,仅在控制节点上启动
slurm-slurmd:计算守护进程,所有节点上启动
munge:认证服务,所有节点都需要
四、配置 Munge(Slurm 认证核心) Munge 是 Slurm 节点间认证的基础。多节点集群的关键约束:所有节点必须使用同一份 /etc/munge/munge.key 。
1. 在控制节点生成 munge key 1 2 /usr/sbin/create-munge-key
2. 分发 key 到所有计算节点 1 2 scp -p /etc/munge/munge.key root@login:/etc/munge/
3. 在所有节点设置权限并启动 1 2 3 4 chown -R munge:munge /etc/munge /var/lib/munge /var/log/mungechmod 400 /etc/munge/munge.key systemctl enable --now munge
4. 验证 munge
正常应看到:
五、创建 Slurm 用户与目录 所有节点 执行:
1 2 3 4 useradd -r -s /sbin/nologin slurmmkdir -p /var/spool/slurm/{ctld,d}mkdir -p /var/log/slurmchown -R slurm:slurm /var/spool/slurm /var/log/slurm
六、配置 slurm.conf(核心) 配置文件位于 /etc/slurm/slurm.conf,所有节点内容必须一致 (可通过 scp 从控制节点分发)。
生产环境双节点示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 ############################ # 基本集群信息 ############################ ClusterName=single_cluster SlurmctldHost=gpu01(192.168.100.2) SlurmUser=slurm SlurmdUser=root ############################ # 端口 ############################ SlurmctldPort=6817 SlurmdPort=6818 ############################ # 状态与日志 ############################ StateSaveLocation=/var/spool/slurm/ctld SlurmdSpoolDir=/var/spool/slurm/d SlurmctldLogFile=/var/log/slurm/slurmctld.log SlurmdLogFile=/var/log/slurm/slurmd.log ############################ # 认证 ############################ AuthType=auth/munge CryptoType=crypto/munge ############################ # 调度器 ############################ SchedulerType=sched/backfill SchedulerParameters=bf_continue,bf_interval=30 ############################ # 资源选择(关键) ############################ SelectType=select/cons_res SelectTypeParameters=CR_Core_Memory DefMemPerCPU=2048 ############################ # cgroup(生产必开) ############################ ProctrackType=proctrack/cgroup TaskPlugin=task/cgroup JobAcctGatherType=jobacct_gather/cgroup ############################ # 进程跟踪 / 清理 ############################ KillOnBadExit=1 ReturnToService=2 ############################ # 超时 ############################ SlurmctldTimeout=300 SlurmdTimeout=300 ############################ # MPI 默认 ############################ MpiDefault=pmix ############################ # 节点定义(按真实资源) ############################ NodeName=login \ CPUs=56 \ RealMemory=127875 \ Sockets=2 \ CoresPerSocket=28 \ ThreadsPerCore=1 \ State=UNKNOWN NodeName=gpu01 \ CPUs=56 \ RealMemory=128027 \ Sockets=2 \ CoresPerSocket=28 \ ThreadsPerCore=1 \ Gres=gpu:V100:8 \ State=UNKNOWN GresTypes=gpu ############################ # 分区定义 ############################ PartitionName=debug \ Nodes=gpu01 \ Default=YES \ MaxTime=3:00:00 \ State=UP PartitionName=N56_128G_V100 \ Nodes=gpu01 \ MaxTime=1-00:00:00 \ State=UP PartitionName=N56_128G \ Nodes=login \ MaxTime=1-00:00:00 \ State=UP
关键参数说明
参数
说明
SlurmctldHost=gpu01(192.168.100.2)
控制节点地址。不写 IP 则依赖 DNS/hosts
SelectTypeParameters=CR_Core_Memory
按 Core + Memory 调度资源
DefMemPerCPU=2048
未指定 --mem 时,作业默认每核申请 2GB 内存
Gres=gpu:V100:8
声明节点上的 GPU 资源
GresTypes=gpu
激活 GPU 通用资源类型
单节点测试简化配置 如果只需要单机测试,将上面的配置改为:
1 2 3 4 5 6 7 8 SlurmctldHost=node1(127.0.0.1) # 只定义一个节点 NodeName=node1 CPUs=56 RealMemory=128027 Sockets=2 CoresPerSocket=28 ThreadsPerCore=1 Gres=gpu:V100:8 State=UNKNOWN # 分区都指向同一节点 PartitionName=debug Nodes=node1 Default=YES MaxTime=3:00:00 State=UP PartitionName=normal Nodes=node1 MaxTime=1-00:00:00 State=UP
同步配置到所有节点 1 2 3 4 scp /etc/slurm/slurm.conf root@login:/etc/slurm/slurm.conf scp /etc/slurm/cgroup.conf root@login:/etc/slurm/cgroup.conf scp /etc/slurm/gres.conf root@login:/etc/slurm/gres.conf
七、配置 cgroup.conf /etc/slurm/cgroup.conf,所有节点一致:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ### # # Slurm cgroup support configuration file # # See man slurm.conf and man cgroup.conf for further # information on cgroup configuration parameters #-- CgroupMountpoint=/sys/fs/cgroup CgroupAutomount=yes ConstrainCores=yes ConstrainRAMSpace=yes ConstrainSwapSpace=yes ConstrainDevices=yes AllowedRAMSpace=100 AllowedSwapSpace=0 MaxRAMPercent=98 MaxSwapPercent=0 MinRAMSpace=30
关键 :ConstrainDevices=yes 启用 GPU 设备隔离,配合下文 gres.conf 使作业只能看到分配给它的 GPU。
八、配置 gres.conf(GPU 资源) /etc/slurm/gres.conf,仅在 GPU 节点上需要(login 节点无 GPU 可跳过):
1 NodeName=gpu01 Name=gpu Type=V100 File=/dev/nvidia[0-7]
要点:
Type=V100 用于匹配 --gres=gpu:V100:x
File=/dev/nvidia[0-7] 绑定全部 8 张 V100(范围语法)
NodeName 必须与 slurm.conf 完全一致
九、启动 Slurm 服务 启动顺序
munge (已启动)
slurmctld (仅控制节点)
slurmd (所有计算节点)
1 2 3 4 5 systemctl enable --now slurmctld slurmd systemctl enable --now slurmd
十、验证 Slurm 状态 1. 查看节点和分区
期望输出:
1 2 3 4 PARTITION AVAIL TIMELIMIT NODES STATE NODELISTdebug * up 3 :00 :00 1 idle gpu01N56_128G_V100 up 1 -00 :00 :00 1 idle gpu01N56_128G up 1 -00 :00 :00 1 idle login
2. 查看节点详情 1 2 scontrol show node gpu01 scontrol show node login
gpu01 应包含 Gres=gpu:V100:8。
3. 查看 GPU 资源视图
输出示例:
1 2 3 NODELIST GRES NODES STATEgpu01 gpu:V100:8 1 idlelogin (null) 1 idle
十一、提交测试任务 1. 交互式任务
2. 批处理任务 1 2 3 4 5 6 7 8 9 10 11 12 13 14 cat > test.sh <<'EOF' hostnamesleep 10 EOFmkdir -p logs sbatch test.sh
查看任务:
十二、GPU 配置(8 × V100 示例) 1. 确认 GPU 设备
输出示例:
1 2 3 /dev/nvidia0 ... /dev/nvidia7 /dev/nvidiactl /dev/nvidia-uvm
2. 查看 GPU 资源 1 scontrol show node gpu01 | grep Gres
输出:
1 2 Gres =gpu:V100:8 GresUsed =0
十三、GPU 作业示例 1. 单 GPU 交互式 1 2 srun --gres=gpu:V100:1 --pty bash nvidia-smi
2. 单 GPU 批处理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 cat > gpu_v100_1.sh <<'EOF' set -euo pipefailmkdir -p logsecho "Host: $(hostname) " echo "JobID: $SLURM_JOB_ID " echo "CPUs: $SLURM_CPUS_PER_TASK " echo "GRES: ${SLURM_JOB_GRES:-N/A} " echo "CUDA_VISIBLE_DEVICES: ${CUDA_VISIBLE_DEVICES:-N/A} " date command -v nvidia-smi >/dev/null 2>&1 || { echo "nvidia-smi not found" ; exit 1; } nvidia-smiecho "GPU V100-1 job completed." EOF sbatch gpu_v100_1.sh
3. 多 GPU 任务 1 srun --gres=gpu:V100:2 --pty bash
4. Hybrid GPU+CPU:绑定线程库 GPU 任务通常也要消耗 CPU 做数据预处理/IO。关键原则 :线程类库必须限制为分配到的 CPU 数,否则会默认用满所有 CPU。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 cat > hybrid_gpu2_cpu.sh <<'EOF' set -euo pipefailmkdir -p logsecho "Host: $(hostname) " echo "JobID: $SLURM_JOB_ID " echo "CPUs: $SLURM_CPUS_PER_TASK " echo "GRES: ${SLURM_JOB_GRES:-N/A} " export OMP_NUM_THREADS="${SLURM_CPUS_PER_TASK} " export MKL_NUM_THREADS="${SLURM_CPUS_PER_TASK} " export OPENBLAS_NUM_THREADS="${SLURM_CPUS_PER_TASK} " export NUMEXPR_NUM_THREADS="${SLURM_CPUS_PER_TASK} " nvidia-smiecho "Hybrid GPU-CPU job completed." EOF sbatch hybrid_gpu2_cpu.sh
5. 用 srun 启动 WarpX(pmix MPI) 1 2 3 4 5 6 7 8 9 cat > srun_warpx.sh <<'EOF' module load warpx/latestsource activate warpx srun --mpi=pmix --gres=gpu:V100:1 -c 1 --mem=1G python input.py EOF
6. 在纯 CPU 节点运行任务 1 2 srun -p N56_128G -N 1 -c 8 --mem=16G --pty bash
十四、GPU 隔离验证 验证 GPU 不可见(普通用户直接 SSH)
如果普通用户能直接看到 GPU,说明 cgroup DevicePolicy=closed 未生效,参考 Linux cgroup 实现 SSH 用户资源与 GPU 访问限制 。
验证 GPU 通过 Slurm 可用 1 2 srun --gres=gpu:V100:1 --mem=1G nvidia-smi
十五、常见 GPU 问题 ❌ 作业内能看到所有 GPU 原因 :
ConstrainDevices=no
未使用 task/cgroup
修复 :
1 2 ConstrainDevices=yes TaskPlugin=task/cgroup
❌ 提交 GPU 作业一直排队 1 2 squeue scontrol show job <jobid>
常见原因 :
GPU 已被全部占用
请求的 GPU 类型错误(如写成 A100 而集群只有 V100)
❌ GPU 规格指定差异
写法
行为
--gres=gpu:1
使用任意类型 GPU(不推荐)
--gres=gpu:V100:1
仅使用 V100
生产环境建议始终指定 GPU 类型。
十六、常见运维问题 1. 节点状态为 DOWN 1 scontrol update NodeName=<node> State=RESUME
2. 查看日志 1 2 3 4 5 journalctl -u slurmctld -f journalctl -u slurmd -f
3. Munge 认证失败
确认所有节点使用同一份 /etc/munge/munge.key
文件权限必须是 400,属主 munge:munge
各节点的系统时间要一致(timedatectl 检查)
4. 节点名不匹配 NodeName 必须与 hostname 输出完全一致:
5. 配置变更后重启 1 2 3 4 5 systemctl restart slurmctld slurmd systemctl restart slurmd
十七、CPU/资源压力测试脚本 1. sbatch 跑满 CPU(用 yes 循环) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 cat > cpu_full.sh <<'EOF' set -euo pipefailmkdir -p logsecho "Host: $(hostname) " echo "JobID: $SLURM_JOB_ID " echo "CPUs: $SLURM_CPUS_PER_TASK " date for ((i=0 ; i<SLURM_CPUS_PER_TASK; i++)); do yes > /dev/null &done wait EOF sbatch cpu_full.sh
2. 用 stress-ng 精确压测 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 cat > cpu_stress.sh <<'EOF' echo "Job started on $(hostname) " echo "Allocated CPUs: $SLURM_CPUS_PER_TASK " echo "Start time: $(date) " stress-ng --cpu "$SLURM_CPUS_PER_TASK " --cpu-method all --timeout 600s --metrics-brief EOF
3. 验证清单
验证项
命令
预期
节点状态
sinfo
所有节点 idle
分区列表
sinfo -o "%P %N %G %t"
3 个分区 UP
srun 分配 CPU
srun -N1 -n1 -c 56 --pty bash 内 nproc
56
CPU 绑定
作业内 taskset -cp $$
与分配的 CPU 一致
GPU 隔离
srun --gres=gpu:V100:1 nvidia-smi
只看到 1 张卡
GPU 排队
srun --gres=gpu:V100:9 nvidia-smi
排队(因为总共只有 8 张)
十八、生产环境建议 1. 资源默认值 1 DefMemPerCPU=2048 # 未指定 --mem 时每核 2GB
为什么需要 :未配置时,不指定 --mem 的作业默认会申请节点的全部剩余内存,导致后续作业因内存不足而排队。
2. GPU 访问控制 通过 systemd 的 DevicePolicy=closed 阻止普通用户直连 GPU,同时不影响 Slurm 作业。详细配置见 Linux cgroup 实现 SSH 用户资源与 GPU 访问限制 。
Slurm 侧前提:
1 2 # /etc/slurm/cgroup.conf ConstrainDevices=yes
3. 分区策略
分区
节点
用途
debug
gpu01
开发调试,3 小时限制,默认分区
N56_128G_V100
gpu01
GPU 生产任务,1 天限制
N56_128G
login
CPU 生产任务,1 天限制
分区命名含硬件规格(56 核/128G/是否含 V100),用户一目了然。
4. 配置同步 多节点集群中,修改配置文件后务必同步到所有节点。可在控制节点维护一个同步脚本:
1 2 3 4 5 6 7 8 9 10 11 12 #!/bin/bash NODES="login" for node in $NODES ; do scp /etc/slurm/slurm.conf root@$node :/etc/slurm/ scp /etc/slurm/cgroup.conf root@$node :/etc/slurm/ scp /etc/slurm/gres.conf root@$node :/etc/slurm/ ssh root@$node systemctl restart slurmddone systemctl restart slurmctld slurmd
十九、slurmdbd 需求分析
场景
是否需要
单机/小集群测试
否
作业计费/统计
是
多用户审计
是
当前生产集群未启用 slurmdbd。如需配置,需额外安装 MariaDB 并创建 slurm 会计数据库。
总结 生产 Slurm 集群的关键约束:
所有节点配置一致 :slurm.conf、cgroup.conf 必须完全同步
Munge key 统一 :所有节点使用同一份 /etc/munge/munge.key
GPU 正确声明 :gres.conf 中的 NodeName 和 Type 必须与 slurm.conf 一致
设备隔离 :ConstrainDevices=yes 确保作业间 GPU 隔离
分区合理规划 :按硬件规格命名分区,用户无需记忆节点名
时间限制 :debug 分区设短时限,避免资源被开发任务长时间占用
配合 Linux cgroup SSH 限制 和 WarpX 安装指南 即可形成完整的 HPC 环境。