Slurm 26.05 主备集群部署 SOP¶
实现体:
工程根(Python 部署工程)。第 5 章操作序列用于人工阅读与复核, 以实现体为准;幂等、备份、回滚均由实现体保证,文档中的 shell 片段不承担错误处理。 日常使用与故障处置见同目录RUNBOOK.md;本次部署排障过程见INCIDENT-20260918-slurm-26.05部署排障.md。
目录¶
一、背景¶
原 Slurm 集群运行在 CentOS 7 与 k8s 共存的环境(21.08 → 26.05),节点为 k8s-master-01、k8s-node-01~03,
部署工具只支持单主、配置模板硬编码、健康保障仅有一份 SOP 而无安装逻辑。
本次将部署工具改造为通用安装部署脚本,并在新环境(Rocky Linux 9.8,5 台独立 VM)执行实际部署。 新增三项能力开关:
| 需求 | 开关 | 说明 |
|---|---|---|
| 主备集群 | slurm.ha.enabled |
多控制节点 + NFS 共享 StateSaveLocation |
| 应用特殊配置 | slurm.custom_config.enabled |
以 slurm_conf_old/ 配置为模板做环境变量替换 |
| 集群健康保障 | slurm.health_ensure / --health-ensure |
机制A 内置 HealthCheck + 机制B 巡检自愈 |
首次部署完成后,又针对实测暴露的两个问题做了修复(作为本次变更的收尾):
- 共享存储写入慢:slurmctld 持续告警
Saving to StateSaveLocation took ~0.6s - 两条启动告警:
Configured MailProg is invalid、cannot create http_parser context
再之后又补齐了用户可用性层面的三项能力(第二轮改造)。起因是实测截图暴露两个问题:
root 执行 sinfo 报 command not found,普通 LDAP 用户 su - cy01 报 user cy01 does not exist。
| 需求 | 开关 | 说明 |
|---|---|---|
| 命令 PATH | slurm.path_env.enabled |
写 /etc/profile.d 片段,登录用户(含 root)直接用 sinfo / squeue / sbatch,不必写全路径 |
| LDAP 用户可用 | user_mgmt.system_auth.enabled / --node-env |
sssd + authselect,全部节点经 NSS/PAM 解析并认证 LDAP 用户,su - <user> / ssh <user>@<node> 可用 |
| 共享家目录 | home_share.enabled |
各节点 /home 挂载同一份 NFS 导出,用户在任一节点看到同一份家目录 |
第三轮改造补齐软件环境栈能力:引入 Lmod 环境模块体系(EDA 行业标准做法),
把工具版本、许可证与路径从"写死在用户脚本里"改为"按需 module load"。
| 需求 | 开关 | 说明 |
|---|---|---|
| 环境模块(Lmod) | module_env.enabled / --module-env |
Lmod 软件栈 + 工具家族分层的 modulefiles + Slurm 集成(TaskProlog 透传) |
二、目标¶
变更完成后应达到的可验证状态:
- 5 节点集群就绪:3 个计算节点
idle,scontrol ping返回 primary 与 backup 均UP。 - 主备成型:
slurm.conf含两条SlurmctldHost,StateSaveLocation位于 NFS 共享目录, 备控slurm-master-02上slurmctld同为active。 - 特殊配置生效:EDA 四分区(interactive / compile / regression / long)、 4 级 QoS 与账户层级已建立,Prolog/Epilog 钩子脚本已落位;License TRES 项按选择剔除。
- 记账可用:
sacct可查作业历史,sacctmgr show qos返回 4 条。 - 健康保障就绪:3 个计算节点 HealthCheck 退出码 0;主控
slurm-cluster-health.timer为active且 在 slurmctld 重启后仍保持 active。 - 共享存储写入延迟 ≤ 50ms,slurmctld 无
Saving to StateSaveLocation告警。 - 启动日志中不再出现
MailProg is invalid与http_parser相关错误。 - 幂等达标:部署与健康保障各自复跑一次,第二次零变更、全跳过。
- 命令可直接用:5 台节点任意登录 shell 中
command -v sinfo返回/usr/local/slurm/bin/sinfo。 - LDAP 用户全节点可用:5 台节点
getent passwd cy01返回cy01:*:4001:4000:..., 且su - cy01 -c 'id -u'输出4001(即 csh 与家目录都到位)。 - 家目录共享:5 台节点
findmnt -o SOURCE /home均为192.168.31.249:/data/nfs/home, 且findmnt -o OPTIONS /home中含soft(选项与 yaml 一致)。 - 上述三项复跑一次
--node-env同样零变更、全跳过;且主部署器复跑仍为零变更, 证明新增能力未破坏既有幂等。 - 环境模块就绪:5 台节点登录 shell 可用
module --version(Lmod 8.7.65),module avail列出/opt/modulefiles/Core下的家族入口与slurm/<版本>。 - 模块按层次生效:
module load synopsys后module avail出现vcs/2023.12; 同族互斥(再module load cadence自动替换 synopsys);跨族可共存(pdk+synopsys)。 - 工具守卫有效:工具未安装时
module load vcs/2023.12明确报错"工具尚未安装或路径待配置", 不会"加载成功但命令找不到"。 - Slurm 集成有效:作业脚本内
source /etc/profile.d/zzz_site_lmod.sh后可用module; 且既有 EDA TaskProlog(task_prolog_eda.sh注入的EDA_JOB_ID/EDA_JOB_NODELIST/EDA_WORKDIR)经透传后仍在作业环境中生效。 - 环境模块复跑
--module-env与主部署器 dry-run 均零变更、全跳过。
三、前置条件¶
| 项目 | 要求 | 核实方式 |
|---|---|---|
| 节点 | 192.168.31.16~20,Rocky Linux 9.8,systemd 252,cgroup v2 |
stat -fc %T /sys/fs/cgroup → cgroup2fs |
| 登录 | 部署机 root 对 5 台免密(密钥认证) | ssh -o BatchMode=yes root@<ip> hostname |
| 编译节点 | 192.168.31.18,8 核 / 15G / ≥50G 空闲 |
ssh root@192.168.31.18 "nproc; free -g; df -h /" |
| 目标系统 | RHEL 系 9.x(rhel/rocky/almalinux/centos)、x86_64 |
由 pre_check 自动校验(os_check),不符即报错退出;/etc/os-release 不存在也会拦下 |
| 节点规格 | cpus / memory_mb 可留空,由部署器探测真机 |
留空时用 nproc + /proc/meminfo 探测;auto_detect.memory_ratio 控制 RealMemory 占物理内存比例(默认 0.95) |
| 出网 | download.schedmd.com 与 dnf 源可达 |
curl -sI https://download.schedmd.com/slurm/ |
| NFS | 宿主机 192.168.31.249 导出 /data/nfs/slurm-state(async) |
见第 5.6 节;exportfs -v 应含该行 |
| 数据库 | MariaDB 可达且 database.password 已填写 |
config/slurm_deploy.yaml,权限 600 |
| 运行环境 | 工程内 venv:.venv,依赖见 requirements.txt |
.venv/bin/python -c "import paramiko, yaml" |
LDAP(--user-mgmt 需) |
控制节点需装 openldap-clients;到 LDAP 的 389 端口可达;bind 凭据可用 |
由 pre_check 自动校验,不符合即汇总列出并退出 |
LDAP(--node-env 需) |
5 台节点到 LDAP 389 端口均可达;bind 凭据可用;LDAP 中用户带 uidNumber/gidNumber |
同理由 pre_check 自动校验;库中缺 uidNumber 时应改 system_auth.id_mapping: true |
| NFS(家目录) | 宿主机 192.168.31.249 已导出 /data/nfs/home(async) |
showmount -e 192.168.31.249 应含 /data/nfs/home |
| NFS(modulefiles) | 宿主机 192.168.31.249 已导出 /data/nfs/modulefiles(async) |
showmount -e 192.168.31.249 应含该行 |
| 出网(EPEL) | Lmod 不在 Rocky 的 baseos/appstream 内(那里只有 Tcl 版 environment-modules);epel-release 由 Rocky 的 extras 仓库提供,装完后需能拉取 EPEL 元数据 |
dnf install -y epel-release && dnf list --available Lmod 有结果 |
| SELinux | Rocky 9 默认 Enforcing,NFS 家目录需放通 |
部署器自动 setsebool -P use_nfs_home_dirs on,无需手工 |
| 用户 loginShell | LDAP 中用户 loginShell 若为 /bin/csh,节点须有该 shell |
system_auth.extra_packages: ["tcsh"](Rocky 9 默认不含 csh) |
| 端口 | 6817 / 6818 / 6819 未被占用 | ss -lntp \| grep -E '6817\|6818\|6819' |
| 防火墙 | firewalld 若运行,需放通集群端口 | 部署器自动处理,无需手工 |
| 软件源 | Rocky 9 的 -devel 包位于 CRB 仓库(默认 disabled) |
部署器按需启用,无需手工 |
凭据(
database.password、database.admin_password)只存放在config/slurm_deploy.yaml, 该文件权限 600 且已加入.gitignore;本文档不记录任何凭据原文,需要时从该文件读取。
执行前检查:
cd /home/rain/Documents/slurm_ins
# 1. 依赖就绪
.venv/bin/python -c "import paramiko, yaml; print('deps ok')"
# 2. 5 台免密
for ip in 16 17 18 19 20; do ssh -o BatchMode=yes root@192.168.31.$ip hostname; done
# 3. NFS 可达
timeout 5 bash -c 'cat < /dev/null > /dev/tcp/192.168.31.249/2049' && echo "NFS reachable"
# 4. 数据库端口可达
timeout 5 bash -c 'cat < /dev/null > /dev/tcp/192.168.31.10/3306' && echo "DB reachable"
# 5. 家目录导出已存在(`--node-env` 需要)
showmount -e 192.168.31.249 | grep '/data/nfs/home' && echo "home export ok"
# 6. modulefiles 导出已存在(`--module-env` 需要)
showmount -e 192.168.31.249 | grep '/data/nfs/modulefiles' && echo "modulefiles export ok"
四、影响范围¶
| 主机 | 角色 | 主要变更 |
|---|---|---|
| .16 slurm-master-01 | slurmctld(主) + slurmdbd | 装 munge/nfs-utils/mariadb 客户端、挂载 NFS、解压产物、建服务、起 slurmdbd/slurmctld |
| .17 slurm-master-02 | slurmctld(备) | 同上,不含 slurmdbd;共享同一 StateSaveLocation |
| .18 slurm-work-01 | slurmd + 编译节点 | 额外装构建依赖、下载源码编译、分发产物 |
| .19 / .20 | slurmd | 同 .18(不含编译) |
- 是否停服:本次为全新安装,5 台初始均无 Slurm、无业务,不停服。
- 窗口期:编译阶段(8 核)约 8 分钟,其间占用
.18的 CPU 与磁盘 IO;其余节点无感。 - 再次执行的影响:实现体先做状态巡检,一致即跳过;仅在检测到漂移时重启服务(约 10–20 秒调度中断)。
- 有作业时的约束:若在已有业务的集群上执行,须先确认
squeue为空,且不得对有作业的节点做变更。 - 不可逆项:
/usr/local/slurm-26.05会被覆盖(实现体先备份);/etc/hosts追加标记段;/etc/fstab追加 NFS 条目;宿主机/etc/exports追加一行(改动前已备份,见第 7 章)。
第二轮改造(2026-09-21)的实际变更¶
| 主机 | 主要变更 |
|---|---|
.16 ~ .20(全部 5 台) |
装 sssd / sssd-ldap / oddjob / oddjob-mkhomedir / tcsh;写 /etc/sssd/sssd.conf(600);authselect select sssd with-mkhomedir;启用 sssd 与 oddjobd;/home 挂载 NFS 并写 fstab;setsebool -P use_nfs_home_dirs on;写 /etc/profile.d/slurm-path.sh |
宿主机 192.168.31.249(dell-R620,即部署机本机) |
新建 /data/nfs/home 并新增 NFS 导出(async,改前已备份 /etc/exports) |
- 是否停服:不停任何 Slurm 服务,调度不中断。执行前
squeue为空,作业面影响为零。 - 窗口期:5 台各约 4–5 分钟(主要是
dnf装包),全流程串行约 9 分钟。 - 被改写的系统配置:
/etc/nsswitch.conf、/etc/pam.d/*(由 authselect 接管)、/etc/fstab、/etc/sssd/sssd.conf(新增文件)。变更前均已备份到各节点/var/backups/slurm/node_env_<时间戳>/。 - 不可逆项:无数据删除动作;
/home被 NFS 覆盖挂载(挂载前该目录为空目录,无内容被遮蔽)。 - 回滚:
--node-env --rollback可卸载三项能力;PAM/NSS 若需还原须从上述备份目录人工覆盖(见 7.5)。
第三轮改造(2026-09-21~22)的实际变更¶
| 主机 | 主要变更 |
|---|---|
宿主机 192.168.31.249 |
新建 /data/nfs/modulefiles 并新增 NFS 导出(async,改前已备份 /etc/exports) |
.16 ~ .20(全部 5 台) |
装 epel-release + Lmod / lua / lua-posix;挂载 /opt/modulefiles ← NFS;写 /etc/lmod/lmod_config.lua 与 /etc/profile.d/zzz_site_lmod.sh;分发 /etc/slurm/task_prolog_lmod.sh |
.16(主控,写共享内容) |
生成 10 个 modulefile:Core/ 下 4 个家族入口 + site.lua + slurm/<版本>,以及 4 个家族下各 1 个示例工具模块 |
.16 / .17(控制节点) |
slurm.conf 的 TaskProlog 由 task_prolog_eda.sh 接管为 task_prolog_lmod.sh(新脚本内部透传原脚本) |
- 是否停服:不停
slurmctld/slurmdbd;但为让 TaskProlog 生效会scontrol reconfigure并重启各计算节点的slurmd—— 该节点在跑的作业会被中断,故执行前须确认squeue为空。 - 窗口期:5 台串行约 7 分钟(主要是 EPEL 首次拉元数据与装包)。
- 被改写的系统配置:各节点
/etc/fstab(新增/opt/modulefiles行)、/etc/slurm/task_prolog_lmod.sh(新增)、/etc/profile.d/zzz_site_lmod.sh(新增)、/etc/lmod/lmod_config.lua(新增)、控制节点slurm.conf(仅TaskProlog一行)。变更前均已备份。 - 不可逆项:无数据删除动作;
/opt/modulefiles原为空目录,无内容被遮蔽。
五、分步操作¶
5.1 准备运行环境¶
cd /home/rain/Documents/slurm_ins
python3 -m venv .venv # 建工程 venv(仅首次)
.venv/bin/python -c "import sysconfig, pathlib; \
p = pathlib.Path(sysconfig.get_paths()['purelib']) / 'py_public_modules.pth'; \
p.write_text('/home/rain/py_public_modules', encoding='utf-8')" # 挂载共享库(仅首次)
.venv/bin/python -m pip install -r requirements.txt
5.2 填写配置¶
vi config/slurm_deploy.yaml # 含凭据,权限保持 600
# 必填:database.password(同时作为 slurmdbd.conf 的 StoragePass)
# 开关:slurm.ha.enabled / slurm.custom_config.enabled / slurm.health_ensure
# 节点:nodes.control[].primary 标记主控;nodes.compute[] 的 cpus/memory_mb 可留空(自动探测)
# 环境:os_check 校验目标发行版/主版本/架构;auto_detect 控制规格探测与内存比例
# 换用其它集群导出的模板时:custom_config.legacy 全部留空即可(从模板自动提取旧主机名/
# IP/安装路径);分区 Nodes= 会按 yaml 的节点与 partitions 定义重算,不依赖模板里的旧节点
5.3 预演(不改动任何系统状态)¶
.venv/bin/python main.py \
--config config/slurm_deploy.yaml --dry-run
预演会真实读取各节点状态,因此变更清单是实际待执行动作;输出末尾给出 「变更记录总数 / 待执行变更 / 幂等跳过」三项计数。
5.4 正式部署¶
.venv/bin/python main.py \
--config config/slurm_deploy.yaml --log-level INFO
实现体按 BaseDeployer 固定生命周期执行:pre_check → sync_status → backup → deploy → health_check。
sync_status 判定零变更时直接退出,不进入 deploy。
deploy 十三阶段(实现文件:slurm_deployer.py):
| 阶段 | 动作 | 实现方法 |
|---|---|---|
| 1 | 系统准备:dnf 装包(按需启用 CRB)、建 slurm 用户(固定 uid 64030)、写 /etc/hosts 段、放通 firewalld 端口、统一 munge key |
_stage_system_prepare |
| 2 | 节点基础环境:命令 PATH / LDAP 认证(sssd + authselect)/ 共享家目录(含 SELinux 放通) | _stage_node_env |
| 3 | 环境模块:Lmod 软件栈 / 工具家族 modulefiles / 站点配置 / TaskProlog 脚本 | _stage_module_env |
| 4 | 记账库初始化:建库 / 建号 / 授权 | _stage_provision_database |
| 5 | 源码编译(自动探测 mariadb_config) | _stage_build |
| 6 | 打包编译产物并取回本地 | _stage_pack |
| 7 | 分发 + 解压,并按 ldd 结果补齐运行库 |
_stage_deploy_host / _install_runtime_libs |
| 8 | HA:挂载 NFS 共享目录、写 fstab、建 StateSaveLocation 子目录并 chown | _stage_mount_shared_state |
| 9 | 渲染 slurm.conf / slurmdbd.conf / cgroup.conf / topology.conf | _stage_render_configs |
| 10 | 分发 slurm_conf_old/pro_epilog/*.sh 作业钩子 |
_stage_distribute_prolog_scripts |
| 11 | 安装机制A 健康检查程序 | _stage_install_healthcheck |
| 12 | 生成 systemd 单元 → 停旧 → 切 symlink → 按依赖顺序启动 | _stage_create_systemd / _stage_start_new |
| 13 | 确认记账链路(QoS 与账户已在阶段 12 内建好) | _stage_init_dbd |
阶段 2 与阶段 3 的判定与执行分别由
NodeEnvInstaller、ModuleEnvInstaller提供, 与独立模式--node-env/--module-env共用同一份实现,两条入口不会行为分叉。阶段 3 只落 modulefiles 与脚本,不碰 slurm.conf:
TaskProlog由阶段 9 的配置渲染统一写入 (_stage_module_env传入manage_slurm_conf=False),避免重复编辑与多余的服务重启。
关键顺序与高危动作(节选自实现体):
# —— 阶段 10 内部:启动顺序不可调换 ——
systemctl start slurmdbd # 1) 先起记账后端
sacctmgr -i add cluster cluster # 2) 预创建 cluster 记录
sacctmgr -i add qos interactive # 3) 建 QoS:PartitionName 引用它,
# 晚于 slurmctld 创建会让后者直接 fatal
mkdir -p /etc/systemd/system/slurmctld.service.d # 4) 首次启动:一次性 override
printf '[Service]\nExecStart=\nExecStart=<install>/sbin/slurmctld -D -s -i\n' \
> /etc/systemd/system/slurmctld.service.d/init-state.conf # state 目录为空时需 -i 重建
systemctl daemon-reload && systemctl start slurmctld && sleep 8 && systemctl stop slurmctld
rm -rf /etc/systemd/system/slurmctld.service.d # 用完立即移除,避免每次重启覆盖 state
systemctl daemon-reload && systemctl start slurmctld # 5) 正常启动主控,再启动备控
systemctl start slurmd # 6) 最后起计算节点
# —— 阶段 9 停旧(高危):顺序 slurmd → slurmctld → slurmdbd ——
systemctl stop slurmd slurmctld slurmdbd
# —— 阶段 4 分发(高危:覆盖安装目录)——
rm -rf /usr/local/slurm-26.05 && tar xzf /tmp/slurm-bin-<date>.tar.gz -C /usr/local
ln -sfn /usr/local/slurm-26.05 /usr/local/slurm # 切 symlink,旧目录保留以支持回滚
5.5 安装集群健康保障(可独立执行)¶
# 仅安装健康保障,不重新部署 Slurm;适用于任意已部署好的集群
.venv/bin/python main.py \
--config config/slurm_deploy.yaml --health-ensure
# 机制A:内置 HealthCheck(slurmd 周期执行,失败自动 DRAIN 节点)
install -m 0755 slurm_health_check.sh /usr/local/bin/slurm_health_check.sh
# 在 slurm.conf 写入三个参数后重载:
# HealthCheckInterval=300 / HealthCheckProgram=... / HealthCheckNodeState=ANY
systemctl restart slurmctld && systemctl restart slurmd
# 机制B:控制节点巡检守护
install -m 0644 cluster.json /etc/slurm-health/cluster.json # 拓扑由部署器生成,不硬编码
install -m 0755 cluster_health_check.py /usr/local/bin/cluster_health_check.py
install -m 0755 wait-for-slurmctld.sh /usr/local/bin/wait-for-slurmctld.sh
systemctl daemon-reload
systemctl enable --now slurm-cluster-health.timer # 每 15 分钟巡检一次
systemctl enable slurm-cluster-health-bootstrap.service # 开机引导一次
timer 单元使用
Wants=slurmctld.service而非Requires=。后者会在 slurmctld 重启(停+起) 时把 timer 一并停止,导致巡检静默失效。
5.6 共享存储:迁移到专用 async 导出¶
首次部署时 StateSaveLocation 落在
/srv/nfs/k8s-hdd,该导出为sync且与 k8s 的 4 个 PVC 共用,实测单次 fsync 500–800ms,slurmctld 持续告警。不能直接改该导出为 async(会影响 k8s 持久化数据),因此新建专用导出。
宿主机 192.168.31.249(dell-R620)上执行:
sudo cp -a /etc/exports /etc/exports.bak.$(date +%Y%m%d_%H%M%S) # 高危:改 /etc/exports 前必备份
sudo mkdir -p /data/nfs/slurm-state
# 新增一行(async + 直接落盘,非 loop 镜像)
sudo sh -c 'printf "/data/nfs/slurm-state 192.168.31.0/24(rw,async,no_subtree_check,no_root_squash)\n" >> /etc/exports'
sudo exportfs -ra
sudo exportfs -v | grep slurm-state # 预期:/data/nfs/slurm-state ... (async,...)
随后把 config/slurm_deploy.yaml 的 slurm.ha.shared_state.nfs_export 改为 /data/nfs/slurm-state,
再执行一次第 5.4 节。实现体会:停 slurmctld → umount 旧挂载 → 挂载新导出 → 更新 fstab → 重新启动。
5.7 安装用户管理能力(可独立执行,基本集群就绪后)¶
# 安装:落地同步脚本 + 运行配置 + systemd timer,并立即同步一次
.venv/bin/python main.py --config config/slurm_deploy.yaml --user-mgmt
# 卸载:停掉 timer、删除脚本与配置(已创建的账户与关联不回滚)
.venv/bin/python main.py --config config/slurm_deploy.yaml --user-mgmt --rollback
安装前会做环境检查,任一项不符合即汇总列出全部不符合项并退出,不做任何变更。检查项:
| 检查项 | 不符合时的提示 |
|---|---|
| 配置完整性 | LDAP uri / base_dn / bind_dn / 凭据是否齐备 |
| Slurm 是否已部署 | {prefix}/etc/slurm.conf 是否存在(提示"请先完成 Slurm 集群部署") |
| 守护进程 | 各控制节点 slurmctld 是否为 active |
sacctmgr 可用 |
{prefix}/bin/sacctmgr 是否存在且可执行 |
| 集群名一致 | yaml 的 ClusterName 与节点上 slurm.conf 是否一致 |
| LDAP 客户端 | 控制节点是否装了 ldapsearch(附安装命令) |
| LDAP 连通性 | 各控制节点到 LDAP 端口的 TCP 可达性 |
| LDAP 凭据与结构 | 用配置凭据 bind 并读取基准 DN,确认有对象 |
落地内容(实现文件 user_mgmt_assets.py):
# 同步脚本(Python,调用 ldapsearch + sacctmgr)
install -m 0755 slurm_user_sync.py /usr/local/bin/slurm_user_sync.py
# 运行配置与凭据
install -m 0644 config.json /etc/slurm-usermgmt/config.json
install -m 0600 ldap.pass /etc/slurm-usermgmt/ldap.pass # 凭据不进命令行与日志
# systemd 定时任务
install -m 0644 slurm-user-sync.service /etc/systemd/system/
install -m 0644 slurm-user-sync.timer /etc/systemd/system/
systemctl daemon-reload && systemctl enable --now slurm-user-sync.timer # 默认每日 03:30(带随机延迟)
/usr/bin/python3 /usr/local/bin/slurm_user_sync.py # 安装后立即同步一次
同步规则(按当前 LDAP 的真实结构,见附录 B 第 7 条):
| 账户层级 | 来源 | parent |
|---|---|---|
frontend / analog / it / backend |
ou=* |
无(基准 DN ou=eda 仅作容器不建账户) |
design / dv |
cn=* |
frontend |
custom / layout |
cn=* |
analog |
cad / sre |
cn=* |
it |
pnr / signoff |
cn=* |
backend |
用户关联按 uid → gidNumber → 小组账户;ldapadmin 在排除列表内。清理(LDAP 中已消失的用户)默认启用,带三重保护:受保护列表、运行中作业跳过、LDAP 返回用户数低于阈值时整体跳过。
5.8 安装节点基础环境(可独立执行)¶
前置:宿主机已导出
/data/nfs/home(见 5.9)。 本模式不重启任何 Slurm 服务,可在有业务的集群上安全执行(执行前确认squeue为空更稳妥)。
# 安装:命令 PATH + LDAP 认证 + 共享家目录,覆盖全部节点
.venv/bin/python main.py \
--config config/slurm_deploy.yaml --node-env
# 卸载:停 sssd/oddjobd、撤 authselect、卸 /home 挂载、删 profile.d 片段
.venv/bin/python main.py \
--config config/slurm_deploy.yaml --node-env --rollback
安装前检查(任一项不符合即汇总列出全部不符合项并退出,不做任何变更):配置完整性、
5 台 SSH 连通、dnf / authselect / mount.nfs 可用、SELinux 为 Enforcing 时 setsebool 存在、
各节点到 LDAP 389 与 NFS 2049 的 TCP 可达。
落地内容(实现文件 node_env_assets.py / node_env_deployer.py):
# 1) 命令 PATH —— 登录用户(含 root)直接用 sinfo/squeue/sbatch
cat > /etc/profile.d/slurm-path.sh <<'EOF'
# Slurm 命令路径(由 slurm 部署器写入,请勿手工修改)
SLURM_PREFIX="/usr/local/slurm"
export PATH="$SLURM_PREFIX/bin:$SLURM_PREFIX/sbin:$PATH"
EOF
chmod 0644 /etc/profile.d/slurm-path.sh
# 2) LDAP 认证 —— 装包 → 写 sssd.conf → authselect → 起服务
dnf install -y sssd sssd-ldap oddjob oddjob-mkhomedir tcsh
install -m 0600 /tmp/sssd.conf /etc/sssd/sssd.conf # 权限必须 600,否则 sssd 拒绝启动
systemctl enable sssd && systemctl restart sssd # 此时 nsswitch 已含 sss
# 3. 确认能解析出用户后,才动 PAM(顺序不可颠倒)
for i in $(seq 1 30); do getent passwd cy01 >/dev/null 2>&1 && break; sleep 1; done
authselect select sssd with-mkhomedir --force # ⚠️ 高危:接管 PAM 与 NSS
systemctl enable --now oddjobd # with-mkhomedir 依赖它建家目录
# 3) 共享家目录 —— 挂载 + 持久化 + SELinux 放通
mount -t nfs -o rw,soft,_netdev 192.168.31.249:/data/nfs/home /home # ⚠️ 高危:覆盖挂载 /home
# fstab 用字段精确匹配替换(awk '$2 != "/home"'),避免误删其它含 /home 字样的行
setsebool -P use_nfs_home_dirs on # SELinux Enforcing 下必须放通
/etc/sssd/sssd.conf 内容(bind 密码取自 yaml,不落日志):
[sssd]
config_file_version = 2
services = nss, pam
domains = rainchen
[domain/rainchen]
id_provider = ldap
auth_provider = ldap
ldap_uri = ldap://192.168.31.10:389
ldap_search_base = dc=rainchen,dc=com
ldap_schema = rfc2307
ldap_default_bind_dn = cn=admin,dc=rainchen,dc=com
ldap_default_authtok = <LDAP bind 密码>
ldap_default_authtok_type = password
ldap_id_mapping = false
ldap_tls_reqcert = never
cache_credentials = true
enumerate = false
三个关键约束(踩过才知道):
ldap_id_mapping = false:LDAP 里已带真实uidNumber/gidNumber,必须用真值。 若用 sssd 默认的映射算法,同一用户在节点上的 uid 会是随机值,与 Slurm 记账对不上。- 先 NSS 后 PAM:
authselect会接管/etc/nsswitch.conf与/etc/pam.d/*。必须先起 sssd 并确认getent passwd <user>正常,再执行 authselect,避免"PAM 已改但解析不通"的中间态。 authselect 执行后立即校验 SSH 连通与getent passwd root,任一异常就地回退为authselect select minimal --force并报错退出。 loginShell与家目录:LDAP 中用户loginShell=/bin/csh,而 Rocky 9 默认不含 csh, 需system_auth.extra_packages: ["tcsh"];家目录由with-mkhomedir首次登录时在 NFS 上自动创建。
关于家目录挂载选项(rw,soft,_netdev):
- 用
soft:宿主机不可达时向应用返回 I/O 错误,而不是让访问家目录的进程进入不可 kill 的 D 状态(hard下su - <user>与 SSH 登录会直接卡死)。代价是写操作超时可能出现 "应用报错、服务端已写入"的不一致;若更看重数据一致性,把home_share.mount_options改回hard即可,重跑会自动卸载重挂。 - 不用
intr:内核 2.6.25 之后该选项已废弃(hard挂载的操作本身可被 SIGKILL 中断),写上无效果。 - 判定同时比对挂载源与挂载选项:只改 yaml 中的选项重跑也会正确触发重挂, 否则会出现"配置改了但实际挂载没变"的长期不一致。
5.9 共享家目录:宿主机新增 /home 导出¶
与 5.6 同属宿主机侧配套操作。宿主机
192.168.31.249原本只导出了 k8s 与 slurm-state 相关目录,没有 /home 导出,需先新增。
宿主机 192.168.31.249(dell-R620)上执行:
sudo cp -a /etc/exports /etc/exports.bak.$(date +%Y%m%d-%H%M%S) # 高危:改 /etc/exports 前必备份
sudo mkdir -p /data/nfs/home
sudo sh -c 'printf "/data/nfs/home 192.168.31.0/24(rw,async,no_subtree_check,no_root_squash)\n" >> /etc/exports'
sudo exportfs -ra
sudo exportfs -v | grep '/data/nfs/home' # 预期含 (async,...)
随后把 config/slurm_deploy.yaml 的 home_share.nfs_server / nfs_export 指向该导出,再执行 5.8。
家目录由各节点首次登录时经
with-mkhomedir在共享目录上自动创建(实测drwx------ cy01:custom /home/cy01)。 若希望预先批量创建,可在任一台已挂载/home的节点上按 LDAP 的 uid/gid 手工mkdir + chown, 部署器不会覆盖已存在的家目录。
5.10 安装环境模块(Lmod,可独立执行)¶
前置:宿主机已导出
/data/nfs/modulefiles(见 5.11)。
# 安装:Lmod 软件栈 + 工具家族 modulefiles + 站点配置 + Slurm 集成,覆盖全部节点
.venv/bin/python main.py \
--config config/slurm_deploy.yaml --module-env
# 卸载:撤 TaskProlog、删模块树与站点配置、卸共享挂载
.venv/bin/python main.py \
--config config/slurm_deploy.yaml --module-env --rollback
⚠️ 安装与卸载都会
scontrol reconfigure并重启各计算节点的slurmd(TaskProlog 由 slurmd 执行), 该节点在跑的作业会被中断 —— 执行前须确认squeue为空。
安装前检查(任一项不符即汇总列出并退出):配置完整性、5 台 SSH 连通、dnf 可用、各节点到 NFS 2049 可达。
落地内容(实现文件 module_env_assets.py / module_env_deployer.py):
# 1) 软件栈 —— Lmod 不在 Rocky 官方仓库内,需先启用 EPEL
dnf install -y epel-release && dnf install -y Lmod lua lua-posix
# 2) 共享 modulefiles 挂载(与 /home 同规格;fstab 用 awk 字段精确匹配替换)
mount -t nfs -o rw,soft,_netdev 192.168.31.249:/data/nfs/modulefiles /opt/modulefiles
# 3) modulefiles 树 —— 内容只生成一次,落在共享存储上(NFS 模式下由主控写入)
# /opt/modulefiles/
# ├── Core/{site.lua, slurm/<版本>.lua, cadence.lua, synopsys.lua, siemens.lua, pdk.lua}
# ├── cadence/IC/20.1.lua # 示例:目录守卫 + PATH + 许可证变量
# ├── synopsys/vcs/2023.12.lua
# ├── siemens/calibre/2026.1.lua
# └── pdk/sky130/1.0.lua # 纯数据类,不注入 PATH
# 4) 站点级配置 —— 刻意不覆盖 Lmod 包自带的 modules.sh(那个归 rpm 管理)
# /etc/lmod/lmod_config.lua systemName / allow_prepend_abs_path
# /etc/profile.d/zzz_site_lmod.sh 自包含:非 login shell 先初始化 Lmod,再前置 Core 路径
# 5) Slurm 集成 —— TaskProlog
install -m 0755 task_prolog_lmod.sh /etc/slurm/task_prolog_lmod.sh
# slurm.conf 的 TaskProlog 由 config_renderer 渲染(独立模式做最小编辑)
scontrol reconfigure && systemctl restart slurmd # 各计算节点
Core/synopsys.lua(家族入口)与 synopsys/vcs/2023.12.lua(工具模块)的形态:
-- 家族入口:把该家族的工具树挂进 MODULEPATH,并声明同族互斥
local tree = "/opt/modulefiles/synopsys"
if not isDir(tree) then LmodError("模块树不存在:" .. tree .. "(共享目录未挂载?)") end
prepend_path("MODULEPATH", tree)
family("eda_suite") -- 同族互斥:加载 cadence 会自动替换 synopsys
-- 工具模块:安装目录守卫 + PATH + 工具专属环境变量
local dir = "/opt/eda/synopsys/vcs/2023.12" -- TODO: 待工具就位后填真实路径
if not isDir(dir) then LmodError("工具尚未安装或路径待配置:" .. dir) end
prepend_path("PATH", pathJoin(dir, "bin"))
setenv("VCS_HOME", dir)
setenv("SNPSLMD_LICENSE_FILE", "27020@lic-server")
四个关键约束(实测踩过):
- Lmod 需 EPEL:Rocky 9 的 baseos/appstream 里没有 Lmod(只有 Tcl 版
environment-modules, 无 hierarchy / spider,不符合 EDA 标准)。epel-release由 Rocky 的extras仓库提供。 TaskProlog是单值参数:模板原本指向旧集群的task_prolog_eda.sh(注入EDA_JOB_ID/EDA_JOB_NODELIST/EDA_WORKDIR)。接管后我们的脚本成为唯一入口,内部透传原脚本, 既有注入不失效;--module-env --rollback会自动把该行恢复回原脚本。关闭module_env.enabled时渲染器也会保留模板原值,不会把这一行删掉。- TaskProlog 只注入 LMOD 位置变量,绝不注入
MODULEPATH:TaskProlog 运行在 slurmd 侧, 看不到用户提交时加载了哪些模块;一旦export MODULEPATH就会覆盖用户--export=ALL的结果, 导致"提交前加载的模块在作业里全部丢失"。 module是 shell function,跨不过进程边界:Slurm 作业脚本是非 login shell。 作业脚本首行须source /etc/profile.d/zzz_site_lmod.sh(该文件自包含:先初始化 Lmod, 再前置 Core 路径,一行即可)。
作业脚本的标准写法:
#!/bin/bash
#SBATCH -J sim -N 1
source /etc/profile.d/zzz_site_lmod.sh # 必须:作业脚本是非 login shell
module load synopsys/vcs/2023.12 # 生产脚本建议写全版本号,保证可复现
vcs -full64 ...
两个使用注意: ① 不要写
module load xxx | head这类管道 —— 管道会让module在子 shell 中执行,加载不生效; ② 若module avail看不到刚部署的模块,是 Lmod 的目录扫描缓存所致,执行module --ignore_cache avail或清理~/.cache/lmod即可(部署器的健康检查已带LMOD_IGNORE_CACHE)。
5.11 共享 modulefiles:宿主机新增导出¶
与 5.6 / 5.9 同属宿主机侧配套操作。
宿主机 192.168.31.249(dell-R620)上执行:
sudo cp -a /etc/exports /etc/exports.bak.$(date +%Y%m%d-%H%M%S) # 高危:改 /etc/exports 前必备份
sudo mkdir -p /data/nfs/modulefiles
sudo sh -c 'printf "/data/nfs/modulefiles 192.168.31.0/24(rw,async,no_subtree_check,no_root_squash)\n" >> /etc/exports'
sudo exportfs -ra
sudo exportfs -v | grep '/data/nfs/modulefiles'
随后把 config/slurm_deploy.yaml 的 module_env.nfs.nfs_server / nfs_export 指向该导出,再执行 5.10。
modulefiles 本身只是 10 个文本文件,放共享存储的意义是一处维护、全集群一致, 同时为后续 EDA 工具本体走 NFS 预留位置(工具体积大,绝不建议放各节点本地)。
5.12 modulefile 真实化:virtuoso IC25.10.000(2026-09-26,跨工程变更)¶
触发:Cadence IC25.10(ic25_install 工程)安装验收完成,5.10 的 cadence 占位
IC/20.1(/opt/eda/...假路径)替换为真实工具;由 ic25 HANDOFF 待办 #0 发起, 经用户批准后实施。本节不手改/opt/modulefiles(红线),一切经--module-env。
变更内容(改前均备份于 docs/backup/,.bak.20260926-000421):
config/slurm_deploy.yaml(样例同步):module_env.families.cadence的 tools 换为virtuoso / IC25.10.000,install_dir=/tools/cadence/virtuoso/IC25.10.000(节点客户端视图),bin_subdir=tools.lnx86/dfII/bin/64bit;license 变量不写(待 license 就绪)。- 渲染器新增
prepend字段(module_env_assets.py):变量 → 相对 install_dir 子目录列表, 渲染为prepend_path——LD_LIBRARY_PATH必须 prepend 保留既有值,原env(setenv)会覆盖。 实测 virtuoso 的 210 个树内 not found 库分布于 26 个目录,全部列入 (module_env_deployer.validate_config同步加 prepend 校验:变量名/相对路径/禁..)。 verify_modules尝试加 cadence 验收钩子后回退:首次执行--module-envRC=1 (health 6 项失败)——① 单步module load cadence/virtuoso/...在家族分层下 unknown (须先 load 家族入口激活 MODULEPATH,正确用法为加载链module load cadence virtuoso/IC25.10.000); ② master .16/.17 未挂/tools,工具目录守卫必拦。回退后 health 归位本工程职责 (Lmod/Core/slurm 模块),cadence 验收移交 ic25 侧;链条写法已留档 example 注释。
执行与实测:
cd /home/rain/Documents/slurm/slurm_ins
.venv/bin/python main.py --config config/slurm_deploy.yaml --module-env --dry-run # 预期:待变更 3(新 lua),26 项幂等跳过
# 真实执行(squeue 实测空;本变更 TaskProlog 未变 → 部署器判定 conf_changed=False,实测【未】重启 slurmd)
.venv/bin/python main.py --config config/slurm_deploy.yaml --module-env # 首轮 RC=1(health 见上,变更本体已成功)
.venv/bin/python main.py --config config/slurm_deploy.yaml --module-env # 回退钩子后 RC=0,零变更全跳过(幂等)
# 终验(有 /tools 的节点):module load 后 ldd not found=0
for h in 18 19 20 28; do ssh root@192.168.31.$h 'bash -lc "module load cadence virtuoso/IC25.10.000 && command -v virtuoso && ldd \$(command -v virtuoso) | grep -c \"not found\""'; done
# 预期:每台输出 /tools/.../dfII/bin/virtuoso 与 0(.16/.17 无 /tools 不适用;lsf .25-.27 未装 Lmod 不适用)
- 实测结论【已确认】:.18/.19/.20/.28 加载链后
NOTFOUND=0(217 树内库闭合);sinfo正常、slurmd active;复跑幂等零变更。已知缺口登记:master .16/.17 无/tools、 lsf 三台(.25–.27)未装 Lmod——均不影响作业面,处置见 ic25 HANDOFF 待办。
5.13 cadence license 变量接入(2026-09-26,跨工程变更)¶
触发:license 服务在
192.168.31.29就绪(ic25 侧license_srv_20260926),客户端需拿到CDS_LIC_FILE;由 ic25 HANDOFF 待办 #1 发起,用户确认后实施。完整八章档案在 ic25 工程的ic25_modulefile_lic_20260926/docs/SOP.md,本节只记本工程侧改动。
变更内容(改前备份:ic25_modulefile_lic_20260926/backup/slurm_ins/config/,.bak.20260926-145859):
config/slurm_deploy.yaml(.example同步):module_env.families.cadence.tools[virtuoso].env由 flow 写法改为 block,新增CDS_LIC_FILE: "5280@192.168.31.29"与LM_LICENSE_FILE: "5280@192.168.31.29"(渲染为setenv,工作方式见 5.12 的 env/prepend 分工)。- 未动渲染器、未动 TaskProlog、未动
verify_modules(cadence 验收仍归 ic25 侧)。
执行与实测(squeue 实测为空):
cd /home/rain/Documents/slurm/slurm_ins
.venv/bin/python main.py --config config/slurm_deploy.yaml --module-env --dry-run # 预期 待变更 1、幂等跳过 26
.venv/bin/python main.py --config config/slurm_deploy.yaml --module-env # RC=0
.venv/bin/python main.py --config config/slurm_deploy.yaml --module-env # 复跑:待变更 0、幂等 27(幂等成立)
实测结论【已确认】:/opt/modulefiles/cadence/virtuoso/IC25.10.000.lua 出现两行 setenv(...LIC...);
客户端 .18 加载链后 echo $CDS_LIC_FILE = 5280@192.168.31.29。
遗留【已确认】:该 license 为 node-locked(FEATURE 行带 HOSTID=),客户端 checkout 被拒
(-9,57 Invalid host),需版权方换发 floating 版本;详见上述 ic25 档案第 6、8 章。
六、验证¶
SLURM=/usr/local/slurm/bin
# 1. 集群与节点
$SLURM/sinfo -N -o '%N %T %C' | sort -u # 预期 3 行,STATE=idle
$SLURM/scontrol ping # 预期 primary/backup 均 is UP
# 2. 主备形态与共享存储
$SLURM/scontrol show config | grep -E 'SlurmctldHost|StateSaveLocation'
# 预期两条 SlurmctldHost,StateSaveLocation=/mnt/slurm-shared/slurmctld-state
findmnt -o TARGET,SOURCE,FSTYPE /mnt/slurm-shared
# 预期:/mnt/slurm-shared 192.168.31.249:/data/nfs/slurm-state nfs4
# 3. 服务
systemctl is-active munge slurmdbd slurmctld # .16 预期均 active
systemctl is-active munge slurmctld # .17
systemctl is-active munge slurmd # .18~.20
# 4. 记账与 QoS
$SLURM/sacctmgr -n -P show qos format=Name,Priority
# 预期 4 行:interactive / regression / normal / long
$SLURM/sacctmgr -n -P show assoc format=Cluster,Account,User | head
$SLURM/sacct -n -P -o JobID,State,ExitCode --starttime today | tail # 历史作业可查
# 5. 健康保障
bash /usr/local/bin/slurm_health_check.sh; echo "exit=$?" # 预期 0(在计算节点执行)
systemctl is-active slurm-cluster-health.timer # 预期 active
systemctl restart slurmctld && sleep 8 && systemctl is-active slurm-cluster-health.timer
# 预期仍为 active(验证 timer 不再被连带停止)
# 6. 日志告警(在 .16 执行)
journalctl -u slurmctld --since '10 min ago' --no-pager | grep -c 'Saving to StateSaveLocation' # 预期 0
journalctl -u slurmctld -n 50 --no-pager | grep -cE 'http_parser|plugin_load' # 预期 0
journalctl -u slurmctld -n 50 --no-pager | grep -c 'MailProg is invalid' # 预期 0
# 7. 共享存储写入延迟
cd /mnt/slurm-shared && for i in 1 2 3; do
s=$(date +%s%N); dd if=/dev/zero of=./iotest bs=4k count=20 conv=fsync status=none
e=$(date +%s%N); echo "第$i 次: $(( (e-s)/1000000 )) ms"; done; rm -f ./iotest
# 预期:9–12 ms
# 8. 端到端作业
cd /tmp && printf '#!/bin/bash\nhostname\necho JOB_OK\n' > t.sh
$SLURM/sbatch -N1 -o /tmp/t_%j.out t.sh
sleep 15 && cat /tmp/t_*.out # 预期输出计算节点主机名与 JOB_OK
$SLURM/sacct -n -P -o JobID,State,ExitCode --starttime today | tail -1 # 预期 COMPLETED 0:0
# 9. 幂等(关键验收)
.venv/bin/python main.py \
--config config/slurm_deploy.yaml 2>&1 | tail -5
# 预期:零变更,无需部署(全跳过)
# 10. 命令 PATH(登录 shell 生效)
ssh root@192.168.31.16 "bash -lc 'command -v sinfo; sinfo -V'"
# 预期:/usr/local/slurm/bin/sinfo 与 slurm 26.05.2
# 11. LDAP 用户全节点可用
for ip in 16 17 18 19 20; do echo -n "192.168.31.$ip: "; \
ssh root@192.168.31.$ip "getent passwd cy01 | cut -d: -f1,3,4,6,7"; done
# 预期:cy01:4001:4000:/home/cy01:/bin/csh(5 行)
for ip in 16 17 18 19 20; do echo -n "192.168.31.$ip su: "; \
ssh root@192.168.31.$ip "su - cy01 -c 'id -u'"; done
# 预期:全部输出 4001(含 csh 与家目录均已就位)
# 12. 共享家目录
for ip in 16 17 18 19 20; do echo -n "192.168.31.$ip: "; \
ssh root@192.168.31.$ip "findmnt -n -o SOURCE,OPTIONS /home | tr ',' ' ' | grep -E '/data/nfs/home|soft' | tr '\n' ' '"; echo; done
# 预期:每行含 192.168.31.249:/data/nfs/home 与 soft
# 13. LDAP 认证相关组件
ssh root@192.168.31.16 "systemctl is-active sssd oddjobd; authselect current | head -4; getsebool use_nfs_home_dirs; stat -c '%a %n' /etc/sssd/sssd.conf"
# 预期:active active;Profile ID: sssd + with-mkhomedir;use_nfs_home_dirs --> on;600 /etc/sssd/sssd.conf
# 14. 节点基础环境幂等(关键验收)
.venv/bin/python main.py \
--config config/slurm_deploy.yaml --node-env 2>&1 | tail -5
# 预期:零变更,无需部署(全跳过)
# 15. 环境模块基本可用(5 台)
for ip in 16 17 18 19 20; do echo -n "192.168.31.$ip: "; \
ssh root@192.168.31.$ip "bash -lc 'module --version' 2>&1 | grep -i 'version [0-9]'"; done
# 预期:5 行 Modules based on Lua: Version 8.7.65 ...
# 16. 模块层次、家族互斥与跨族共存
ssh root@192.168.31.16 "bash -lc 'module purge; module load synopsys; \
module avail 2>&1 | grep -A2 modulefiles/synopsys; echo ---; module load cadence; module -t list'"
# 预期:modulefiles/synopsys 下出现 vcs/2023.12;
# 加载 cadence 时提示 Lmod is automatically replacing \"synopsys\" with \"cadence\";
# module -t list 只剩 cadence
# 17. 工具守卫(工具未安装时明确报错,而非静默成功)
ssh root@192.168.31.16 "bash -lc 'module load synopsys; module load vcs/2023.12' 2>&1 | head -3"
# 预期:Lmod has detected the following error: 工具尚未安装或路径待配置:/opt/eda/synopsys/vcs/2023.12
# 18. 端到端:作业内 module 可用 + 既有 EDA TaskProlog 未失效
ssh root@192.168.31.16 "printf '#!/bin/bash\n#SBATCH -J lmodverify -N1 -o /tmp/lmodverify_%%j.out -t 00:03:00\nsource /etc/profile.d/zzz_site_lmod.sh\nmodule load slurm && command -v sinfo\necho \"EDA_JOB_ID=\$EDA_JOB_ID EDA_WORKDIR=\$EDA_WORKDIR LMOD_CMD=\$LMOD_CMD\"\n' > /tmp/lmod_verify.sh && /usr/local/slurm/bin/sbatch /tmp/lmod_verify.sh"
# 作业完成后,到运行节点查看 /tmp/lmodverify_<jobid>.out,预期:
# /usr/local/slurm/bin/sinfo
# EDA_JOB_ID=<jobid> EDA_WORKDIR=/root LMOD_CMD=/usr/share/lmod/lmod/libexec/lmod
# 19. 环境模块幂等(关键验收)
.venv/bin/python main.py \
--config config/slurm_deploy.yaml --module-env 2>&1 | tail -5
# 预期:零变更,无需部署(全跳过)
七、回滚¶
7.1 备份位置¶
| 备份内容 | 位置 | 说明 |
|---|---|---|
宿主机 /etc/exports |
docs/backup/etc/exports.bak.* |
本次 NFS 变更前备份,已移入交付物目录 |
| 集群侧配置/目录/数据库 | 各控制节点 /var/backups/slurm/ |
实现体自带,随 --rollback 使用,保持原位 |
逐条登记与"何时可删"见 backup/README.md。
7.2 一键回滚(集群)¶
.venv/bin/python main.py \
--config config/slurm_deploy.yaml --rollback
动作:停新服务 → 找旧版本目录 → symlink 切回 → 起旧服务。
7.3 卸载健康保障¶
.venv/bin/python main.py \
--config config/slurm_deploy.yaml --health-ensure --rollback
动作:禁用并删除 timer/service → 删巡检脚本与拓扑配置 → 删 HealthCheck 程序 →
用 slurm.conf.healthbak.* 恢复 slurm.conf。
7.4 手工回滚(脚本失败时)¶
# a) 服务与 symlink
systemctl stop slurmd slurmctld slurmdbd 2>/dev/null # 高危:停服
ln -sfn /usr/local/slurm-<旧版本> /usr/local/slurm
systemctl start slurmdbd slurmctld slurmd
# b) 共享存储:切回原导出(先确认 slurmctld 已停)
systemctl stop slurmctld
umount /mnt/slurm-shared
mount -t nfs -o rw,hard,intr,_netdev 192.168.31.249:/srv/nfs/k8s-hdd /mnt/slurm-shared
# 同步修改 /etc/fstab 中该行的导出路径
# c) 宿主机 /etc/exports:移除新增行(高危:改系统配置前先备份)
sudo cp -a /etc/exports /etc/exports.bak.$(date +%Y%m%d_%H%M%S)
sudo sed -i '\#/data/nfs/slurm-state#d' /etc/exports
sudo exportfs -ra
# d) 数据库回滚(如需)
gunzip < /var/backups/slurm/db_slurm_acct_db_<timestamp>.sql.gz | \
mysql -h 192.168.31.10 -u slurm -p slurm_acct_db
回滚后验证:scontrol ping 正常、sinfo 能列出节点、sacct 可查历史、三个守护进程 active。
7.5 卸载节点基础环境(第二轮改造)¶
# 一键卸载:命令 PATH + LDAP 认证 + 共享家目录(覆盖全部 5 台)
.venv/bin/python main.py \
--config config/slurm_deploy.yaml --node-env --rollback
动作顺序:删 /etc/profile.d/slurm-path.sh → umount /home 并从 /etc/fstab 删该行
→ setsebool -P use_nfs_home_dirs off → 停并禁用 sssd / oddjobd
→ authselect select minimal --force → 删 /etc/sssd/sssd.conf。
不会删除:已安装的软件包、NFS 上已创建的家目录及其内容。删除家目录需人工确认后手工执行。
PAM/NSS 若需还原到变更前状态(authselect 接管前的版本),各节点备份位于
/var/backups/slurm/node_env_<时间戳>/,内含 _etc_nsswitch.conf、_etc_fstab、
_etc_pam.d、_etc_sssd_sssd.conf:
ssh root@192.168.31.16 "ls -1 /var/backups/slurm/node_env_*/" # 确认备份点
ssh root@192.168.31.16 "cp -a /var/backups/slurm/node_env_<ts>/_etc_nsswitch.conf /etc/nsswitch.conf && \
cp -a /var/backups/slurm/node_env_<ts>/_etc_pam.d/. /etc/pam.d/ && \
systemctl restart sshd" # 高危:改 PAM 后必须确认 SSH 仍可登录
宿主机侧若也要撤销 /home 导出(先确认各节点已 umount /home):
sudo cp -a /etc/exports /etc/exports.bak.$(date +%Y%m%d-%H%M%S) # 高危:改前必备份
sudo sed -i '\#^/data/nfs/home #d' /etc/exports
sudo exportfs -ra
回滚后验证:getent passwd cy01 无输出;findmnt /home 无输出(回到本地目录);
bash -lc 'command -v sinfo' 无输出(命令文件本身仍保留在 /usr/local/slurm/bin)。
7.6 卸载环境模块(第三轮改造)¶
# 一键卸载:撤 TaskProlog → 删模块树与站点配置 → 卸共享挂载
.venv/bin/python main.py \
--config config/slurm_deploy.yaml --module-env --rollback
动作顺序:把 slurm.conf 的 TaskProlog 恢复为原脚本 /usr/local/slurm/task_prolog_eda.sh
→ 删 /etc/slurm/task_prolog_lmod.sh → 删 /etc/profile.d/zzz_site_lmod.sh 与 /etc/lmod/lmod_config.lua
→ umount /opt/modulefiles 并从 /etc/fstab 删该行 → scontrol reconfigure + 重启各计算节点 slurmd。
不会删除:已安装的 Lmod 软件包、共享存储上的 modulefiles 内容(避免误删共享内容)。 如需彻底清理,先确认无其它使用者,再人工删除
/data/nfs/modulefiles下的内容与Lmod包。
宿主机侧若也要撤销 modulefiles 导出(先确认各节点已 umount /opt/modulefiles):
sudo cp -a /etc/exports /etc/exports.bak.$(date +%Y%m%d-%H%M%S) # 高危:改前必备份
sudo sed -i '\#^/data/nfs/modulefiles #d' /etc/exports
sudo exportfs -ra
回滚后验证:bash -lc 'module --version' 报 command not found(或回落到 Tcl 版);
findmnt /opt/modulefiles 无输出;grep '^TaskProlog=' /usr/local/slurm/etc/slurm.conf
预期回到 /usr/local/slurm/task_prolog_eda.sh。
八、风险说明¶
| 风险 | 影响 | 缓解措施 |
|---|---|---|
database.password 未填 |
部署在 pre_check 直接失败,不产生任何变更 |
配置检查前置,--dry-run 也会告警 |
编译依赖缺失或 mariadb_config 未找到 |
编译中断,旧版本未切换,集群不受影响 | 编译失败即中止;build_deps 已含 Rocky 9 全部所需包名 |
-devel 包不在默认仓库 |
装包失败,部署中断 | 部署器检测到 -devel 包时自动启用 CRB 仓库 |
| firewalld 只放通 ssh | 6817/6818 被拦,slurmd 无法拉取 configless 配置 | 部署器自动 firewall-cmd --permanent --add-port 后 reload |
| munge key 权限设为 group 可读 | munged 拒绝启动:Keyfile is insecure,全线起不来 |
部署器固定 chown munge:munge + chmod 400(不能用 640) |
| 首次启动 state 目录为空 | slurmctld fatal: No Assoc usage file ... to recover |
一次性 systemd override 注入 -i 初始化 state,用完即移除 |
| QOS 晚于 slurmctld 创建 | fatal: Partition xxx has an invalid qos |
启动顺序固定为 slurmdbd → 记账初始化 → slurmctld → slurmd |
编译节点的 -devel 包不分发 |
计算节点缺运行库,slurmd 或插件 dlopen 失败 |
运行库检查覆盖 sbin/* 与 lib/slurm/*.so,用 ldd 探测 + dnf repoquery 反查包名自动补齐 |
| cgroup v2 下 slurmd 未按 systemd 模式启动 | cannot create cgroup context for cgroup/v2,作业无法运行 |
单元用 Type=notify + ExecStart=... --systemd -s(--systemd 与 -D 互斥) |
编译时缺 dbus-devel |
不生成 cgroup_v2.so,配置再对也跑不了作业 |
build_deps 已含;分发判据额外校验该插件存在 |
| 编译依赖变化但版本号不变 | 产物实际不同却被判为"已安装",出现假一致 | 引入编译输入指纹(版本+依赖+configure 参数),变化即自动重编译与重分发 |
| 共享存储后端被更换 | 只看 mountpoint 会漏判为零变更,切换不执行 |
sync_status 比对 findmnt 的挂载源 |
| 渲染结果含生成时间戳 | 配置哈希每次都变,漂移检测永久判为有变更,幂等失效 | 渲染器禁止写入时间戳(config_renderer.py 有注释约束) |
timer 用 Requires=slurmctld.service |
slurmctld 重启会连带停掉巡检 timer,健康守护静默失效 | 改用 Wants=,巡检同时校验 enabled 与 active |
| 数据库操作凭据落到命令行/日志 | 密码出现在进程列表与日志文件 | 全部改用 0600 临时 cnf 文件传参,写入走 SFTP;日志已确认不含凭据 |
备控仅在 slurm-master-02,slurmdbd 单点 |
主控全挂时记账不可用(调度仍可继续) | 本次未做 DBD 双活;如需可后续扩展 |
模板 MailProg 指向不存在的 sendmail |
slurmctld 每次启动记一条告警 | 部署器探测 /usr/sbin/sendmail,不存在时自动注释该行 |
| 模板里的分区与主机名指向旧集群 | 换用其它集群导出的模板时,替换映射对不上;且模板只定义 3 个计算节点时,新集群多出的节点不属于任何分区、无法接作业 | 旧环境标识改为从模板自动提取(ControlMachine/SlurmctldHost、NodeName、PluginDir、Prolog 路径、全文 IP),并用节点名前缀从注释补齐;PartitionName 的 Nodes= 按 yaml 重算(覆盖全部旧节点→视为全量,替换为当前全部计算节点);必要时用 custom_config.legacy 手工覆盖 |
| 模板注释里残留旧集群主机名 | 排障时误以为配置未生效 | 注释行同样参与旧标识替换 |
| 手工填写节点 CPU/内存与真机不符 | RealMemory 偏大会导致内存超分、偏小则浪费资源 |
yaml 留空即自动探测(nproc + /proc/meminfo,内存取物理 95%);填写了则以 yaml 为准 |
| 目标机非 RHEL 系或版本不符 | 直接进入装包阶段,以 command not found / Unable to find a match 之类的晦涩报错失败,难定位 |
pre_check 先校验 /etc/os-release 的 ID/ID_LIKE、VERSION_ID 与 uname -m,不符即报错并说明期望值;可用 os_check.enabled: false 关闭 |
| 目标机与部署机之间有跳板/容器环境 | /etc/os-release 缺失导致识别失败 |
该校验会明确报错而不是静默通过 |
sacctmgr -i 模式下对象不存在也输出表头 |
用它做存在性判断会恒为真,同步全部走"已存在,跳过",实际什么都没建 | 查询一律用 -n -P(不带 -i),-i 只用于变更操作 |
| LDAP 基准 DN 本身被当成账户 | ou=eda 会被建成一个无意义的顶级账户 |
基准 DN 只作容器,其直接子级视为顶级账户 |
| 用户清理误删 | 误删关联不可回滚(记账历史无法复原) | 三重保护:受保护列表、有运行作业跳过、LDAP 返回用户数低于 min_ldap_users 时整体跳过清理 |
| LDAP 凭据泄露 | 密码进入命令行、进程列表或日志 | 凭据写 0600 文件并用 ldapsearch -y 传入;巡检会校验该文件权限为 600 |
| 账户体系重复建设 | 部署时按"工种"建的账户与 LDAP 按"部门"建的账户并存,两套维度无法自动合并 | 已统一为 LDAP 单一来源;sacctmgr.accounts 中只保留 root,避免重建 |
authselect 接管 PAM/NSS |
理论上可能影响 SSH 登录(PAM 栈被重写) | 变更前备份 nsswitch.conf 与 /etc/pam.d/;顺序为先起 sssd 确认 getent 正常、再动 authselect;执行后立即校验 SSH 与 getent passwd root,异常就地回退 minimal 并报错退出 |
sssd.conf 含 LDAP bind 密码 |
凭据泄露 | 权限强制 600 并在校验阶段复查;内容经 SFTP 写入(不进命令行);日志不打印内容 |
ldap_id_mapping 取默认值 |
节点上 uid 由算法随机生成,与 LDAP/Slurm 记账对不上,作业归属错乱 | 明确设 false,使用 LDAP 真实 uidNumber/gidNumber;库中若无 uidNumber 才改 true |
LDAP 用户 loginShell=/bin/csh 而节点无 csh |
su - <user> 无法进入预期 shell(或落回 /bin/sh) |
system_auth.extra_packages: ["tcsh"],由部署器一并安装 |
/home 被 NFS 覆盖挂载 |
本地 /home 原有内容被遮蔽 |
变更前确认为空目录;fstab 带 _netdev 避免开机阻塞;回滚 umount /home 即恢复本地目录 |
家目录用 soft 挂载 |
宿主机故障时写操作可能返回 I/O 错误,而服务端实际已写入,存在数据不一致风险 | 按"家目录优先保登录可用性"取舍(hard 会让 su - <user> 与 SSH 登录卡死);若更看重数据一致性,把 home_share.mount_options 改回 hard,重跑会自动卸载重挂 |
| 挂载判定只比对挂载源 | 漏判"仅挂载选项变更",改了 yaml 却不重挂,配置与实际长期不一致 | 两处挂载(/home 与 HA 的 /mnt/slurm-shared)的判定都已同时比对挂载源与挂载选项,共用 utils/idempotent_utils.mount_options_matched;该函数跳过 _netdev / intr 等不出现在内核挂载表的选项,避免把它们误判为漂移而反复卸载重挂 |
| SELinux enforcing 未放通 NFS 家目录 | 用户能 su 但读不了自己家目录 |
部署器自动 setsebool -P use_nfs_home_dirs on,并在 pre_check 校验 setsebool 存在 |
| LDAP 用户与本地用户名冲突 | 同名账号解析优先级混乱,登录身份与预期不符 | authselect 生成的 nsswitch.conf 为 files sss systemd(本地优先);新增 LDAP 用户时应避开节点上的本地同名账号 |
明文 ldap:// 传输 |
bind 凭据与用户认证报文在网内明文 | 当前内网且 LDAP 未启用 TLS;如需加固,改 ldaps:// 并按需调整 tls_reqcert |
| NFS 不可达导致挂载失败 | 部署中断(不产生半成品,本地 /home 保持可用) |
pre_check 先探测各节点到 2049 的连通性,任一不通即汇总退出、不做变更 |
| Lmod 需 EPEL | 内网隔离环境下装不上 Lmod | epel-release 由 Rocky 的 extras 仓库提供(无需外部网络即可安装),但 EPEL 元数据需可从网络拉取;若目标环境确实隔离,改用 Rocky 自带的 environment-modules(Tcl 版,无 hierarchy / spider,不符合 EDA 标准)或提前备离线 rpm |
TaskProlog 被接管导致既有 EDA 注入失效 |
作业里 EDA_JOB_ID / EDA_JOB_NODELIST / EDA_WORKDIR 丢失 |
Lmod 的 TaskProlog 内部透传原脚本;--module-env --rollback 自动恢复原值;关闭 module_env.enabled 时渲染器保留模板原值(不删行) |
TaskProlog 误注入 MODULEPATH |
覆盖用户 --export=ALL 的结果,提交前加载的模块在作业里全部丢失 |
只注入不变的 LMOD_* 位置变量,明确不注入 MODULEPATH(TaskProlog 在 slurmd 侧,看不到用户提交环境) |
module 是 shell function,跨不过作业边界 |
作业脚本里 module load 报 command not found |
作业脚本首行 source /etc/profile.d/zzz_site_lmod.sh(该文件自包含:先初始化 Lmod 再前置路径);SOP/RUNBOOK 均给出标准写法 |
作业脚本写成 module load x \| head |
管道让 module 在子 shell 中执行,加载静默失效,排查困难 |
文档明确禁止该写法(加载与查看分开写) |
| Lmod 目录扫描缓存 | 刚部署的模块在 module avail 里看不到,误判为部署失败 |
部署器健康检查带 LMOD_IGNORE_CACHE=yes;用户可执行 module --ignore_cache avail 或清 ~/.cache/lmod |
| 示例工具模块指向未安装的路径 | "加载成功但命令找不到",用户误以为环境正常 | modulefile 内置 isDir 守卫,工具未就位时 module load 明确报错并给出路径 |
重启 slurmd 中断作业 |
计算节点上正在跑的作业被中断 | 安装与卸载都会重启 slurmd(TaskProlog 由 slurmd 执行),执行前须确认 squeue 为空;已在 5.10 醒目标注 |
| EDA 工具本体放各节点本地 | 磁盘放不下且 5 台易不一致 | 设计为 modulefiles 与工具本体都走 NFS 共享(主控 /opt 仅余 15G,本地放不下工具) |
附录¶
A. 交付物清单¶
| 文件 | 用途 |
|---|---|
docs/SOP.md |
本文档:本次变更的实施、验证与回滚 |
docs/RUNBOOK.md |
Slurm 集群日常运行与故障处置手册 |
docs/INCIDENT-20260918-slurm-26.05部署排障.md |
本次部署排障台账与复盘 |
docs/backup/README.md |
备份台账(位置、用途、可删时机) |
{main,deployer,slurm_deployer,config_renderer,health_assets,health_ensure_deployer}.py |
实现体 |
{user_mgmt_assets,user_mgmt_deployer}.py |
用户管理能力实现体(LDAP 同步资产与部署器) |
{node_env_assets,node_env_deployer}.py |
节点基础环境实现体(命令 PATH / LDAP 认证 / 共享家目录;含可复用的 NodeEnvInstaller) |
{module_env_assets,module_env_deployer}.py |
环境模块实现体(Lmod 软件栈 / 工具家族 modulefiles / 站点配置 / Slurm 集成;含可复用的 ModuleEnvInstaller) |
config/slurm_deploy.yaml(.example) |
部署配置(实例含凭据,权限 600) |
B. 关键决策经过¶
- 共享存储为何新建导出而非改现有导出:
/srv/nfs/k8s-hdd同时承载 k8s 的 4 个 PVC, 改async会削弱 k8s 持久化数据的落盘保证。故新建/data/nfs/slurm-state, 顺带摆脱 loop 镜像的嵌套文件系统开销。实测 fsync 由 500–800ms 降至 9–12ms。 - cgroup 版本:目标系统为 Rocky 9 + cgroup v2,模板原为 cgroup v1 语法;
保留语义但剔除 v2 不支持的
ConstrainSwapSpace/AllowedSwapSpace。 - License TRES:按选择剔除
AccountingStorageTRES中的license/*项(本环境无 FlexLM)。 - QoS 强制关联:保留
AccountingStorageEnforce=associations,qos,limits,并配套自动创建 QoS 与账户层级,否则集群无法提交作业。 - 通用化改造(第二轮):原实现把旧环境标识写死为
k8s-master-01/k8s-node-01~03, 只能替换那一份特定模板;分区节点也直接沿用模板,导致"新集群 5 台、分区只覆盖 3 台"。 改为「从模板自动提取标识 + 分区按 yaml 重算」,并保留custom_config.legacy手工覆盖口子。 验证方式:构造 4 个场景(现网 3 节点、扩到 5 节点、换用prod-ctl-01/prod-cmp-01~02的另一份模板、 yaml 显式指定分区节点),13 项断言全通过。 - 用户管理能力与 LDAP 对齐:原
slurm_user_management/下两个脚本(本地组映射的slurm_user_onboarding.py、LDAP 同步的slurm_ldap_sync.sh)都是旧集群(teama/teamb/teamc账户、EDA分区、192.168.0.2LDAP)的资产,直接迁移会失败。改造为按实际读取的 LDAP 结构 生成账户:dc=rainchen,dc=com下只有ou=eda,其下 4 个部门 ou 与 8 个小组 cn。 账户层级按 DN 递归建立,用户按gidNumber关联;两套旧方案的数据源与账户模型互斥,故只保留 LDAP 一套。验证结果:新建 12 个账户(层级正确)、8 个用户关联,ldapadmin按排除列表跳过。 -
账户体系统一到 LDAP 单一来源:同步能力落地后,集群里同时存在两套维度不同的账户—— 部署时按"工种"建的
engineering/verification/synthesis/physical,与 LDAP 按"部门"建的frontend/analog/it/backend及其小组。二者名字不重叠、无对应关系,无法自动合并。经确认采用 "只留 LDAP"方案:移除 4 个 EDA 业务账户(移除前确认无任何用户关联、无在跑作业,并已备份 账户配置),并同步从sacctmgr.accounts中删去其定义,避免下次部署时被重建;仅保留管理账户root。移除后作业提交验证通过(COMPLETED 0:0)。 -
免手填机器信息:节点
cpus/memory_mb改为可留空自动探测(nproc+/proc/meminfo, 内存取物理 95%),并在pre_check增加发行版/主版本/架构校验。实测探测值 8 核 / 14944MB (物理 15730MB),与手工填写的 15000MB 基本吻合;OS 校验用「改期望值」的方式构造了 主版本不符、发行版不符、架构不符三个反例,均被正确拦截并给出可读原因。 - 节点基础环境为何做成两条入口:全新部署的用户诉求是"装完就能用",而对已就绪的集群
则需要补装且不能触碰 Slurm 服务。于是把判定与执行下沉到
NodeEnvInstaller(node_env_deployer.py),由主部署器阶段 2 与独立模式--node-env共用: 前者保证新集群一次到位,后者给存量集群补装且不重启任何 Slurm 服务。 这与既有"--health-ensure独立 + 主流程内置阶段"的模式保持一致。 - 为何用 sssd 而非 nss-pam-ldapd:RHEL 系 9 的默认认证栈就是 sssd,
authselect的sssdprofile 能一并把 NSS 与 PAM 配好;sssd 自带凭据缓存,LDAP 短暂不可达时已登录会话不受影响。id_mapping必须显式设false——LDAP 中已有真实uidNumber/gidNumber,否则节点上的 uid 会由算法随机生成,与 Slurm 记账中的用户对不上。 - 家目录为何共享而非本地创建:最初方案是在各节点用
with-mkhomedir本地建家目录,改动更小; 经确认改为 NFS 共享/home——EDA 场景下用户在不同节点登录需要看到同一份工程数据。 代价是宿主机需新增导出(/data/nfs/home),并在各节点挂载后额外放通 SELinux 的use_nfs_home_dirs(Rocky 9 默认 Enforcing 且该布尔为 off,不放通则用户读不了自己家目录)。 - 为何用"工具家族分层"而非编译器/MPI 分层:EDA 工具(cadence / synopsys / siemens)依赖 glibc
而非自编译工具链,不构成"编译器 → MPI → 应用"的依赖链。行业主流做法是把 Core 层作为家族入口,
加载后才暴露该家族的工具树;PDK 单独一族。好处是
module avail默认只显示与当前环境相关的模块 (否则一次列出上百个),并可用family()实现同族互斥,防止两家 EDA 工具的 PATH 与许可证变量 互相覆盖。实测:加载synopsys后再加载cadence,Lmod 自动替换并提示Lmod is automatically replacing "synopsys" with "cadence";而pdk与工具不同族,可共存。 - TaskProlog 为何只注入
LMOD_*位置变量:曾考虑顺带注入MODULEPATH以便作业内直接可用, 但 TaskProlog 运行在 slurmd 侧、看不到用户提交环境,一旦export MODULEPATH就会覆盖用户--export=ALL传进来的模块列表 —— 属于"看似增强、实则破坏"。故明确只注入固定不变的工具位置变量。 - 为何 modulefiles 放 NFS 而非各节点本地:内容虽小(10 个文本文件),但本地存放意味着 5 份副本、 改一处要同步五处;且后续 EDA 工具本体(数十至数百 GB)只能走共享存储,两者放一起最自然。
--module-env与主部署器阶段的职责划分:阶段 3 只落 modulefiles 与脚本,TaskProlog交给 阶段 9 的渲染器统一写。原因是主部署器的漂移检测基于"渲染结果哈希":若由阶段 3 另行编辑 slurm.conf, 下次渲染会判为漂移并覆盖,还会多触发一次服务重启。独立模式(无渲染器参与)则采用最小编辑。 两者写入的行内容完全相同(manage_slurm_conf开关控制),因此互不冲突。
C. 修订记录¶
| 日期 | 修改人 | 变更内容 |
|---|---|---|
| 2026-09-18 | 部署执行人 | 首版:三项能力改造 + 新环境部署 + 共享存储与启动告警修复 |
| 2026-09-18 | 部署执行人 | 依新版文档规范重写为三份文档,补 backup 台账、幂等与告警修复的风险项 |
| 2026-09-18 | 部署执行人 | 通用化改造:旧环境标识自动提取、分区节点按 yaml 重算、注释行纳入替换;实跑验证幂等不变 |
| 2026-09-20 | 部署执行人 | 补齐免手填能力:CPU/内存自动探测、目标系统发行版与架构前置校验 |
| 2026-09-20 | 部署执行人 | 新增 --user-mgmt:LDAP → Slurm 账户与用户定时同步,含安装前环境检查与卸载 |
| 2026-09-20 | 部署执行人 | 账户体系统一到 LDAP 单一来源:移除 EDA 业务账户及其配置定义,仅保留 root |
| 2026-09-21 | 部署执行人 | 第二轮:补齐用户可用性——命令 PATH(slurm.path_env)、LDAP 认证(user_mgmt.system_auth,--node-env)、共享家目录(home_share);主部署器新增阶段 2;宿主机新增 /data/nfs/home 导出 |
| 2026-09-21 | 部署执行人 | 家目录挂载选项由 rw,hard,intr,_netdev 调整为 rw,soft,_netdev(避免宿主机故障时登录卡死);挂载选项判据下沉为共享函数 utils/idempotent_utils.mount_options_matched,/home 与 HA 共享存储两处统一使用;校正 slurm_deployer.py 中过时的阶段编号注释;修正文档中 /etc/exports 与账户层级两处不一致 |
| 2026-09-22 | 部署执行人 | 第三轮:新增环境模块能力(Lmod 软件栈、工具家族分层 modulefiles、站点配置、Slurm TaskProlog 集成),支持 --module-env 独立安装/卸载;主部署器新增阶段 3(共 13 阶段);宿主机新增 /data/nfs/modulefiles 导出;config_renderer 支持渲染 TaskProlog 并与既有 task_prolog_eda.sh 透传共存 |
来源:
/home/rain/Documents/slurm/slurm_ins/docs/SOP.md| 最后更新:2026-09-26 15:06(由build/sync.py同步,请勿在站点侧修改)