CentOS Stream 9 Slurm 集群部署指南(单节点 / 多节点)

本文提供 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
# gpu01
hostnamectl set-hostname gpu01

# login
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
# gpu01 上执行
/usr/sbin/create-munge-key

2. 分发 key 到所有计算节点

1
2
# gpu01 上执行,把 key 拷贝到 login
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/munge
chmod 400 /etc/munge/munge.key
systemctl enable --now munge

4. 验证 munge

1
2
# 每个节点都执行
munge -n | unmunge

正常应看到:

1
STATUS:          Success (0)

五、创建 Slurm 用户与目录

所有节点执行:

1
2
3
4
useradd -r -s /sbin/nologin slurm
mkdir -p /var/spool/slurm/{ctld,d}
mkdir -p /var/log/slurm
chown -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
# gpu01 上执行
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 服务

启动顺序

  1. munge(已启动)
  2. slurmctld(仅控制节点)
  3. slurmd(所有计算节点)
1
2
3
4
5
# gpu01(控制节点)
systemctl enable --now slurmctld slurmd

# login(纯计算节点)
systemctl enable --now slurmd

十、验证 Slurm 状态

1. 查看节点和分区

1
sinfo

期望输出:

1
2
3
4
PARTITION     AVAIL  TIMELIMIT  NODES  STATE NODELIST
debug* up 3:00:00 1 idle gpu01
N56_128G_V100 up 1-00:00:00 1 idle gpu01
N56_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
sinfo -o "%N %G %D %t"

输出示例:

1
2
3
NODELIST  GRES         NODES STATE
gpu01 gpu:V100:8 1 idle
login (null) 1 idle

十一、提交测试任务

1. 交互式任务

1
srun -N 1 -n 1 hostname

2. 批处理任务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
cat > test.sh <<'EOF'
#!/bin/bash
#SBATCH -J test
#SBATCH -p debug
#SBATCH -N 1
#SBATCH -n 1
#SBATCH -o logs/%x_%j.out

hostname
sleep 10
EOF

mkdir -p logs
sbatch test.sh

查看任务:

1
squeue

十二、GPU 配置(8 × V100 示例)

1. 确认 GPU 设备

1
ls -l /dev/nvidia*

输出示例:

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 # 应只看到 1 张 V100

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'
#!/bin/bash
#SBATCH -J gpu_v100_1
#SBATCH -p debug
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=1
#SBATCH --gres=gpu:V100:1
#SBATCH -t 00:10:00

set -euo pipefail
mkdir -p logs

echo "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

# 关键验证:在作业内应该只看到 1 张 V100(受 ConstrainDevices 限制)
command -v nvidia-smi >/dev/null 2>&1 || { echo "nvidia-smi not found"; exit 1; }
nvidia-smi

echo "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'
#!/bin/bash
#SBATCH -J hybrid_gpu2_cpu
#SBATCH -p N56_128G_V100
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=4
#SBATCH --gres=gpu:V100:1
#SBATCH -t 02:00:00

set -euo pipefail
mkdir -p logs

echo "Host: $(hostname)"
echo "JobID: $SLURM_JOB_ID"
echo "CPUs: $SLURM_CPUS_PER_TASK"
echo "GRES: ${SLURM_JOB_GRES:-N/A}"

# 限制线程类库只用分配到的 CPU,避免超用
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-smi

echo "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'
#!/bin/bash

module load warpx/latest
source activate warpx

# 走 pmix MPI,与 slurm.conf MpiDefault=pmix 一致
srun --mpi=pmix --gres=gpu:V100:1 -c 1 --mem=1G python input.py
EOF

6. 在纯 CPU 节点运行任务

1
2
# login 节点无 GPU,提交到 N56_128G 分区
srun -p N56_128G -N 1 -c 8 --mem=16G --pty bash

十四、GPU 隔离验证

验证 GPU 不可见(普通用户直接 SSH)

1
2
3
# 普通用户直接运行
nvidia-smi
# 预期:Failed to initialize NVML: Unknown Error

如果普通用户能直接看到 GPU,说明 cgroup DevicePolicy=closed 未生效,参考 Linux cgroup 实现 SSH 用户资源与 GPU 访问限制

验证 GPU 通过 Slurm 可用

1
2
srun --gres=gpu:V100:1 --mem=1G nvidia-smi
# 预期:正常显示 GPU 信息(仅显示分配到的 GPU)

十五、常见 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 输出完全一致:

1
2
hostname
# 输出必须与 slurm.conf 中 NodeName 相同

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'
#!/bin/bash
#SBATCH -J cpu_full
#SBATCH -p debug
#SBATCH -N 1
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=56
#SBATCH --mem=8G
#SBATCH -t 00:10:00
#SBATCH -o logs/%x_%j.out

set -euo pipefail
mkdir -p logs

echo "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'
#!/bin/bash
#SBATCH -J cpu_stress
#SBATCH -N 1
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=56
#SBATCH --time=00:10:00
#SBATCH -o cpu_stress_%j.out

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 bashnproc 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
# sync-slurm-config.sh
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 slurmd
done

systemctl restart slurmctld slurmd

十九、slurmdbd 需求分析

场景 是否需要
单机/小集群测试
作业计费/统计
多用户审计

当前生产集群未启用 slurmdbd。如需配置,需额外安装 MariaDB 并创建 slurm 会计数据库。

总结

生产 Slurm 集群的关键约束:

  1. 所有节点配置一致slurm.confcgroup.conf 必须完全同步
  2. Munge key 统一:所有节点使用同一份 /etc/munge/munge.key
  3. GPU 正确声明gres.conf 中的 NodeNameType 必须与 slurm.conf 一致
  4. 设备隔离ConstrainDevices=yes 确保作业间 GPU 隔离
  5. 分区合理规划:按硬件规格命名分区,用户无需记忆节点名
  6. 时间限制:debug 分区设短时限,避免资源被开发任务长时间占用

配合 Linux cgroup SSH 限制WarpX 安装指南 即可形成完整的 HPC 环境。


CentOS Stream 9 Slurm 集群部署指南(单节点 / 多节点)
https://zhazhajust.github.io/2026/06/25/slurm-server/
作者
JayZz
发布于
2026年6月25日
许可协议