SOP:Slurm 日志分离 + MpiDefault 配置¶
变更日期:2026-09-12|执行方式:真实集群实施(非模拟) 集群:Slurm 26.05.2(k8s-master-01 + k8s-node-01/02/03,configless 模式) 变更窗口:队列空载窗口(slurmdbd → slurmctld → slurmd 逐级重启) 结果:成功(终检全绿,端到端作业验证通过)
一、背景¶
1.1 变更前状态(实测取证)¶
# scontrol show config
SlurmctldLogFile = (null) ← 未指定日志文件
SlurmdLogFile = (null)
SlurmctldSyslogDebug = (null)
SlurmdSyslogDebug = (null)
MpiDefault = (null) ← 未配置
# slurmdbd.conf 中无任何日志相关配置
后果:
1. Slurm 日志全部混入 syslog/journald,与系统日志、LSF 日志、kube 组件日志交织,排障检索困难
2. 日志随 journald 的 SystemMaxUse 策略被整体轮转/清理,无法长期留存 Slurm 审计线索
3. MpiDefault 未配置,用户运行 MPI 作业缺少明确的默认启动方式
1.2 变更目标¶
| 编号 | 目标 | 验收标准 |
|---|---|---|
| G1 | Slurm 日志独立落盘 | /var/log/slurm/{slurmctld,slurmd,slurmdbd}.log 有完整日志 |
| G2 | 不再向 syslog/journald 写 Slurm 日志 | journald 中 Slurm 自身日志行数 = 0 |
| G3 | 日志可控轮转,避免无限增长 | logrotate 配置生效(weekly / 50M / 保留 8 份) |
| G4 | 配置 MpiDefault |
scontrol show config 显示 MpiDefault = pmi2 |
二、前置条件¶
| 项 | 要求 | 本集群实测 |
|---|---|---|
| 队列为空 | 重启 slurmd 会因 KillMode=control-group 连坐清杀节点作业 |
✅ 作业数=0 |
| 日志目录存在且属主正确 | /var/log/slurm 属主 slurm:slurm |
✅ 四节点均存在 |
| 磁盘空间 | 日志需独立空间 | ✅ 控制节点 29G 可用;计算节点 71~76G |
| SELinux | 不应阻止写入 | ✅ Disabled |
| 配置备份 | 必须可回滚 | ✅ 见第三章 |
| 时钟同步 | munge 依赖 | ✅ chronyd active,亚毫秒偏差 |
三、备份(变更前置,必须执行)¶
# 控制节点 k8s-master-01
cd /usr/local/slurm/etc
cp -a slurm.conf "slurm.conf.bak.$(date +%Y%m%d)"
cp -a slurmdbd.conf "slurmdbd.conf.bak.$(date +%Y%m%d)"
# 校验备份与源文件一致
md5sum slurm.conf slurm.conf.bak.$(date +%Y%m%d) \
slurmdbd.conf slurmdbd.conf.bak.$(date +%Y%m%d)
本次实际备份结果:
1cdcc770022d0d65f49d42a565e443de slurm.conf (6593 B)
1cdcc770022d0d65f49d42a565e443de slurm.conf.bak.20260912
de4d6b3a813945c185bdaab54ab2d251 slurmdbd.conf (259 B)
de4d6b3a813945c185bdaab54ab2d251 slurmdbd.conf.bak.20260912
四、变更清单(精确到参数与值)¶
4.1 /usr/local/slurm/etc/slurm.conf(控制节点,configless 会下发给计算节点)¶
在 # --- 日志级别 --- 段(SlurmdDebug=info 之后)插入:
# --- 日志文件(2026-09-12 新增:日志独立落盘,不再写 syslog)---
SlurmctldLogFile=/var/log/slurm/slurmctld.log
SlurmdLogFile=/var/log/slurm/slurmd.log
SlurmctldSyslogDebug=quiet
SlurmdSyslogDebug=quiet
在 --- 进程跟踪与任务插件 --- 段(TaskPlugin= 之后)插入:
# --- MPI 默认类型(2026-09-12 新增)---
# Slurm 侧编译支持的类型:none / cray_shasta / pmi2(未编译 pmix)
MpiDefault=pmi2
参数取值依据(重要):
SlurmctldSyslogDebug/SlurmdSyslogDebug的合法值为quiet | fatal | error | info | verbose | debug | debug2..debug5,没有none。 要实现"完全不写 syslog",正确值是quiet(Log nothing)——依据man slurm.conf。
4.2 /usr/local/slurm/etc/slurmdbd.conf(控制节点)¶
追加:
# --- 日志独立落盘(2026-09-12 新增)---
DebugLevel=info
LogFile=/var/log/slurm/slurmdbd.log
DebugLevelSyslog=quiet
参数名易错点(重要):slurmdbd.conf 用的是
DebugLevelSyslog, 与 slurm.conf 的SlurmctldSyslogDebug不是同一个名字; 写成SyslogLevel属于非法参数。同样没有none值,用quiet。 修改后必须保持600 slurm:slurm(文件含数据库明文口令)。
4.3 /etc/logrotate.d/slurm(四个节点:控制 + 三计算)¶
# Slurm 日志轮转(2026-09-12 新增)
# 说明:Slurm 不会在收到信号后重新打开日志文件,因此必须使用 copytruncate
# (先复制再截断原文件),进程继续写同一 inode,无需重启服务。
/var/log/slurm/slurmctld.log
/var/log/slurm/slurmdbd.log
/var/log/slurm/slurmd.log
{
weekly
size 50M
rotate 8
copytruncate
compress
delaycompress
missingok
notifempty
nodateext
}
为什么必须用
copytruncate:Slurm 不支持"收到信号后重新打开日志文件", 若用传统create模式(重命名旧文件+新建),Slurm 仍会继续写已被重命名的旧 inode, 导致新日志文件始终为空、旧文件持续增长。
4.4 systemd drop-in(拦截 stdout 通道,关键补充)¶
问题:slurmctld -D -s 中的 -D 语义是 "Run daemon in foreground, with logging copied to stdout"。
日志虽已写入 SlurmctldLogFile,但仍被复制到 stdout,而 systemd 默认 StandardOutput=journal
会把 stdout 收进 journald —— 于是 journald 中仍有 Slurm 日志副本。
实测证据:journalctl -o verbose 显示 _TRANSPORT=syslog 0 条(说明 quiet 已生效),
但 _TRANSPORT=stdout 38 条(stdout 通道残留)。
方案:用 systemd drop-in 丢弃 stdout 副本(不改原 unit,便于回滚):
# 控制节点
for u in slurmctld slurmdbd; do
mkdir -p /etc/systemd/system/${u}.service.d
cat > /etc/systemd/system/${u}.service.d/10-logfile-only.conf <<'EOF'
# 2026-09-12 日志分离:Slurm 以 -D 运行时会把日志复制到 stdout,
# 而 systemd 默认把 stdout 收进 journald,导致日志在 journal 中仍有副本。
# 日志已完整写入 SlurmctldLogFile/LogFile,故此处丢弃 stdout 副本。
[Service]
StandardOutput=null
EOF
done
systemctl daemon-reload
# 计算节点(三台各执行)
mkdir -p /etc/systemd/system/slurmd.service.d
cat > /etc/systemd/system/slurmd.service.d/10-logfile-only.conf <<'EOF'
# 2026-09-12 日志分离:丢弃 -D 产生的 stdout 副本(日志已写入 SlurmdLogFile)
[Service]
StandardOutput=null
EOF
systemctl daemon-reload
保留的排障通道:
StandardError未改动(仍进 journald), 因此服务启动阶段的 stderr 错误仍可在journalctl中看到,兼顾"日志分离"与"启动可排障"。
五、分步操作(执行顺序)¶
# Step 0 安全门禁:队列必须为空
export PATH=/usr/local/slurm/bin:$PATH
[ "$(squeue -h -o '%i' | wc -l)" -eq 0 ] || { echo "队列非空,中止"; exit 1; }
# Step 1 备份(见第三章)
# Step 2 预创建日志文件(权限按运行身份)
touch /var/log/slurm/slurmctld.log
chown slurm:slurm /var/log/slurm/slurmctld.log && chmod 640 /var/log/slurm/slurmctld.log
# slurmdbd.log 已存在(slurm:slurm 600),沿用
# slurmd.log 由 slurmd(root)首次启动时自动创建
# Step 3 改 slurm.conf / slurmdbd.conf(见第四章)
# Step 4 部署 logrotate(四节点)
# Step 5 部署 drop-in 并 daemon-reload(四节点)
# Step 6 重启服务(顺序不可颠倒)
systemctl restart slurmdbd && sleep 8
systemctl restart slurmctld && sleep 12
for n in k8s-node-01 k8s-node-02 k8s-node-03; do
ssh "$n" "systemctl restart slurmd"
done
# Step 7 验证(见第六章)
为什么必须重启而不是
scontrol reconfigure:SlurmctldLogFile/SlurmdLogFile属于启动期参数,reconfigure不重建日志输出通道; 实测reconfigure可生效的是SlurmctldDebug(级别),而非日志目标。
六、验证(实测结果)¶
6.1 参数生效¶
MpiDefault = pmi2
SlurmctldLogFile = /var/log/slurm/slurmctld.log
SlurmctldSyslogDebug = quiet
SlurmdLogFile = /var/log/slurm/slurmd.log
SlurmdSyslogDebug = quiet
6.2 日志文件落盘(G1)¶
-rw-r----- 1 slurm slurm 2153 9月 12 12:25 /var/log/slurm/slurmctld.log
-rw------- 1 slurm slurm ... 9月 12 12:25 /var/log/slurm/slurmdbd.log
-rw------- 1 root root 2772 9月 12 12:27 /var/log/slurm/slurmd.log (三节点)
6.3 已脱离 syslog(G2)—— 核心验收项¶
# 通道统计(journalctl -o verbose)
_TRANSPORT=syslog 条数: 0 ← SlurmctldSyslogDebug=quiet 生效
_TRANSPORT=stdout 条数: 38 ← drop-in 部署前残留
# drop-in 生效后(12:27:44 起)
slurmctld 自身日志行数 = 0
slurmd 自身日志行数 = 0
slurmdbd 自身日志行数 = 0
判定方法说明:journald 同时接收 syslog API 与进程 stdout 两条通道;
用 _TRANSPORT 字段可精确区分,避免"日志还在 journald"的误判。
残留的历史行(12:25~12:27)属于 drop-in 生效之前的旧进程,非新增。
6.4 端到端作业验证¶
提交:sbatch -p compile -n2 --mem=2048M --wrap "hostname; echo E2E_OK" → JobId=438
结果:COMPLETED ExitCode=0:0 NodeList=k8s-node-01
journald 增量:slurmctld = 0 ;slurmd = 0 ← 日志完全未进 journal
文件日志(控制节点):
[2026-09-12T12:28:13.001] sched: Allocate JobId=438 NodeList=k8s-node-01 #CPUs=2 Partition=compile
[2026-09-12T12:28:14.339] _job_complete: JobId=438 WEXITSTATUS 0
[2026-09-12T12:28:14.340] _job_complete: JobId=438 done
文件日志(计算节点):
[2026-09-12T12:28:13.769] Launching batch JobId=438 SLUID=sDJHM29Y03K800 for UID 2001
[2026-09-12T12:28:13.981] [438.batch] task/cgroup: _memcg_initialize: job: alloc=2048MB mem.limit=3072MB
[2026-09-12T12:28:14.345] [438.batch] done with step
附带收益:slurmd 日志中的
alloc=2048MB mem.limit=3072MB第三次独立验证了cgroup.conf的AllowedRAMSpace=150%(2048 × 1.5 = 3072),与阶段 1/6 的结论一致。
6.5 logrotate 校验(G3)¶
$ logrotate -d /etc/logrotate.d/slurm
rotating pattern: /var/log/slurm/slurmctld.log
considering log /var/log/slurm/slurmdbd.log
log needs rotating ← 该文件 105MB > 50M,下次运行时将轮转压缩
considering log /var/log/slurm/slurmd.log
log does not exist -- skipping ← 计算节点首次运行前正常跳过
七、回滚步骤(完整、可直接执行)¶
# R1 恢复配置(控制节点)
cd /usr/local/slurm/etc
cp -a slurm.conf.bak.20260912 slurm.conf
cp -a slurmdbd.conf.bak.20260912 slurmdbd.conf
# 权限复位(备份为 cp -a,权限已保留;仍显式确认更稳)
chown slurm:slurm slurmdbd.conf && chmod 600 slurmdbd.conf
# R2 移除 logrotate(四节点)
rm -f /etc/logrotate.d/slurm
# R3 移除 drop-in(四节点)
rm -rf /etc/systemd/system/slurmctld.service.d \
/etc/systemd/system/slurmdbd.service.d
for n in k8s-node-01 k8s-node-02 k8s-node-03; do
ssh "$n" "rm -rf /etc/systemd/system/slurmd.service.d"
done
# R4 重载并重启(顺序同正向)
systemctl daemon-reload
systemctl restart slurmdbd; sleep 8
systemctl restart slurmctld; sleep 12
for n in k8s-node-01 k8s-node-02 k8s-node-03; do ssh "$n" "systemctl restart slurmd"; done
# R5 验证回滚
scontrol show config | grep -iE "^MpiDefault|^SlurmctldLogFile|^SlurmdLogFile"
# 期望:三项均回到 (null)
journalctl -u slurmctld --since "1 min ago" | tail # 日志重新出现于 journald
回滚无需删除日志文件:
/var/log/slurm/*.log保留不影响回滚后运行(不再被写入)。 如需彻底清理,确认服务已回滚后再删除。
八、风险说明¶
| 风险 | 等级 | 说明 | 缓解措施 |
|---|---|---|---|
| 重启 slurmd 导致节点作业被杀 | 高 | KillMode=control-group 会连坐清杀 cgroup 内全部进程(阶段 5 F2 已实测) |
强制"队列为空"门禁;生产建议先 DRAIN 等作业跑完 |
| 重启 slurmctld 中断调度 | 中 | 重启期间无法提交/调度 | 选低峰窗口;重启仅十余秒;StateSaveLocation 保证状态恢复 |
| 重启 slurmdbd 中断记账 | 低 | 调度不受影响,记账事件进 dbd.messages 缓冲,恢复后补传 |
观察 dbd.messages 是否清空 |
| 日志文件权限错 → 服务起不来 | 中 | Slurm 对日志文件不可写会 fatal | 预先创建并设定正确属主(slurm:slurm / root:root) |
| 参数值非法 → 服务无法启动 | 高 | 本次实际发生,见第九章 | 改配置前必须查 man 页确认取值;改后立即 systemctl restart 并观察 |
| 完全停写 journal 后降低可观测性 | 中 | journald 不再有 Slurm 日志,需改变排障习惯 | 保留 stderr→journal 通道;排障改用 /var/log/slurm/*.log |
| logrotate 配置错误 | 低 | 可能不轮转或误删日志 | 用 logrotate -d dry-run 校验后再启用 |
九、排错记录(本次实际踩坑,务必沉淀)¶
9.1 事故:SlurmctldSyslogDebug=none 非法 → slurmctld/slurmdbd 启动失败¶
现象:变更后执行 squeue 报错,slurmdbd 重启失败:
squeue: error: Invalid SlurmctldSyslogDebug none
squeue: fatal: Unable to process configuration file
systemctl restart slurmdbd → failed
根因:SlurmctldSyslogDebug 的合法取值不含 none。依据 man slurm.conf:
SlurmctldSyslogDebug
quiet Log nothing
fatal Log only fatal errors
error Log only errors
info / verbose / debug / debug2..debug5
影响:
- slurmctld 因配置 fatal,叠加 Restart=always 进入重启循环
- slurmdbd 同样解析 slurm.conf,直接 failed(其 unit 无 Restart)
- 整个集群调度不可用(约 1 分钟窗口)
修复:none → quiet(SlurmctldSyslogDebug / SlurmdSyslogDebug 各一处),重启后恢复。
教训:
1. Slurm 参数取值必须查 man 页,不能凭直觉用 none/off 之类的通用词
2. 变更后立即验证服务状态,不要连续执行多步后再统一验证(本次因 set -e 在 systemctl is-active 返回非 0 时中断,反而缩短了故障暴露时间)
3. 单点集群改 slurm.conf 属高危操作,应先在测试配置上验证语法;slurm.conf 建议用 slurmctld -f <file> 之类做预检(本版本无 -t,可先在备用路径放置配置并临时启动验证)
9.2 事故:slurmdbd.conf 参数名写错(SyslogLevel vs DebugLevelSyslog)¶
现象:slurmdbd 即使修好 slurm.conf 后仍 failed。
根因:slurmdbd.conf 与 slurm.conf 的日志参数命名体系不同:
| 用途 | slurm.conf | slurmdbd.conf |
|---|---|---|
| 日志级别(文件) | SlurmctldDebug / SlurmdDebug |
DebugLevel |
| 日志级别(syslog) | SlurmctldSyslogDebug / SlurmdSyslogDebug |
DebugLevelSyslog |
| 日志文件 | SlurmctldLogFile / SlurmdLogFile |
LogFile |
验证方法(本次采用):列出 man 页的合法参数名再比对——
man slurmdbd.conf | col -b | grep -E "^ [A-Z][A-Za-z]+$" | sort -u
修复:SyslogLevel=none → DebugLevelSyslog=quiet。
9.3 现象:日志已分离但 journald 仍有副本¶
根因:-D 参数把日志复制到 stdout,systemd 默认 StandardOutput=journal 收走。
判定:journalctl -o verbose 的 _TRANSPORT 字段可区分 syslog / stdout 通道。
修复:drop-in 设 StandardOutput=null(见 4.4)。
十、遗留问题与建议¶
| 项 | 说明 | 建议 |
|---|---|---|
| OpenMPI 未编译 Slurm PMI 支持 | MpiDefault=pmi2 已配置,但 OpenMPI 4.1.5 编译时未启用 --with-pmi=slurm,srun -n N ./prog 仍会报 OMPI was not built with SLURM's PMI support。详见 MPI与OpenMPI集成实测报告.md |
如需 srun 直启 MPI,应单独立项重编译 OpenMPI(加 --with-pmi=slurm) |
| StateSaveLocation 写入慢 | 日志出现 Saving to StateSaveLocation took 615ms... Please check backing filesystem(本次变更前即存在) |
检查 /var/spool/slurmctld 所在盘 IO;EDA 大集群建议独立 SSD |
| 旧 slurmdbd.log 105MB | 变更前遗留的 9月2日旧日志 | 下次 logrotate 自动轮转压缩;也可立即手动执行 logrotate -f /etc/logrotate.d/slurm |
sched_min_age=30 疑似无效参数 |
SchedulerParameters 中的该项在 man 页中不存在(阶段 6 已记录) |
建议清理,避免"以为配了" |
| 日志级别为 info | 生产排障期可临时调 debug(scontrol reconfigure 即可生效,无需重启) |
scontrol setdebug debug 临时提级,排障后 scontrol setdebug info |
十一、变更后文件清单¶
| 文件 | 位置 | 说明 |
|---|---|---|
SOP_日志分离与MPI默认.md |
本目录 | 本文档 |
apply_slurm_log_mpi.sh |
本目录 | 正向变更可复现脚本 |
rollback_slurm_log_mpi.sh |
本目录 | 回滚脚本 |
MPI与OpenMPI集成实测报告.md |
本目录 | MPI 四组对照实测与结论 |
slurm.conf.bak.20260912 |
控制节点 /usr/local/slurm/etc/ |
配置备份(md5 1cdcc770...) |
slurmdbd.conf.bak.20260912 |
控制节点 /usr/local/slurm/etc/ |
配置备份(md5 de4d6b3a...) |
来源:
/home/rain/Documents/slurm/slurm_study/slurm_study_plan/运维变更_日志分离与MPI默认/SOP_日志分离与MPI默认.md| 最后更新:2026-09-12 12:29(由build/sync.py同步,请勿在站点侧修改)