技术文章

Slurm 部署指南:在 EL8 / EL9 上搭建主备控制器与作业记账

面向 Rocky Linux、AlmaLinux 与 RHEL 的 EL8 / EL9 Slurm 集群部署教程:涵盖 RPM 构建、MUNGE 认证、MariaDB 双库、主备控制器、节点防火墙,以及 sbatch 提交、squeue 查询和 sacct 记账验收。

Slurm 部署指南概念封面

大家好啊,我是 jianpeng。今天和大家聊一下 Slurm 在 EL8 / EL9 上的部署。

Slurm 是用于 Linux 计算集群的开源作业调度与资源管理系统:控制器分配资源,计算节点执行任务,用户通过客户端提交和查询作业。本文面向新建 CPU 集群,给出 EL8 / EL9 上的 Slurm 安装配置步骤,把用户身份、资源调度、任务执行与作业记录接起来。[2]

本文采用 Slurm 26.05.4、MariaDB 10.11 系列和 MUNGE。适用于受维护的 RHEL、Rocky Linux、AlmaLinux 等 EL8 / EL9 环境;软件仓库、CPU 架构及 cgroup 模式按实际节点选择。Slurm 26.05.4 发布记录[1]

这是一份依据官方文档整理的部署模板,尚未在目标服务器上执行。文中的状态均为验收要求,图中关系为原创示意。所有 REPLACE_... 参数须先替换;每段命令只在标注节点执行。

开始前准备好三项外部条件:可用的主机名解析与管理通道、全节点一致的业务用户身份、两台控制器可独立访问的共享状态存储。login 与 compute 还需要路径一致的作业目录。本文只配置控制器主备,db1 为单节点数据库。

按任务阅读:首次安装先看RPM 软件源、MUNGE 与插件构建;配置记账和完成日志看MariaDB 双库与 slurmdbd;搭建主备看主控制器与共享状态、备用控制器;提交和查询作业看sbatch、squeue、sacct 与切换验收。端口按节点列在各部署章节末尾。

1. 架构、服务与实施参数

先看请求经过哪些服务,再按角色安装软件。

节点职责与通信(原创示意)

图中调度、执行和记账分别经过不同服务。记账密码只留在 db1,完成日志凭据只配置在双控制器;login 提交任务,compute 执行任务。

1.1 节点职责

节点 角色 需要启动的服务
db1 单节点数据库、作业记账与完成日志 mariadb、slurmdbd、munge、chronyd
master1 主调度控制器 slurmctld、munge、chronyd
master2 备调度控制器 slurmctld、munge、chronyd
login 用户登录、提交作业、查询 sshd、munge、chronyd
compute 执行计算任务 slurmd、munge、chronyd

各节点 Slurm RPM 安装对照表

节点 slurm slurm-slurmctld slurm-slurmdbd slurm-slurmd slurm-perlapi
db1 必装 — 必装 — —
master1 必装 必装 — — 推荐,本文安装
master2 必装 必装 — — 推荐,本文安装
login 必装 — — — 推荐,本文安装
compute 必装 — — 必装 推荐,本文安装

“—”表示该节点角色不需要安装此包。slurm 是基础包,提供客户端命令和公共组件;各守护进程分别由对应子包提供。slurm-perlapi 是官方推荐的辅助包,不是 slurmctld/slurmd 的替代服务。表中使用 RPM 包名,实际文件还带版本、发行包号、EL 版本和 CPU 架构后缀;全节点 Slurm 版本一致,各自使用适配本机 EL8/EL9 与架构的 RPM。

MUNGE、chrony、管理 SSH 和数据库软件不属于 Slurm RPM:所有节点按公共准备安装 MUNGE 等基础软件,MariaDB-server、MariaDB-client、MariaDB-backup 仅在 db1 安装。后续各节点的安装命令与此表对应,不使用 dnf install /srv/slurm-rpms/*.rpm 把所有角色包一起装上。

slurmstepd 由计算节点的 slurmd 按作业启动,不需要单独配置一个常驻 systemd 服务。本文使用本地配置文件和 auth/munge;login 不运行 slurmctld、slurmd、slurmdbd 或 sackd。管理 SSH 可以按站点策略部署在所有节点。官方节点与软件包说明[2]

本方案只为控制器配置主备。db1 是单节点,不配置数据库副本、数据库 VIP、Pacemaker、DbdBackupHost 或 AccountingStorageBackupHost。db1 故障时记账服务不可用;已建立运行状态的控制器可暂存部分记账消息,但缓存有上限,不能把它当作数据库高可用。第一次启动控制器前,slurmdbd 必须可用。本文还启用 JobCompType=jobcomp/mysql:当前活动控制器直接连接 db1 的完成日志库,这条连接不经过 slurmdbd,也不受其记账缓存保护。db1 故障还会影响 JobComp 初始化或写入,控制器主备不能消除这个单点。官方记账故障与缓存行为[3]

1.2 统一填写的参数

参数 本文约定
集群名称 hpc,全小写,全节点一致
主、备控制器 master1、master2,与 hostname -s 一致
数据库记账节点 db1
登录、计算节点 login、compute
slurm 服务用户 UID 2001,主组 slurm,GID 2001
munge 服务用户 UID 2002,主组 munge,GID 2002
统一配置目录 /etc/slurm
控制器共享文件系统挂载点 /srv/slurm
控制器共享状态目录 /srv/slurm/state
计算节点本地运行目录 /var/spool/slurmd
作业数据共享路径 /shared,login 与 compute 都可访问
数据库名 slurm_acct_db(记账)、slurm_comp_db(完成日志)
数据库账号 slurm@127.0.0.1 用于记账;slurm@REPLACE_MASTER1_IP 与 slurm@REPLACE_MASTER2_IP 用于完成日志,共三条来源账号
测试用业务账号 / 用户 Slurm account 为 research,真实 Linux 用户为 alice

2001/2002 是本部署模板选择的新编号,不是 Slurm 的强制值。部署前必须在所有节点和统一身份目录确认未占用;若被占用,统一选择另一对编号并修改全文。slurm 与真实作业用户的 UID/GID 必须跨节点一致;munge 服务用户也统一编号,便于标准化运维。

1.3 EL8 与 EL9 的差异

项目 EL8 EL9
Slurm RPM 在 EL8、对应 CPU 架构构建 在 EL9、对应 CPU 架构构建
常见默认 cgroup v1 v2
额外开发仓 RHEL CodeReady Builder;Rocky/Alma PowerTools RHEL CodeReady Builder;Rocky/Alma CRB
MariaDB 本文统一使用上游 MariaDB 10.11 RPM 同左,使用 EL9 对应 RPM
身份管理 接入站点统一身份服务 接入站点统一身份服务

不要直接把 EL8 的 Slurm RPM 当作 EL9 安装包。新建环境不把 NIS 作为两套系统的统一前提;业务用户可由现有 LDAP/FreeIPA/SSSD 等身份服务提供。下面服务用户创建步骤适用于站点决定使用本地固定服务账号的情况。

1.4 部署前交付清单

动手前先填写实际环境:发行版及小版本、架构、内核、systemd、Slurm 和 MariaDB 的完整版本,以及计算节点实际使用的 cgroup 模式。EL8 与 EL9 分别准备对应 RPM;表中的“常见默认值”不能代替节点探测。

共享存储应交付以下可核对的结果:

  • master1 与 master2 分别直接挂载同一套独立存储到 /srv/slurm,能够看到同一份 /srv/slurm/state。
  • 两台控制器上的 slurm 用户使用一致的 UID/GID,可以读写状态目录;普通业务用户没有写权限。
  • 持久挂载在重启后生效;挂载缺失时控制器启动被阻止,不能误用同名的本地空目录。
  • 存储服务及其故障域独立于两台控制器,存储侧的故障处理和恢复流程有明确负责人。
  • login 与 compute 挂载同一份 /shared,alice 的身份、路径和读写权限一致。作业目录与控制状态目录分开管理。

存储挂载命令必须采用实际文件系统的交付配置。尚无共享状态存储时,可先验证单控制器安装,但本篇主备验收需要在上述条件满足后进行。

2. 所有节点公共准备:软件源、MUNGE 与 RPM 构建

公共准备决定后续服务能否互相信任。先核对身份和时间,再验证认证与软件包。

公共准备的依赖关系(原创示意)

同一 MUNGE 密钥、可解析的用户身份与可靠时间同步需要同时成立;安装 RPM 不会自动补齐这些前提。

2.0 先配置 RPM 软件源:优先内部镜像

【所有节点及构建机,在第一次 dnf install 之前】优先使用站点维护的内部镜像源,统一依赖、版本和访问路径。先取得仓库管理员交付的仓库地址、签名公钥及指纹;RHEL 优先使用已授权的 Satellite / 内部内容服务。没有内部镜像时,再选择本节的官方联网方案,两种方式不要叠加执行。

内部镜像应按发行版、EL 主版本和 CPU 架构分别提供,不能把 Rocky、AlmaLinux、RHEL 或 EL8/EL9 的仓库混用。至少包括以下内容:

  • BaseOS、AppStream:基础系统、工具及运行依赖;所有节点需要。
  • 开发仓库:RHEL 使用 CodeReady Builder;Rocky/AlmaLinux 8 使用 PowerTools,9 使用 CRB。构建和部分 EPEL 依赖需要。
  • EPEL:与 EL 主版本匹配,用于 MUNGE 等扩展包。构建机也要能访问前述依赖仓库。
  • MariaDB 10.11:只在 db1 安装数据库时启用,镜像中保留选定补丁版本的 server/client/backup。
  • Slurm 26.05.4:内部自建 RPM 仓库或已分发的 /srv/slurm-rpms/;按 EL 与架构分开。本文后续继续使用本地 RPM 文件安装,但依赖仍由已配置仓库解析。

内部镜像配置方法。先查看并备份现有配置;RHEL 的 redhat.repo 由订阅工具管理,不直接覆盖。若管理员已交付正确的 .repo 和公钥文件,核对后使用即可。否则以本例创建 /etc/yum.repos.d/internal-hpc.repo:每个 REPLACE_*_BASEURL 替换为实际完整 HTTPS 仓库地址,地址下必须有 repodata/repomd.xml。文件中的仓库 ID 是本文示例名称,可按站点统一命名。DNF 仓库配置依据[28]。

cat /etc/os-release
uname -m
dnf repolist --all
cp -a /etc/yum.repos.d "/root/yum.repos.d.before-slurm.$(date +%Y%m%d-%H%M%S)"
[internal-baseos]
name=Internal BaseOS
baseurl=REPLACE_BASEOS_BASEURL
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-internal-os
sslverify=1

[internal-appstream]
name=Internal AppStream
baseurl=REPLACE_APPSTREAM_BASEURL
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-internal-os
sslverify=1

[internal-builder]
name=Internal CodeReady Builder or PowerTools or CRB
baseurl=REPLACE_BUILDER_BASEURL
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-internal-os
sslverify=1

[internal-epel]
name=Internal EPEL
baseurl=REPLACE_EPEL_BASEURL
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-internal-epel
sslverify=1

[internal-mariadb]
name=Internal MariaDB 10.11
baseurl=REPLACE_MARIADB_BASEURL
enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-internal-mariadb
sslverify=1

[internal-slurm]
name=Internal Slurm 26.05.4
baseurl=REPLACE_SLURM_BASEURL
enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-internal-slurm
sslverify=1

公钥文件名由本例统一命名,内容必须是所用 RPM 的真实签名公钥:保留上游签名的镜像使用相应上游公钥,内部重新签名的包使用内部签名公钥。先按交付的可信指纹核对,再把文件放入 /etc/pki/rpm-gpg/;只分发公钥,不分发签名私钥。MariaDB 和 Slurm 两个可选仓库保持 enabled=0,用到时再启用。

如采用内部 CA,先通过可信通道部署 CA 证书并更新系统信任库,保持 sslverify=1。保持 gpgcheck=1;若镜像还签署仓库元数据,再按镜像交付说明启用 repo_gpgcheck=1,它与 RPM 包签名校验是两项不同检查。

# 公钥已按可信指纹核对并安装到下列路径
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-internal-os
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-internal-epel
dnf --disablerepo='*' --enablerepo='internal-baseos,internal-appstream,internal-builder,internal-epel' makecache --refresh
dnf --disablerepo='*' --enablerepo='internal-baseos,internal-appstream,internal-builder,internal-epel' list --available munge munge-libs

确认元数据可读、包来自预期内部源后,按站点工具禁用被替代的公网 repo ID;或在每次安装时保留上面的 --disablerepo/--enablerepo 限定。仅添加内部源不会自动阻止 DNF 从其他已启用仓库取包。保留必要的订阅及管理仓库,不整体删除原有 .repo 文件。使用已有内部源时,下列公网源步骤全部跳过。

没有内部镜像时的官方联网方案。先确认发行版安装介质自带的 BaseOS/AppStream 仓库可用;RHEL 使用有效订阅,Rocky/AlmaLinux 使用本发行版官方仓库文件。不要从其他发行版复制基础仓库。随后按发行版只选择下面一组:

【RHEL 8 / 9,具备相应订阅】

EL_MAJOR=$(rpm -E '%rhel')
subscription-manager repos --enable "codeready-builder-for-rhel-${EL_MAJOR}-$(arch)-rpms"
dnf install -y "https://dl.fedoraproject.org/pub/epel/epel-release-latest-${EL_MAJOR}.noarch.rpm"

【Rocky / AlmaLinux 8】

dnf install -y dnf-plugins-core
dnf config-manager --set-enabled powertools
dnf install -y epel-release

【Rocky / AlmaLinux 9】

dnf install -y dnf-plugins-core
dnf config-manager --set-enabled crb
dnf install -y epel-release

仓库依据:Red Hat EPEL 说明[5]、AlmaLinux 仓库说明[6]、Rocky Linux 仓库说明[7]。构建机也需要相应开发仓库。

最后执行 dnf repolist --enabled、dnf makecache --refresh 并确认基础工具与 MUNGE 可查询,再进入第 2.1 节。离线环境由管理员同步含依赖和元数据的完整仓库,或交付经过验证的离线包集合,不使用 rpm --nodeps 绕过依赖。内部 Slurm 仓库也需先签署 RPM 并生成仓库元数据,不能把一个只有 RPM 文件的 HTTP 目录直接当成 DNF 仓库。

2.1 主机名、解析与时间同步

【各节点,root】分别设置自身主机名,例如在 db1 上执行:

hostnamectl set-hostname db1
hostname -s
cat /etc/os-release
uname -m

其余节点分别使用 master1、master2、login、compute。所有节点通过 DNS 或 /etc/hosts 解析同一组地址;使用 /etc/hosts 时合并以下内容,不覆盖已有记录:

REPLACE_DB1_IP       db1
REPLACE_MASTER1_IP   master1
REPLACE_MASTER2_IP   master2
REPLACE_LOGIN_IP     login
REPLACE_COMPUTE_IP   compute

不要把这些主机名映射到 127.0.0.1。验证:

getent hosts db1 master1 master2 login compute
dnf install -y chrony openssh-clients openssh-server rsync curl ca-certificates \
    tar bzip2 policycoreutils util-linux

将 /etc/chrony.conf 的时间源配置为站点实际 NTP 服务器,随后:

systemctl enable --now chronyd
chronyc sources -v
chronyc tracking

本文后续通过 SSH 分发配置,所有节点必须先按站点策略配置可用的管理 SSH 账号、认证方式和防火墙,再启用服务:

systemctl enable --now sshd

后文 scp root@节点 以管理员已经获准的 root SSH 通道为例;若站点禁止 root SSH,改为授权管理账号传入临时目录后通过 sudo 安装到目标路径,不为教程修改该策略。SSH 用于管理员分发文件,不是 Slurm 启动作业的必要传输机制;不要复制另一台机器的 SSH 私钥。

2.2 创建 slurm 与 munge 用户和组

【所有节点,安装 Slurm/MUNGE RPM 之前】先核对名称和数字编号:

getent passwd slurm munge
getent group slurm munge
getent passwd 2001 2002
getent group 2001 2002

全新节点应无同名或占号记录,且统一身份服务处于正常可查询状态。若已有正确的服务账号,直接验证并复用;若 UID/GID 不一致,先处理身份与原有文件属主,不直接执行下面的创建命令,也不盲目 usermod。

【仅在上述用户、组和编号均未占用时】

groupadd -g 2001 slurm
useradd -u 2001 -g slurm -M -d /var/lib/slurm -s /sbin/nologin slurm
groupadd -g 2002 munge
useradd -u 2002 -g munge -M -d /var/lib/munge -s /sbin/nologin munge
passwd -l slurm
passwd -l munge

install -d -o slurm -g slurm -m 0755 /var/lib/slurm
install -d -o munge -g munge -m 0700 /var/lib/munge

id slurm
id munge
test "$(id -u slurm)" = 2001 && test "$(id -g slurm)" = 2001
test "$(id -u munge)" = 2002 && test "$(id -g munge)" = 2002

这些是锁定密码、禁止交互登录的服务账号。MariaDB 自己的 Linux mysql 用户由 MariaDB RPM 管理,不应把它改为 slurm。

真实业务用户也必须能在 db1、两台控制器、login 和 compute 上解析为同一身份。例如:

getent passwd alice
id alice

sacctmgr add user 只建立 Slurm 记账关联,不会创建 Linux 用户,也不会创建用户家目录。官方身份要求[4]

2.3 安装与初始化 MUNGE

【所有节点】第 2.0 节仓库已配置并验证可用,下面安装和初始化 MUNGE。

【所有节点】安装 MUNGE:

dnf install -y munge munge-libs
install -d -o munge -g munge -m 0700 /etc/munge /var/log/munge /var/lib/munge
id munge

【仅 db1,新集群】生成一份密钥。test 用于保护已有密钥,不应为了重跑教程覆盖生产集群的 key:

test ! -e /etc/munge/munge.key || exit 1
umask 077
dd if=/dev/urandom of=/etc/munge/munge.key bs=1024 count=1 status=none
chown munge:munge /etc/munge/munge.key
chmod 0600 /etc/munge/munge.key
restorecon -RF /etc/munge /var/lib/munge /var/log/munge

【master1、master2、login、compute】分别安全复制 db1 的同一份密钥。此时尚未启动任何 Slurm 服务:

systemctl stop munge
scp root@db1:/etc/munge/munge.key /etc/munge/munge.key
chown munge:munge /etc/munge/munge.key
chmod 0600 /etc/munge/munge.key
restorecon -RF /etc/munge /var/lib/munge /var/log/munge

【所有节点】

systemctl enable --now munge
munge -n | unmunge
systemctl status munge --no-pager

【db1】验证跨节点认证;对应 SSH 账号需有执行 unmunge 的权限:

munge -n | ssh master1 unmunge
munge -n | ssh master2 unmunge
munge -n | ssh login unmunge
munge -n | ssh compute unmunge

预期 STATUS: Success。在 login 再反向验证到 db1 和 compute。认证失败时先检查密钥、权限、时钟和用户编号。MUNGE 官方安装指南[8]

2.4 构建完整 Slurm RPM:数据库、JWT 与 REST 插件

已有经过验证、包含下列插件的 Slurm 26.05.4 RPM 时直接复用。需要构建时,每个 EL 主版本、每种 CPU 架构分别使用对应构建机;不在每个生产节点安装编译器。先完成第 2.0 节软件源配置,优先使用内部镜像;联网的 Rocky/AlmaLinux 8 启用 PowerTools,9 启用 CRB,并提供对应 EPEL 包,RHEL 使用 CodeReady Builder。

缺插件需要重新构建 RPM。cannot create url_parser context for http_parser/libhttp_parser、cannot create auth context for auth/jwt 和 fatal: failed to initialize auth plugin 可由插件缺失或其运行依赖无法加载引起。只在目标节点补装 libjwt、http-parser,不会给已构建的旧 Slurm RPM 自动增加 .so。

构建依赖与产物对应如下:

  • libjwt-devel → auth_jwt.so:提供 JWT 认证能力。本文 26.05.4 的 RPM spec 要求 libjwt ≥ 1.10.0 且 < 3,不能直接用任意最新主版本。
  • http-parser-devel → http_parser_libhttp_parser.so:提供 HTTP/URL 解析。本文选用 libhttp_parser 后端,与上面的插件名一致。
  • http-parser-devel、json-c-devel,以及所选认证的 libjwt-devel → slurmrestd:配合 --with slurmrestd --with jwt 构建 REST 服务和 JWT 插件。26.05.4 也支持 llhttp 后端;只构建 llhttp 时不会得到名为 http_parser_libhttp_parser.so 的插件。
  • mariadb-devel → accounting_storage_mysql.so、jobcomp_mysql.so:分别供 slurmdbd 记账和控制器完成日志使用。构建机若使用上游 MariaDB 开发库,应选择对应的 MariaDB-devel,不与发行版开发库混装。

JWT 和 REST 构建前提见官方说明[31]、[32];具体开关和版本约束以本文版本的 RPM spec[11]为准。

【构建机】从 SchedMD 官方下载目录[9]取得并校验 slurm-26.05.4.tar.bz2。以下固定版本并安装开发依赖;原版 spec 的 Release 为 1,示例产物路径与它对应。同版本补插件重建应按站点打包流程修改 spec 的 Release 及源目录约定、递增发行包号,不能覆盖同名旧包;不要假定命令行 --define rel 会覆盖 spec 内的定义。

SLURM_VERSION=26.05.4
SLURM_RELEASE=1  # 与本次使用的 RPM spec Release 一致
EL_MAJOR=$(rpm -E '%rhel')
dnf install -y rpm-build rpmdevtools dnf-plugins-core gcc make \
    munge-devel hwloc-devel mariadb-devel \
    libjwt-devel http-parser-devel json-c-devel
rpm -q libjwt-devel http-parser-devel json-c-devel mariadb-devel
rpmdev-setuptree
rpmbuild -ts "slurm-${SLURM_VERSION}.tar.bz2"
dnf builddep -y --define '_with_jwt 1' --define '_with_slurmrestd 1' \
    "$HOME/rpmbuild/SRPMS/slurm-${SLURM_VERSION}"-*.src.rpm

【EL8 构建机,目标计算节点使用 cgroup v1】

rpmbuild -ta "slurm-${SLURM_VERSION}.tar.bz2" \
    --define "dist .el${EL_MAJOR}" \
    --define '_smp_mflags -j4' \
    --with hwloc --with jwt --with slurmrestd

【EL9 构建机,目标计算节点使用 cgroup v2】

dnf install -y dbus-devel kernel-headers libbpf-devel
rpmbuild -ta "slurm-${SLURM_VERSION}.tar.bz2" \
    --define "dist .el${EL_MAJOR}" \
    --define '_smp_mflags -j4' \
    --with hwloc --with jwt --with slurmrestd --with cgroupv2

-j4 是此例的并行构建数,可按构建机资源调整。EL8 若使用统一 cgroup v2,需按官方 cgroup v2 指南[12]补齐内核/systemd 条件并构建 v2 插件,不能套用 v1 分支。不要在同一 RPM 输出目录混放多个旧版本再用通配符打包。

【构建完成后】逐项检查三个关键插件、slurmdbd 数据库插件和 REST 子包。下面每项均应有路径输出,缺少任一项即停止交付:

RPM_DIR="$HOME/rpmbuild/RPMS/$(rpm -E '%_arch')"
MAIN_RPM="$RPM_DIR/slurm-${SLURM_VERSION}-${SLURM_RELEASE}.el${EL_MAJOR}.$(rpm -E '%_arch').rpm"
DBD_RPM="$RPM_DIR/slurm-slurmdbd-${SLURM_VERSION}-${SLURM_RELEASE}.el${EL_MAJOR}.$(rpm -E '%_arch').rpm"
REST_RPM="$RPM_DIR/slurm-slurmrestd-${SLURM_VERSION}-${SLURM_RELEASE}.el${EL_MAJOR}.$(rpm -E '%_arch').rpm"
test -f "$MAIN_RPM" && test -f "$DBD_RPM" && test -f "$REST_RPM" || exit 1
for PLUGIN in auth_jwt http_parser_libhttp_parser jobcomp_mysql; do
  rpm -qpl "$MAIN_RPM" | grep -E "/${PLUGIN}\.so$" || exit 1
done
rpm -qpl "$DBD_RPM" | grep '/accounting_storage_mysql\.so$' || exit 1
rpm -qpl "$REST_RPM" | grep '/sbin/slurmrestd$' || exit 1
rpm -qpR "$MAIN_RPM" "$DBD_RPM" "$REST_RPM"

auth_jwt.so、HTTP parser 和 jobcomp_mysql.so 在主 slurm RPM 中;accounting_storage_mysql.so 随 slurm-slurmdbd,REST 可执行文件随 slurm-slurmrestd。在匹配目标系统的隔离验证机上,用 DNF 安装本次主包和 REST 子包后检查文件及动态依赖:

# 仅隔离验证机;RPM_DIR 等变量沿用上面的本次构建路径
dnf install -y "$MAIN_RPM" "$REST_RPM"
for PLUGIN in auth_jwt http_parser_libhttp_parser jobcomp_mysql; do
  PLUGIN_PATH=$(rpm -ql slurm | grep -E "/${PLUGIN}\.so$")
  test -n "$PLUGIN_PATH" || exit 1
  ldd "$PLUGIN_PATH" || exit 1
done
slurmrestd -V
ldd "$(command -v slurmrestd)"

ldd 输出不能有 not found。这里验证文件和动态依赖;后续在已配置专用非 root REST 服务账号及有效 slurm.conf 的验证环境中,再运行 slurmrestd -a list 和 slurmrestd -s list,确认认证列表包含 rest_auth/jwt 且 OpenAPI 插件可列出。这两条列举命令也会初始化配置,不能在尚无配置的机器上直接当作通过标准。离线交付按 rpm -qpR 和 DNF 的依赖解析结果收集全部运行包,通常涉及 libjwt、jansson、http-parser、json-c 及数据库连接库;它们不是完整依赖清单。在同 EL/架构的干净隔离环境完成离线安装后,再测试 JWT 令牌与 REST 请求,不能用“RPM 文件存在”代替接口验收。

此前 25.11.3 的补插件重建记录可用于理解这个问题,但不把旧版的 14 个二进制 RPM 数量作为 26.05.4 的固定验收数量。实际包数随版本和构建选项变化,验收以本次包清单、插件、依赖与运行结果为准。

按站点内部签名/分发流程交付本次完整构建产物,角色安装仍只选择第 1.1 节所需子包。把匹配当前节点 EL/架构的 RPM 放入 /srv/slurm-rpms,该目录只保留同一次构建的版本和发行包号。官方 RPM 指南[10]。

构建出 JWT 和 REST 能力,不等于已启用 REST 服务。本文集群仍以 AuthType=auth/munge 运行,启用的是 jobcomp/mysql 完成日志;没有部署 REST 监听服务,因此本篇防火墙清单不新增 REST 端口。后续部署 REST 时另行配置 JWT 密钥、认证、服务账号及访问范围。

2.5 提前采集 compute 硬件信息

主控配置需要 compute 的真实资源值,因此准备阶段先在 compute 安装软件做探测,计算服务在第 7 章才启动:

dnf install -y /srv/slurm-rpms/slurm-[0-9]*.rpm \
    /srv/slurm-rpms/slurm-slurmd-[0-9]*.rpm \
    /srv/slurm-rpms/slurm-perlapi-[0-9]*.rpm
slurmd -C
stat -fc %T /sys/fs/cgroup
cat /proc/1/cgroup

记录 CPUs、Boards、SocketsPerBoard、CoresPerSocket、ThreadsPerCore 和 RealMemory。配置的 RealMemory 以 MiB 为单位,低于实测物理内存,给内核、守护进程和文件缓存留出空间;例如实测约 64 GiB 的机器可按实际开销预留数 GiB,而非机械照抄某个固定数值。slurmd 硬件探测[13]

2.6 Slurm 服务端口与防火墙

按目的节点放行本文配置的 Slurm 服务端口,来源限定为实际参与通信的主机。第 3–7 章末尾分别给出各节点的最终清单和规则;前面的服务探测需要连通时,可先应用对应节点规则。

目的节点 / 入站端口 允许来源与用途
master1、master2 TCP 6817 对端控制器、db1、login、compute,以及授权 Slurm 客户端;两台均配置
compute TCP 6818 master1/master2、login、其他运行 srun 的授权主机及计算节点
db1 TCP 6819 master1/master2,以及允许运行 sacct/sacctmgr/sreport 的 login、compute 等节点
login TCP 60001–63000 master1/master2 与 compute 的 srun 控制和 I/O 回连
compute TCP 60001–63000 在批处理脚本中启动 srun 时,由控制器与计算节点回连
db1 TCP 3306 本机 slurmdbd 使用 127.0.0.1;外部仅允许 master1/master2 写 JobComp 完成日志

SrunPortRange=60001-63000 约束 srun 进程的监听端口;除了 login,在批处理脚本里运行 srun 的 compute 也需要相应入站规则。其他主机如果也执行 srun,按实际控制器、计算节点来源补齐同样规则。MUNGE 使用本地 Unix socket,不另开放 MUNGE TCP/UDP 服务端口。Slurm 网络路径[14]、端口参数[20]。

【对应节点,root】以下示例用于已运行的 firewalld,先确认 Slurm 通信网卡对应的 zone:

firewall-cmd --state
firewall-cmd --get-active-zones
firewall-cmd --get-zone-of-interface=REPLACE_CLUSTER_INTERFACE
firewall-cmd --zone=REPLACE_ZONE --list-all

REPLACE_ZONE 填实际 zone;REPLACE_ALLOWED_SOURCE_CIDR 填授权 Slurm 通信方的 IP/CIDR;REPLACE_PORT_OR_RANGE 只选上表对应服务端口。下面是 IPv4 通用格式,已按角色示例添加的规则不需要重复执行。使用 IPv6 时按实际源地址改用 family="ipv6"。规则语法[29]。

firewall-cmd --get-active-zones
firewall-cmd --permanent --zone=REPLACE_ZONE \
  --add-rich-rule='rule family="ipv4" source address="REPLACE_ALLOWED_SOURCE_CIDR" port port="REPLACE_PORT_OR_RANGE" protocol="tcp" accept'
firewall-cmd --reload

检查 --list-all 中实际生效的 ports 与 rich rules。--list-ports 不显示 rich rules;新增限定来源的规则也不会自动撤销已有的宽泛放行。每个节点完成后同时核对运行时规则、永久规则和实际服务监听端口。

3. db1:双数据库和记账服务部署

记账经过 slurmdbd,完成日志由活动控制器直接写库;先按这两条路径准备数据库和授权。

记账与完成日志的两条写入路径(原创示意)

slurmdbd 通过本机回环地址写入 slurm_acct_db;主备控制器具备到 db1:3306 的权限,由活动控制器的 jobcomp/mysql 写入 slurm_comp_db。两个库分别授权,login 和 compute 不直接访问 MariaDB。

3.1 安装 MariaDB 10.11

【db1,root】本文使用上游 MariaDB RPM。先确认这是新数据库节点、没有需要保留的旧实例:

rpm -q mariadb-server MariaDB-server mysql-server
dnf module list mariadb

如果发行版提供且启用了 MariaDB 模块流,在安装上游包前执行 dnf module disable -y mariadb;若该系统没有此模块流则跳过。不要删除正在使用的数据库来满足教程。

优先使用内部 MariaDB 镜像。第 2.0 节的 internal-mariadb 指向匹配当前 EL/架构的 10.11 仓库,并已核对相应签名公钥时,执行下面一组;使用站点其他 repo ID 时同步替换。先确认 server/client/backup 的可选版本来自同一快照,再安装。

# 仅 db1,内部镜像方案
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-internal-mariadb
dnf --disablerepo='*' --enablerepo='internal-baseos,internal-appstream,internal-builder,internal-epel,internal-mariadb' makecache --refresh
dnf --disablerepo='*' --enablerepo='internal-baseos,internal-appstream,internal-builder,internal-epel,internal-mariadb' list --showduplicates MariaDB-server MariaDB-client MariaDB-backup
dnf --disablerepo='*' --enablerepo='internal-baseos,internal-appstream,internal-builder,internal-epel,internal-mariadb' install -y MariaDB-server MariaDB-client MariaDB-backup
rpm -q MariaDB-server MariaDB-client MariaDB-backup

没有内部 MariaDB 镜像时,才使用下面的官方联网方案;已通过内部源完成安装时跳过这一组,避免新增公网源。

依照 MariaDB 官方仓库配置文档[15],下载仓库脚本并核对对应版本的官方 SHA-256,再执行:

install -d -m 0700 /root/mariadb-install
cd /root/mariadb-install
curl -fL https://r.mariadb.com/downloads/mariadb_repo_setup -o mariadb_repo_setup
# 从上述官方页面的 Versions 部分取得与此脚本版本匹配的校验值
printf '%s  %s\n' 'REPLACE_OFFICIAL_SHA256' mariadb_repo_setup | sha256sum -c - || exit 1
bash mariadb_repo_setup --mariadb-server-version=mariadb-10.11 \
    --skip-maxscale --skip-tools
dnf install -y MariaDB-server MariaDB-client MariaDB-backup
rpm -q MariaDB-server MariaDB-client MariaDB-backup

server、client、backup 使用同一选定补丁版本,并记录到交付清单。下面的 innodb_snapshot_isolation 需要 10.11.8 或之后的版本;新装选择受维护的 10.11 补丁版本,不安装已过时的早期补丁。

3.2 配置数据库参数

【db1】在启动新实例前创建 /etc/my.cnf.d/zz-slurm.cnf;确认 /etc/my.cnf 包含此目录,且没有靠后文件覆盖相同参数:

[mysqld]
bind-address=127.0.0.1,REPLACE_DB1_IP
port=3306
skip-name-resolve

innodb_buffer_pool_size=4G
innodb_log_file_size=1G
innodb_lock_wait_timeout=900
innodb_default_row_format=dynamic
innodb_snapshot_isolation=OFF
max_allowed_packet=64M

character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci

REPLACE_DB1_IP 必须是 db1 实际拥有、供控制器访问的集群 IPv4 地址。MariaDB 10.11 支持逗号分隔的多个监听地址;此处只监听回环和指定集群地址,不绑定所有网卡[33]。首次启动前配置;若是在已运行的新建实例上修改监听地址,安排重启 MariaDB 后复核。

db1 必须有足够内存容纳 4 GiB buffer pool、MariaDB 其他开销、slurmdbd 和操作系统;资源不足时先调整规格和参数。锁等待、包大小、大小写不敏感排序规则和 snapshot isolation 按 Slurm 数据库参数要求[16] 配置。

3.3 初始化系统库和安全设置

【db1】

systemctl enable mariadb
systemctl start mariadb && /usr/bin/mariadb-secure-installation

数据库安全初始化:以下回答适用于本文新装实例,由本机操作系统 root 执行,保留 root 的 Unix socket 登录。提示可能随 MariaDB 版本和已有认证状态变化;已启用的选项可能跳过。下面是交互提示及选择,不是逐行执行的 Bash 命令。

Enter current password for root (enter for none):  直接回车
Switch to unix_socket authentication [Y/n]:        Y(已经启用时可能跳过)
Change the root password? [Y/n]:                   n(保留本机 root 的 socket 登录)
Remove anonymous users? [Y/n]:                     Y
Disallow root login remotely? [Y/n]:               Y
Remove test database and access to it? [Y/n]:      Y
Reload privilege tables now? [Y/n]:                Y

“直接回车”只适用于未设置 root 密码、可用本机 socket 认证的新装实例;已有数据库按现有有效凭据登录,不照抄空密码。保留 socket 认证不等于允许任意远程用户免密登录。完成后核对服务与本地 root 登录:

systemctl status mariadb --no-pager
mariadb -u root -e 'SELECT VERSION(), @@datadir, @@socket;'

安全初始化工具说明[30]。

上游 RPM 通常在首次启动空实例时创建系统表。系统库初始化与后面创建 slurm_acct_db、slurm_comp_db 是两件事。正常启动成功后,不要再执行 mariadb-install-db。

安全初始化按提示保留本机 OS root 的 Unix socket 登录,移除匿名账号,禁止远程 root,移除 test 库并重新加载权限;已有 root 认证设置时保留站点批准的方式。Unix socket 登录说明见 MariaDB 官方认证文档[17]。

只有日志明确显示全新空数据目录未初始化时,才停止服务,并针对已核实的空目录执行:

systemctl stop mariadb
# 仅适用于新装、确认为空、实际 datadir 就是 /var/lib/mysql 的实例
mariadb-install-db --user=mysql --datadir=/var/lib/mysql \
    --auth-root-authentication-method=socket
restorecon -RF /var/lib/mysql
systemctl start mariadb

不得在已有数据、恢复后的目录上执行此补救步骤,也不能通过删除数据目录解决启动失败。

3.4 创建两个数据库与三条来源账号授权

本方案同时启用 Slurm 记账和 JobCompType=jobcomp/mysql,因此创建两个库:

  • slurm_acct_db:slurmdbd 使用,保存账户、作业、步骤、资源等记账信息;普通 sacct 查询走这条路径。
  • slurm_comp_db:活动 slurmctld 的 jobcomp/mysql 使用,保存作业完成日志;它不能替代记账库和账户关联。插件首次连接负责初始化所需表,无需手工复制建表 SQL[35]。

MariaDB 以“用户名+来源主机”识别账号。本拓扑创建三条 slurm 账号记录:本机 127.0.0.1 只授权记账库;master1、master2 的准确源 IP 只授权完成日志库。主备都要授权,备用接管后才能继续写入。login、compute 不需要数据库账号,也不分发数据库密码。

由于第 3.2 节启用了 skip-name-resolve,远程授权填写 master1、master2 的实际源 IP,不用主机名。REPLACE_MASTER1_IP、REPLACE_MASTER2_IP 必须与 MariaDB 实际看到的连接来源一致,多网卡或地址转换环境先确认路由;不使用 'slurm'@'%' 规避来源匹配问题。本文 slurmdbd 明确使用回环 TCP,不另建 localhost socket 账号。

两组密码分别对应配置,文件名不是 slurmc.conf:

  • REPLACE_DB_PASSWORD 对应 db1 /etc/slurm/slurmdbd.conf 的 StoragePass,只用于记账库。
  • REPLACE_JOBCOMP_DB_PASSWORD 对应两控制器专用配置的 JobCompPass,只用于完成日志库;两条远程账号在本文共用这组完成日志密码。

分发给普通用户和计算节点的 /etc/slurm/slurm.conf 不包含密码。第 4.3 节通过仅控制器可读的配置入口提供 JobComp 密码。两组密码建议分别生成;使用足够长、不含 #、空白或单引号的随机密码,避免 Slurm 配置注释和 SQL 引号歧义[34]。

【db1,root】交互登录,避免把真实密码写入命令行和 SQL 历史:

MYSQL_HISTFILE=/dev/null mariadb -u root

【新建集群,只执行一次】替换两个控制器源 IP 和两组密码后执行:

CREATE DATABASE slurm_acct_db
  CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE slurm_comp_db
  CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

CREATE USER 'slurm'@'127.0.0.1'
  IDENTIFIED BY 'REPLACE_DB_PASSWORD';
CREATE USER 'slurm'@'REPLACE_MASTER1_IP'
  IDENTIFIED BY 'REPLACE_JOBCOMP_DB_PASSWORD';
CREATE USER 'slurm'@'REPLACE_MASTER2_IP'
  IDENTIFIED BY 'REPLACE_JOBCOMP_DB_PASSWORD';

GRANT ALL PRIVILEGES ON slurm_acct_db.* TO 'slurm'@'127.0.0.1';
GRANT ALL PRIVILEGES ON slurm_comp_db.* TO 'slurm'@'REPLACE_MASTER1_IP';
GRANT ALL PRIVILEGES ON slurm_comp_db.* TO 'slurm'@'REPLACE_MASTER2_IP';

Slurm 插件需要在各自库中建表和维护表结构,因此授权到整个对应库,但不授予全局权限,也不把两个库同时授权给每个来源。数据库 root 继续只通过本机 socket 管理。

在同一个管理员 SQL 会话中核对两个库、三条账号及各自授权,再退出:

SHOW DATABASES LIKE 'slurm%';
SELECT User, Host FROM mysql.user WHERE User = 'slurm';
SHOW GRANTS FOR 'slurm'@'127.0.0.1';
SHOW GRANTS FOR 'slurm'@'REPLACE_MASTER1_IP';
SHOW GRANTS FOR 'slurm'@'REPLACE_MASTER2_IP';
EXIT;

新建本文实例应匹配上述清单。已有库或账号时先核对用途,复用正确授权;密码调整用 ALTER USER,不要删库重建。通过 CREATE USER、GRANT 的账号变更立即生效,无需额外执行 FLUSH PRIVILEGES。

先验证 slurmdbd 的回环连接,再查看监听参数:

mariadb --protocol=TCP -h 127.0.0.1 -P 3306 -u slurm -p slurm_acct_db \
    -e 'SELECT USER(),CURRENT_USER(),DATABASE();'
mariadb -u root -e "SHOW VARIABLES WHERE Variable_name IN
('bind_address','innodb_buffer_pool_size','innodb_lock_wait_timeout',
 'innodb_snapshot_isolation','max_allowed_packet');"
ss -lntp

预期记账账号可登录 slurm_acct_db;3306 只监听 127.0.0.1 和所填的 db1 集群地址。完成日志的远程认证、建表和写入在启动控制器及第 8 章主备作业验收时检查,不能用本机登录成功代替两控制器验证。

3.5 安装并配置 slurmdbd

【db1】

dnf install -y /srv/slurm-rpms/slurm-[0-9]*.rpm \
    /srv/slurm-rpms/slurm-slurmdbd-[0-9]*.rpm
install -d -o root -g root -m 0755 /etc/slurm
install -d -o slurm -g slurm -m 0755 /var/log/slurm
rpm -ql slurm-slurmdbd | grep '/accounting_storage_mysql\.so$'
systemctl cat slurmdbd

最后两项用于确认数据库插件和软件包提供的 systemd unit;不要用其他版本教程的 unit 覆盖它。

创建 /etc/slurm/slurmdbd.conf:

AuthType=auth/munge
DbdHost=db1
DbdAddr=db1
DbdPort=6819
SlurmUser=slurm
DebugLevel=info
LogFile=/var/log/slurm/slurmdbd.log
PidFile=/run/slurmdbd/slurmdbd.pid

StorageType=accounting_storage/mysql
StorageHost=127.0.0.1
StoragePort=3306
StorageLoc=slurm_acct_db
StorageUser=slurm
StoragePass=REPLACE_DB_PASSWORD

此文件只存放在 db1,权限设置为:

chown slurm:slurm /etc/slurm/slurmdbd.conf
chmod 0600 /etc/slurm/slurmdbd.conf
restorecon -RF /etc/slurm /var/log/slurm

这里 MariaDB 和 slurmdbd 同机且均由 systemd 管理,添加启动依赖及失败重试。Restart=always 也覆盖初始化失败后以 0 退出的情况,管理员显式 stop 不会被自动重启:

install -d /etc/systemd/system/slurmdbd.service.d
cat > /etc/systemd/system/slurmdbd.service.d/dependencies.conf <<'EOF'
[Unit]
Wants=mariadb.service
Requires=munge.service
After=network-online.target mariadb.service munge.service
StartLimitIntervalSec=0

[Service]
Restart=always
RestartSec=5s
EOF
systemctl daemon-reload
systemctl enable --now slurmdbd
systemctl status slurmdbd --no-pager
journalctl -u slurmdbd -n 80 --no-pager
mariadb -u root -e 'SHOW TABLES FROM slurm_acct_db;'

slurmdbd 首次启动负责创建 Slurm 表结构,不需要下载 SQL 建表脚本。集群专属表还会在注册集群后建立。日志中不能有数据库认证、插件加载或 schema 初始化错误。

3.6 db1 部署结束:防火墙与端口核对

最终入站清单:TCP 6819 允许 master1、master2、login 和本文允许查询记账的 compute。TCP 3306 对外仅允许 master1、master2 的准确源 IP,用于 JobComp 完成日志。其他记账客户端逐个加真实 IP/CIDR,不能放大成整个办公网。

必须可达的出站:master1/master2 的 TCP 6817(控制器回调)。此处使用 slurm.conf 明确设置的 6817。

ZONE=REPLACE_ZONE
for SRC in REPLACE_MASTER1_IP REPLACE_MASTER2_IP REPLACE_LOGIN_IP REPLACE_COMPUTE_IP; do
  firewall-cmd --permanent --zone="$ZONE" \
    --add-rich-rule="rule family=\"ipv4\" source address=\"$SRC\" port port=\"6819\" protocol=\"tcp\" accept"
done
for SRC in REPLACE_MASTER1_IP REPLACE_MASTER2_IP; do
  firewall-cmd --permanent --zone="$ZONE" \
    --add-rich-rule="rule family=\"ipv4\" source address=\"$SRC\" port port=\"3306\" protocol=\"tcp\" accept"
done
firewall-cmd --reload
firewall-cmd --zone="$ZONE" --list-all
firewall-cmd --permanent --zone="$ZONE" --list-all
ss -lntp

在 db1 核对 slurmdbd 监听 6819、MariaDB 监听 127.0.0.1:3306 和 db1 集群地址的 3306;在 master1 和 login 执行 sacctmgr ping。控制器启动后再从 db1 检查两个控制器可达。仅端口连通不能替代数据库认证和记账验收。

4. master1:主控制器部署

两台控制器的目录名称相同,还需要确认它们访问同一份数据。

主备控制器共享状态(原创示意)

两台分别直接挂载独立共享存储。启动保护检查挂载点;运行中的存储故障仍需按存储侧流程处理。

4.1 安装主控制器软件

【master1】

dnf install -y /srv/slurm-rpms/slurm-[0-9]*.rpm \
    /srv/slurm-rpms/slurm-slurmctld-[0-9]*.rpm \
    /srv/slurm-rpms/slurm-perlapi-[0-9]*.rpm
install -d -o root -g root -m 0755 /etc/slurm
install -d -o slurm -g slurm -m 0755 /var/log/slurm
slurmctld -V
systemctl cat slurmctld

4.2 准备两台控制器共享的状态存储

部署要求:master1 和 master2 必须分别挂载同一套独立共享存储,访问同一份状态数据。共享存储服务必须独立于两台控制器,不能由 master1 提供给 master2,也不能反向由 master2 提供给 master1。

两台分别作为存储客户端配置持久挂载;StateSaveLocation=/srv/slurm/state 在两台指向同一份数据。挂载命令和 /etc/fstab 条目取决于实际存储协议,应使用存储团队交付的配置。共享存储自身的可用性也应独立验证。

不要采用 master2 挂载 master1:/srv/slurm 这种方式,也不要将 master1 已挂载的共享目录再次导出给 master2。 否则 master1 宕机时 master2 也会失去状态目录,无法实现预期的控制器接管。两个同名本地目录或定时 rsync 同样不能代替共享状态。

普通 ext4/XFS 块设备不能直接在两台同时读写挂载。SchedMD 不推荐用 NFS 承载 StateSaveLocation,应选择支持两台共同访问、满足低延迟要求的共享文件系统。官方状态存储要求[19]

【master1】确认已正确挂载后,创建状态子目录:

mountpoint -q /srv/slurm || exit 1
findmnt --mountpoint /srv/slurm
install -d -o slurm -g slurm -m 0700 /srv/slurm/state
runuser -u slurm -- sh -c 'printf "%s\n" hpc-state-storage > /srv/slurm/state/.storage-check'

【master2,基础系统已准备好】验证可见同一文件,且 slurm 可写:

mountpoint -q /srv/slurm || exit 1
findmnt --mountpoint /srv/slurm
runuser -u slurm -- cat /srv/slurm/state/.storage-check
runuser -u slurm -- test -w /srv/slurm/state

如果尚无共享存储,可先按单控制器验证基本安装,但不能把 master2 标记为已完成可用的备控制器。

4.3 编写统一 slurm.conf

【master1】创建 /etc/slurm/slurm.conf。NodeName 行中的数值来自第 2.5 节 compute 的探测结果,必须先替换全部占位符:

ClusterName=hpc
SlurmctldHost=master1
SlurmctldHost=master2

SlurmUser=slurm
SlurmdUser=root
AuthType=auth/munge
SlurmctldPort=6817
SlurmdPort=6818
SlurmctldTimeout=120
SlurmdTimeout=300

StateSaveLocation=/srv/slurm/state
SlurmdSpoolDir=/var/spool/slurmd
SlurmctldPidFile=/run/slurmctld/slurmctld.pid
SlurmdPidFile=/run/slurm/slurmd.pid
SlurmctldLogFile=/var/log/slurm/slurmctld.log
SlurmdLogFile=/var/log/slurm/slurmd.log
SlurmctldDebug=info
SlurmdDebug=info

SchedulerType=sched/backfill
SelectType=select/cons_tres
SelectTypeParameters=CR_Core_Memory
ProctrackType=proctrack/cgroup
TaskPlugin=task/cgroup,task/affinity
JobAcctGatherType=jobacct_gather/cgroup
JobAcctGatherFrequency=30

AccountingStorageType=accounting_storage/slurmdbd
AccountingStorageHost=db1
AccountingStoragePort=6819
AccountingStorageEnforce=associations,limits

JobCompType=jobcomp/mysql
JobCompHost=db1
JobCompPort=3306
JobCompLoc=slurm_comp_db
JobCompUser=slurm

SrunPortRange=60001-63000
ReturnToService=1

NodeName=compute NodeAddr=compute CPUs=REPLACE_CPUS Boards=REPLACE_BOARDS SocketsPerBoard=REPLACE_SOCKETS_PER_BOARD CoresPerSocket=REPLACE_CORES_PER_SOCKET ThreadsPerCore=REPLACE_THREADS_PER_CORE RealMemory=REPLACE_ALLOCATABLE_MIB State=UNKNOWN
PartitionName=cpu Nodes=compute Default=YES DefaultTime=00:30:00 MaxTime=1-00:00:00 DefMemPerCPU=1024 State=UP

CPU 分区和默认每 CPU 1 GiB 内存是本文示例策略,可按机器规格调整。这里只调度 compute,master1/master2/db1/login 不出现在 NodeName/Partition 的计算资源清单中。配置字段定义见 slurm.conf 官方手册[20]。

JobCompType=jobcomp/mysql 已启用。JobCompHost/Port/Loc/User 分别对应数据库主机、端口、完成日志库和账号。主备控制器的主 slurm RPM 都必须包含 jobcomp_mysql.so;它通过 MariaDB 3306 直接写入 slurm_comp_db,与上面的 AccountingStorage 配置并行。

将完成日志密码放在控制器专用配置入口。普通 Slurm 命令需要读取统一 slurm.conf,所以该文件维持 0644,不写 JobCompPass。仅 master1/master2 使用 /etc/slurm/slurmctld.conf 包含共享配置,再补充私密参数;第 4.5 节通过服务环境变量指定这个入口。Slurm 支持 SLURM_CONF 与 Include[34]。

【master1,root】下面先安全创建文件,再用编辑器将占位密码替换为第 3.4 节的完成日志密码;不在终端粘贴含真实密码的命令:

test ! -e /etc/slurm/slurmctld.conf || exit 1
install -o slurm -g slurm -m 0600 /dev/null /etc/slurm/slurmctld.conf
cat > /etc/slurm/slurmctld.conf <<'EOF'
Include /etc/slurm/slurm.conf
JobCompPass=REPLACE_JOBCOMP_DB_PASSWORD
EOF
chown slurm:slurm /etc/slurm/slurmctld.conf
chmod 0600 /etc/slurm/slurmctld.conf
rpm -ql slurm | grep '/jobcomp_mysql\.so$'
ldd "$(rpm -ql slurm | grep '/jobcomp_mysql\.so$')"

通过权限受控的编辑器完成替换后,确认专用文件无占位符;只报告是否发现,不打印密码行:

if grep -q 'REPLACE_' /etc/slurm/slurmctld.conf; then
  echo '请先替换控制器完成日志密码' >&2
  exit 1
fi
runuser -u slurm -- test -r /etc/slurm/slurmctld.conf
stat -c '%U:%G %a %n' /etc/slurm/slurmctld.conf

预期权限为 slurm:slurm 600,插件存在且 ldd 无 not found。不要把这个私密入口包含回公共 slurm.conf,也不要分发给 login、compute 或普通业务用户。普通 sacct 继续使用 slurmdbd;本教程由 db1 管理员核对 JobComp SQL 记录,不向用户提供 sacct --completion 所需的数据库凭据。

创建 /etc/slurm/cgroup.conf,稍后分发给 compute:

CgroupPlugin=autodetect
ConstrainCores=yes
ConstrainRAMSpace=yes
ConstrainDevices=yes

EL8 常见 v1、EL9 常见 v2,以实际挂载为准。统一 autodetect 允许不同节点使用各自受支持的版本,不代表允许单节点采用 v1/v2 hybrid 模式。v1 已被弃用,新节点优先使用 v2;EL8 改 v2 时可能需要 EnableControllers=yes,常规 EL9 不默认添加。cgroup.conf[21]、cgroup v2 指南[12]

chown root:root /etc/slurm/slurm.conf /etc/slurm/cgroup.conf
chmod 0644 /etc/slurm/slurm.conf /etc/slurm/cgroup.conf
restorecon -RF /etc/slurm /var/log/slurm
grep -n 'REPLACE_' /etc/slurm/slurm.conf

最后一条应无匹配;若仍有占位符,不要启动。

4.4 注册集群、账户和真实用户

【master1,root】此时 db1 的 slurmdbd 已运行,master1 的配置已能定位 db1;无需先启动 slurmctld 才能注册集群:

sacctmgr ping
sacctmgr -i add cluster hpc
sacctmgr -i add account research Cluster=hpc Description=Research Organization=Example
sacctmgr -i add user Name=alice Account=research Cluster=hpc
sacctmgr show cluster
sacctmgr show associations where cluster=hpc

这些 add 命令用于新集群,只执行一次;重新部署节点时复用既有记录。alice 必须已经由 Linux/统一身份服务提供。由于启用了 AccountingStorageEnforce,没有有效关联的用户不能提交作业。sacctmgr 官方手册[22]

4.5 加入共享存储启动保护并启动主控制器

【master1】保留 RPM 自带的 unit,通过 drop-in 增加依赖并指定控制器私密配置入口。先查看 systemctl cat slurmctld,确认 /etc/sysconfig/slurmctld、/etc/default/slurmctld 没有其他 SLURM_CONF 设置,SLURMCTLD_OPTIONS 也没有冲突的 -f 配置参数;环境文件可能覆盖这里的 Environment。本文版本的 unit 依据[36]。

install -d /etc/systemd/system/slurmctld.service.d
cat > /etc/systemd/system/slurmctld.service.d/dependencies.conf <<'EOF'
[Unit]
Requires=munge.service
After=network-online.target munge.service
RequiresMountsFor=/srv/slurm/state

[Service]
Environment="SLURM_CONF=/etc/slurm/slurmctld.conf"
ExecStartPre=/usr/bin/mountpoint -q /srv/slurm
EOF
systemctl daemon-reload
systemctl enable --now slurmctld
systemctl status slurmctld --no-pager
journalctl -u slurmctld -n 80 --no-pager
scontrol ping

挂载点必须与真实存储路径一致。这里的保护防止启动时误用本地空目录,不代表运行中的存储故障可以自动修复。RequiresMountsFor 的含义见 systemd 官方文档[23]。

此阶段 master2 尚未启动、compute 尚未启动,查询到备用控制器不可达或计算节点未注册是预期的阶段状态。不能使用 slurmctld -c 作为常规启动命令,它会清理已有状态。

4.6 master1 部署结束:防火墙与端口核对

最终入站清单:TCP 6817 允许 master2、db1、login、所有 compute 和其他授权 Slurm 客户端。没有在本机启动 srun 时,不额外开放 60001–63000。

必须可达的出站:master2 的 TCP 6817、db1 的 TCP 6819 与 3306、compute 的 TCP 6818、运行 srun 的 login/compute 的 TCP 60001–63000。

ZONE=REPLACE_ZONE
for SRC in REPLACE_MASTER2_IP REPLACE_DB1_IP REPLACE_LOGIN_IP REPLACE_COMPUTE_CIDR; do
  firewall-cmd --permanent --zone="$ZONE" \
    --add-rich-rule="rule family=\"ipv4\" source address=\"$SRC\" port port=\"6817\" protocol=\"tcp\" accept"
done
firewall-cmd --reload
firewall-cmd --zone="$ZONE" --list-all
firewall-cmd --permanent --zone="$ZONE" --list-all
ss -lntp

核对 slurmctld 监听 6817;从 login/compute 检查主控可达。备控未部署时先记录待验,完成第 5 章后再验证双向控制器通信。

5. master2:备控制器部署

备控制器的关键是统一配置、共同状态以及实际接管行为。

控制器接管与回切(原创示意)

配置中的主备顺序保持一致。接管要结合日志和新作业验证,不能只凭端口可达判断成功。

【master2】安装与 master1 相同版本、适配本机 EL 版本的控制器 RPM:

dnf install -y /srv/slurm-rpms/slurm-[0-9]*.rpm \
    /srv/slurm-rpms/slurm-slurmctld-[0-9]*.rpm \
    /srv/slurm-rpms/slurm-perlapi-[0-9]*.rpm
install -d -o root -g root -m 0755 /etc/slurm
install -d -o slurm -g slurm -m 0755 /var/log/slurm
scp root@master1:/etc/slurm/slurm.conf /etc/slurm/slurm.conf
scp root@master1:/etc/slurm/cgroup.conf /etc/slurm/cgroup.conf
chown root:root /etc/slurm/slurm.conf /etc/slurm/cgroup.conf
chmod 0644 /etc/slurm/slurm.conf /etc/slurm/cgroup.conf

# 控制器私密入口仅复制到 master2,创建过程即限制读取权限
(umask 077; scp root@master1:/etc/slurm/slurmctld.conf /etc/slurm/slurmctld.conf) || exit 1
chown slurm:slurm /etc/slurm/slurmctld.conf
chmod 0600 /etc/slurm/slurmctld.conf
rpm -ql slurm | grep '/jobcomp_mysql\.so$'
ldd "$(rpm -ql slurm | grep '/jobcomp_mysql\.so$')"

install -d /etc/systemd/system/slurmctld.service.d
scp root@master1:/etc/systemd/system/slurmctld.service.d/dependencies.conf \
    /etc/systemd/system/slurmctld.service.d/dependencies.conf
restorecon -RF /etc/slurm /var/log/slurm /etc/systemd/system/slurmctld.service.d

mountpoint -q /srv/slurm || exit 1
runuser -u slurm -- cat /srv/slurm/state/.storage-check
runuser -u slurm -- test -w /srv/slurm/state
munge -n | ssh master1 unmunge
systemctl daemon-reload
systemctl enable --now slurmctld
systemctl status slurmctld --no-pager
journalctl -u slurmctld -n 80 --no-pager
scontrol ping

两台使用完全相同的公共 slurm.conf 和私密 slurmctld.conf;启动前同样核对服务环境文件无冲突、JobComp 插件及运行库完整,db1 已授权 master2 的实际源 IP。两台配置中的控制器顺序一致,不能在 master2 把自身改成第一条 SlurmctldHost。主备身份由统一配置的顺序决定,不需要 VIP。master2 日志应表明备用角色;scontrol ping 应能探测两个控制器。

主控制器不可用且满足 Slurm 的超时和共享心跳判断条件时,master2 接管;master1 恢复后会重新收回主角色。SlurmctldTimeout=120 不是承诺 120 秒内必定恢复,状态存储不可用时不能靠备用控制器完成恢复。官方控制器主备行为[24]

5.1 master2 部署结束:防火墙与端口核对

最终入站清单:TCP 6817 允许 master1、db1、login、所有 compute 和其他授权 Slurm 客户端。备控制器同样需要可被客户端访问,不能等接管后才放行。

必须可达的出站:master1 的 TCP 6817、db1 的 TCP 6819 与 3306、compute 的 TCP 6818、运行 srun 的 login/compute 的 TCP 60001–63000。

ZONE=REPLACE_ZONE
for SRC in REPLACE_MASTER1_IP REPLACE_DB1_IP REPLACE_LOGIN_IP REPLACE_COMPUTE_CIDR; do
  firewall-cmd --permanent --zone="$ZONE" \
    --add-rich-rule="rule family=\"ipv4\" source address=\"$SRC\" port port=\"6817\" protocol=\"tcp\" accept"
done
firewall-cmd --reload
firewall-cmd --zone="$ZONE" --list-all
firewall-cmd --permanent --zone="$ZONE" --list-all
ss -lntp

在两台控制器上分别运行 scontrol ping 与 sacctmgr ping,确认主备和记账路径可达;在 login 再核对两台控制器。规则必须同时覆盖接管和回切两个方向。

6. login:登录与提交节点部署

提交脚本所在的路径,需要能在真正执行任务的节点上找到。

登录与作业文件路径(原创示意)

login 与 compute 使用同一份作业目录和用户身份。共享状态目录只供控制器使用,不是用户工作区。

【login】

dnf install -y openssh-server \
    /srv/slurm-rpms/slurm-[0-9]*.rpm \
    /srv/slurm-rpms/slurm-perlapi-[0-9]*.rpm
install -d -o root -g root -m 0755 /etc/slurm
scp root@master1:/etc/slurm/slurm.conf /etc/slurm/slurm.conf
chown root:root /etc/slurm/slurm.conf
chmod 0644 /etc/slurm/slurm.conf
restorecon -RF /etc/slurm
systemctl enable --now sshd munge chronyd

sinfo --version
scontrol ping
sacctmgr ping

login 上需要的是 sbatch、srun、squeue、sinfo、sacct 等客户端命令和 MUNGE。它不运行计算守护进程,用户的任务应通过 Slurm 提交到 compute。

在 login 和 compute 上挂载同一份用户家目录或工作目录,例如 /shared,保证脚本、输入文件和输出目录在两边路径一致、UID/GID 权限一致。共享作业数据目录与控制器 /srv/slurm/state 用途不同,不能让普通用户写控制器状态目录。

若站点统一身份目录已提供 alice,可由共享存储管理员创建工作目录:

# 在正确挂载的 /shared 上执行;用户主组以站点实际身份为准
mountpoint -q /shared || exit 1
install -d -o alice -g "$(id -gn alice)" -m 0750 /shared/alice
runuser -u alice -- test -w /shared/alice

SSH 认证策略、家目录自动挂载和 MPI/编译器模块按站点规范配置;这些不会由 Slurm 自动提供。

6.1 login 部署结束:防火墙与端口核对

最终入站清单:TCP 60001–63000 允许 master1/master2 和所有 compute 回连。login 不运行 Slurm 守护进程,不需要入站 6817、6818、6819 或 3306。

必须可达的出站:master1/master2 的 TCP 6817、compute 的 TCP 6818、db1 的 TCP 6819。

ZONE=REPLACE_ZONE
for SRC in REPLACE_MASTER1_IP REPLACE_MASTER2_IP REPLACE_COMPUTE_CIDR; do
  firewall-cmd --permanent --zone="$ZONE" \
    --add-rich-rule="rule family=\"ipv4\" source address=\"$SRC\" port port=\"60001-63000\" protocol=\"tcp\" accept"
done
firewall-cmd --reload
firewall-cmd --zone="$ZONE" --list-all
firewall-cmd --permanent --zone="$ZONE" --list-all
ss -lntp

无 srun 任务时,这段动态端口不会持续监听。计算节点就绪后,以 alice 在共享目录执行第 8 章作业,并用 srun -N1 -n1 hostname 检查回连;不要用空闲时探测 60001 是否开放作为唯一判据。

7. compute:计算节点部署

计算节点要完成用户切换、任务启动和资源约束,先看三个层次的关系。

计算节点上的进程职责(原创示意)

slurmd 以 root 运行,按作业启动 slurmstepd,并以业务用户身份运行任务。cgroup 负责本配置中的资源约束。

7.1 安装检查与配置分发

【compute】第 2.5 节已安装计算节点 RPM,现在核对版本并配置:

rpm -q slurm slurm-slurmd slurm-perlapi munge
slurmd -V
install -d -o root -g root -m 0755 /etc/slurm /var/log/slurm
install -d -o root -g root -m 0755 /var/spool/slurmd
scp root@master1:/etc/slurm/slurm.conf /etc/slurm/slurm.conf
scp root@master1:/etc/slurm/cgroup.conf /etc/slurm/cgroup.conf
chown root:root /etc/slurm/slurm.conf /etc/slurm/cgroup.conf
chmod 0644 /etc/slurm/slurm.conf /etc/slurm/cgroup.conf
restorecon -RF /etc/slurm /var/log/slurm /var/spool/slurmd

slurmd -C
stat -fc %T /sys/fs/cgroup
cat /proc/1/cgroup
findmnt -R /sys/fs/cgroup

cgroup2fs 对应统一 v2;EL8 默认 v1 常见为 tmpfs 顶层及多个控制器挂载。按实际结果核对插件:

rpm -ql slurm | grep -E '/(cgroup_v[12]|task_cgroup|proctrack_cgroup|jobacct_gather_cgroup)\.so$'

需要与本机 cgroup 版本匹配的插件。启动前确认共享工作目录可访问、alice 可解析、MUNGE 可与控制器通信。

7.2 启动 slurmd

【compute】使用 RPM 原 unit;特别是 cgroup v2 下要保留 Delegate=yes 等软件包设置,不用旧式自编 unit 替换:

systemctl cat slurmd
install -d /etc/systemd/system/slurmd.service.d
cat > /etc/systemd/system/slurmd.service.d/dependencies.conf <<'EOF'
[Unit]
Requires=munge.service
After=network-online.target munge.service
EOF
systemctl daemon-reload
systemctl enable --now slurmd
systemctl status slurmd --no-pager
journalctl -u slurmd -n 100 --no-pager

slurmd 通常以 root 运行,以便切换到作业用户身份、建立 cgroup、管理任务。它不是用 slurm 服务账号运行的控制器。slurmd 官方手册[25]

【master1 或 login】

sinfo -N -l
scontrol show node compute
sinfo -R

预期节点成功注册且可调度。若出现 Low RealMemory、CPU 拓扑不匹配或 INVAL/DRAIN,先修复资源配置并重新分发;只有确认原因已消除,才由管理员执行:

scontrol update NodeName=compute State=RESUME

7.3 compute 部署结束:防火墙与端口核对

最终入站清单:TCP 6818 允许两控制器、login 和计算节点之间的请求/转发;TCP 60001–63000 允许两控制器和计算节点回连,以支持批处理脚本在 compute 上执行 srun。没有给计算节点开放入站 6817、6819 或 3306 的需求。

必须可达的出站:master1/master2 的 TCP 6817、其他 compute 的 TCP 6818、login/compute 的 TCP 60001–63000、本文授权记账查询所需的 db1 TCP 6819。

ZONE=REPLACE_ZONE
for SRC in REPLACE_MASTER1_IP REPLACE_MASTER2_IP REPLACE_LOGIN_IP REPLACE_COMPUTE_CIDR; do
  firewall-cmd --permanent --zone="$ZONE" \
    --add-rich-rule="rule family=\"ipv4\" source address=\"$SRC\" port port=\"6818\" protocol=\"tcp\" accept"
done
for SRC in REPLACE_MASTER1_IP REPLACE_MASTER2_IP REPLACE_COMPUTE_CIDR; do
  firewall-cmd --permanent --zone="$ZONE" \
    --add-rich-rule="rule family=\"ipv4\" source address=\"$SRC\" port port=\"60001-63000\" protocol=\"tcp\" accept"
done
firewall-cmd --reload
firewall-cmd --zone="$ZONE" --list-all
firewall-cmd --permanent --zone="$ZONE" --list-all
ss -lntp

每台 compute 都执行相同角色规则,REPLACE_COMPUTE_CIDR 只覆盖受信任计算节点;地址不连续时改成多个准确源地址。核对 slurmd 监听 6818,再从 login 运行普通作业与 srun 测试。

8. Slurm 作业提交、记账与主备切换验收

验收既要检查正常任务,也要观察控制器故障后的调度行为。

从提交到切换的验收(原创示意)

任务输出、最终退出码、sacct 记账与 JobComp 完成记录需要一起核对;主备测试还要确认原任务被追踪、新任务能够提交并最终执行。

sbatch 提交批处理作业,squeue 查看仍在队列中的作业,sacct 查询记账记录,srun 启动作业步骤。安装验收应先确认能提交和执行,再核对退出码与数据库记录;历史任务不能只用 squeue 查询。

8.1 普通作业验证

【login,真实用户 alice】进入共享工作目录,创建任务脚本:

cd /shared/alice
cat > smoke.sbatch <<'EOF'
#!/bin/bash
#SBATCH --job-name=slurm-smoke
#SBATCH --partition=cpu
#SBATCH --account=research
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=1
#SBATCH --mem=512M
#SBATCH --time=00:05:00
#SBATCH --output=slurm-%j.out

set -e
hostname
id
srun /bin/hostname
sleep 20
EOF

JOB_ID=$(sbatch --parsable smoke.sbatch)
printf 'JobID=%s\n' "$JOB_ID"
squeue -j "$JOB_ID"

完成后查询:

cat "slurm-${JOB_ID}.out"
sacct -j "$JOB_ID" -o JobID,JobName,Partition,Account,State,ExitCode,Elapsed,AllocCPUS,MaxRSS

验收:输出主机为 compute、任务身份为 alice、最终 COMPLETED 且 ExitCode=0:0,数据库中可查询到记录。记账上报可能有短暂延迟。短任务不保证采样到非零 MaxRSS,不能仅以该列为空判断记账故障。

【db1,管理员】任务完成后,在 MariaDB 检查插件建表和完成记录。jobcomp_table 由本文版本的插件创建,其字段与 sacct 输出不是同一套结构[35]:

mariadb -u root -e 'SHOW TABLES FROM slurm_comp_db;'
mariadb -u root -e 'SELECT jobid,user_name,name,state,nodelist,starttime,endtime
  FROM slurm_comp_db.jobcomp_table ORDER BY endtime DESC LIMIT 10;'

将 jobid 与 login 刚提交的 JobID 对照,核对用户、作业名、节点和完成时间;state 是内部数值,不直接当作 sacct 的状态字符串。SHOW TABLES 有结果只能证明初始化,出现对应已完成任务的行才证明写入。退出码仍按前面的 sacct 查询核对。

8.2 主控制器切换和恢复

先提交一个运行约 10 分钟、时限大于 10 分钟的测试任务:

# login,alice
HA_JOB_ID=$(sbatch --parsable -A research -p cpu --time=00:15:00 --mem=512M \
    --job-name=controller-ha --wrap='hostname; sleep 600; hostname')
squeue -j "$HA_JOB_ID"

确认任务进入 RUNNING 后,在维护窗口仅停止 master1 的控制器:

# master1,root
systemctl stop slurmctld

【master2 / login】观察接管和业务恢复:

# master2
journalctl -u slurmctld -n 100 --no-pager

# login
scontrol ping
squeue
sinfo -N -l
sbatch -A research -p cpu --mem=128M --wrap='hostname'

新任务可能因 compute 已被占用而排队,能够正常提交、排队并最终执行即可。需要确认原任务仍被正确追踪、master2 日志显示接管;仅看到 scontrol ping 有应答不足以证明调度已接管。

确认接管期间的新任务已经完成,且 sacct 与 slurm_comp_db 都有对应记录后,恢复 master1:

# master1
systemctl start slurmctld
journalctl -u slurmctld -n 100 --no-pager
scontrol ping

预期 master1 恢复主角色、master2 退回 standby。先在 master2 接管期间完成一个新任务,核对其 sacct 记录和第 8.1 节 SQL 中的 JobComp 记录,再恢复 master1;回切后再提交并完成一个新任务,同样检查两条记录路径。原长任务结束后也核对最终状态与输出。只有正常主控、备用接管和恢复主控三种情况下均能写入,才能确认两台的来源授权与私密配置可用。主控短暂中断通常不直接终止计算节点已运行的进程,但最近尚未持久化的控制状态可能丢失,不能宣称绝对无感或零状态损失。Slurm HA 持久化边界[24]

8.3 重启和交付检查

在约定维护窗口逐台验证重启,不能同时重启两台控制器来测试“单机故障”。检查项目:

检查项 通过标准
软件版本 各节点 Slurm 版本一致,各自 RPM 匹配 EL 版本/架构
身份 slurm 为 2001:2001、munge 为 2002:2002;业务用户身份一致
MUNGE / 时间 本机和跨机认证成功,chrony 正常
数据库 双库与三条来源授权正确;3306 仅回环及指定集群地址监听,对外只放行两控制器
slurmdbd 服务与日志正常,新作业最终可由 sacct 查询
JobComp 双控制器均有插件、0600 私密配置;主控、接管和回切后的新完成任务均写入 slurm_comp_db
控制器 两个地址可达、共享同一状态目录、故障接管和回切实测通过
登录节点 普通用户可以 SSH 登录、提交任务、查询自己的记账
计算节点 拓扑匹配,cgroup 插件加载成功,任务运行身份与资源限制正确
持久性 共享挂载、运行目录、服务依赖和开机启动经重启验证

9. 备份、维护与常见排错

备份对象分成配置与密钥、控制状态、MariaDB 双库三类,恢复方法也不同。

备份与恢复的范围(原创示意)

备份应放到独立故障域并做隔离恢复验证。动态状态采用受控停服或存储快照,不能直接覆盖在线状态文件。

9.1 单节点数据库必须有独立备份

【db1,root】以下为一次 MariaDB 物理备份示例,采用本机 root socket 认证,要求 backup 工具与 server 版本匹配:

umask 077
BACKUP_DIR="/var/backups/mariadb/$(date +%Y%m%d-%H%M%S)"
test ! -e "$BACKUP_DIR" || exit 1
install -d -m 0700 "$BACKUP_DIR"
mariadb-backup --backup --user=root --target-dir="$BACKUP_DIR" && \
    mariadb-backup --prepare --target-dir="$BACKUP_DIR"

此物理备份覆盖同一实例的 slurm_acct_db、slurm_comp_db 及账号授权;恢复演练需要同时检查两条记录路径。两个操作都必须成功;将备份复制到独立故障域,定期在隔离环境恢复验证。备份不应只留在 db1 的同一块磁盘。另行保护 /etc/slurm、MUNGE key、共享控制状态存储和包版本清单;动态控制状态使用存储快照或受控停服方式备份,不通过覆盖在线 state 文件实施恢复。MariaDB 官方备份与恢复[26]

9.2 配置更新原则

  • master1 保存配置源;将同一份 slurm.conf 分发给 master2、login、compute。db1 仅运行 slurmdbd 时不必持有 slurm.conf;若要在 db1 使用 Slurm 客户端命令,则也分发该文件。
  • 普通可重载参数修改后使用 scontrol reconfigure,需重启的参数按对应版本手册处理;计算资源/cgroup 变更应先排空相关计算节点。
  • slurmdbd.conf 的记账密码只留在 db1;slurmctld.conf 的 JobComp 密码只留在两控制器,均为 slurm:slurm 0600。私密配置和其备份都限制读取权限;轮换时同步数据库账号与对应服务配置。MUNGE 密钥只在可信节点间分发,权限保持 0600。
  • Slurm 升级、数据库 schema 转换和控制状态格式兼容按 官方升级指南[27] 单独计划,先备份,不把升级与身份编号调整混在一起。

9.3 常用排错入口

现象 优先检查
Invalid credential / authentication failed MUNGE 同一密钥、文件权限、时钟、UID/GID
slurmdbd 启动失败 数据库密码、127.0.0.1 授权、插件、MariaDB 参数、日志
Invalid account or account/partition combination Linux 用户是否存在,sacctmgr association 是否关联到 hpc/research
compute 为 INVAL / DRAIN slurmd -C 与 NodeName 配置差异、RealMemory、sinfo -R
cgroup 插件加载失败 构建时依赖、实际 v1/v2 模式、RPM unit、systemd 委派
master2 不接管 同一状态存储、共享心跳、配置顺序、主机名、控制器日志
srun 卡住但 sbatch 可提交 compute 回连到 login 的 SrunPortRange、双向网络、工作目录权限
sacct 暂无记录 db1 可达性、DBD 日志、作业是否结束、正常上报延迟
JobComp 初始化或写入失败 两控制器 jobcomp_mysql.so 及依赖、私密配置入口、db1:3306、实际源 IP 授权、JobCompPass 与库名
auth/jwt 或 http_parser 插件加载失败 构建开发依赖和开关、主 RPM 插件文件、ldd 运行库、PluginDir 与版本;修复后重新验证 REST 请求
# 按节点选择相应服务
journalctl -u munge -n 100 --no-pager
journalctl -u slurmctld -n 100 --no-pager
journalctl -u slurmdbd -n 100 --no-pager
journalctl -u slurmd -n 100 --no-pager
tail -n 100 /var/log/slurm/slurmctld.log
tail -n 100 /var/log/slurm/slurmdbd.log
tail -n 100 /var/log/slurm/slurmd.log
scontrol ping
sacctmgr ping
sinfo -R

上述日志路径按角色存在,不能因为另一角色的日志文件不存在而判断服务异常。关于插件、参数和升级的最终依据,应以所安装补丁版本的本机 man slurm.conf、man slurmdbd.conf、man cgroup.conf 及对应官方发布文档为准。

按第 8 章逐项记录结果,再把现场使用的版本和配置一并归档。可从配置附件包取得本文示例,按参数替换表填写现场值;附件仅供逐项参考,不能整体执行。

还在比较调度系统时,可先阅读芯片研发计算集群选型:LSF、Slurm 等八类调度系统详解。已完成安装但任务持续等待时,可接着查看LSF / Slurm 作业排队原因与排查路径。

引用链接

  1. Slurm 26.05.4 发布记录

  2. 官方节点与软件包说明

  3. 官方记账故障与缓存行为

  4. 官方身份要求

  5. Red Hat EPEL 说明

  6. AlmaLinux 仓库说明

  7. Rocky Linux 仓库说明

  8. MUNGE 官方安装指南

  9. SchedMD 官方下载目录

  10. 官方 RPM 指南

  11. Slurm 26.05.4 RPM spec

  12. Slurm cgroup v2 指南

  13. slurmd 硬件探测

  14. Slurm 官方网络说明

  15. MariaDB 官方仓库配置文档

  16. Slurm 数据库参数要求

  17. MariaDB 官方认证文档

  18. slurmdbd.conf

  19. 官方状态存储要求

  20. slurm.conf 官方手册

  21. cgroup.conf

  22. sacctmgr 官方手册

  23. systemd 官方文档

  24. 官方控制器主备行为

  25. slurmd 官方手册

  26. MariaDB 官方备份与恢复

  27. 官方升级指南

  28. DNF 仓库配置参考

  29. firewalld 来源限制规则

  30. MariaDB 安全初始化工具

  31. JWT 构建与认证要求

  32. Slurm REST 构建前提

  33. MariaDB bind_address 参数

  34. Slurm 26.05.4 配置手册源文件

  35. Slurm 26.05.4 JobComp MySQL 插件

  36. Slurm 26.05.4 控制器 systemd unit