BASELINE — 稳定层(环境事实 / 机制陷阱 / 命令速查)¶
- 定位:本项目(Slurm 26.05 主备集群)的稳定事实层,装「换个会话、换个项目、换个 cell 仍然成立」的内容。
- 不被注入:与
HANDOFF.md不同,本文件不经 SessionStart 注入,由HANDOFF.md第 5 节指针按需读取。 - 分工:HANDOFF 只装变化(现状 / 待办 / 红线 / 关键基线数字);稳定内容一律落本文件。
- 档位标注:
【已确认】=有实测证据;【未验证】=未证实;【待决策】=尚未定论。 - 维护触发:本轮往 HANDOFF 新增条目时,须回一句「BASELINE 是否需同步加/改一行」;入口三问第 ① 问成立的内容一律进本文件。
1. 集群拓扑与登录【已确认】¶
本项目直接管理的 Slurm 集群,以及相邻的 Lustre / LSF 设施:
| 用途 | 主机 | 说明 |
|---|---|---|
| Slurm 控制 | .16 / .17 |
主 / 备,HA;.16 兼 modulefile 内容生成节点(写 NFS 共享盘) |
| Slurm 计算 | .18 / .19 / .20 |
slurm-work-01~03 |
| Slurm 提交节点 | .28 |
hpc-submit,无 slurmd |
| LSF | .23 / .24(主控主备,MXJ=0 不接作业)、.25 / .26 / .27(计算 01~03,唯一执行节点,池 24 槽) |
与本集群共用 modulefiles |
| Lustre | .21(MGS/MDS)、.22(OSS) |
导出 edafs,客户端挂 /mnt/lustre |
| License | .29 |
FlexLM |
| K8s(相邻,不在本项目内) | .10 / .13 / .14 / .15 |
master-01 + node-01~03 |
- 本机
192.168.31.249是共享 KVM 宿主(另承载 k8s / LSF / Lustre 虚机),对上述主机 root 免密 ssh;.11/.12/.30无此主机,.249/.250是本机自身、不要当远程目标。 - 全部 Rocky Linux 9.8。宿主虚盘池:
ssd-pool→/kvm/img、hdd-pool→/data/kvm/img。 - 凭据取值:
~/.secrets/prod.env(600,须显式source,用法见rainchen-envskill §3);凭据值不入文档。 - 工程根 =
/home/rain/Documents/slurm/slurm_ins,venv 为.venv/。
2. 存储三层【已确认】¶
权威源:rainchen-env skill §5 与 k8s_ins/env-inventory/hpc-simulation-env.yaml。三台计算节点磁盘与挂载口径如下:
| 层 | 路径 | 用途 | 生命周期 |
|---|---|---|---|
| Tier1 NFS(持久) | /projects(读写,LDAP 组 2775)、/home;/tools、/pdk 只读 |
源数据与最终结果 | 长期 |
| Tier0 Lustre(跨节点共享临时) | /mnt/lustre/scratch/users/<用户>/<jobid> |
workdir;多节点作业必须用它。容量 295G,单 MDT / 单 OST,无法条带化 | 老化 timer 30 天 |
| 本地(节点私有临时) | /local_scratch/users/<用户>/<jobid>,即 $TMPDIR(作业 prolog 注入) |
编译中间产物、工具临时文件,把元数据压力从共享层卸载 | 老化 timer 7 天 |
数据流:/projects 读输入 → 在 Lustre scratch 建 workdir → 中间产物写 $TMPDIR(本地)→ 结束后只把必要文件 stage-out 回 /projects。
已知坑:
- EDA 编译产物默认落 cwd(VCS 的
./csrc、./simv),不在$TMPDIR——要真正用上本地层须cd "$TMPDIR",或用-Mdir/-raw显式指向本地,否则元数据压力仍全压共享层。 - 临时数据不会自清,靠三层兜底:作业脚本
trap 'rm -rf -- "${TMPDIR:-}"' EXIT+ Slurm Epilog(成功即删 / 失败改名留现场)+ 老化 timer(本地 7 天 / Lustre 30 天)。 mnt-lustre.mount无自愈:客户端 fstab 带nofail,MDS 客户端恢复窗口拒连时静默跳过,unit 落failed后不自动重试——2026-09-29 起.18/.19/.20潜伏 4 天无人察觉,即此机制所致。处置:systemctl restart mnt-lustre.mount(幂等)。根因与证据详env_facts_sync_20261004/SOP.md附录 A。 现已由机制 B 自愈覆盖(2026-10-07 起,同日两次扩面):.16上slurm-cluster-health.timer(15min)巡检lustre_guards中该 unit 处于failed的机器即reset-failed+start;只判失败态、不涉及调度状态(机制 AHealthCheckProgram仍关闭,未引入 DRAIN)。lustre_guards现为 8 台:.18–.20/.28(Slurm 侧,来自nodes.compute+nodes.submit)+.21/.25–.27(来自slurm.health_ensure.lustre_extra_guards)。巡检靠 SSH,故.16/.17→ 上述 8 台须有 root 公钥免密——缺失时脚本记 WARNING「无法探测」并跳过;sync_status()亦须能比对cluster.json,否则改配置会被「零变更」幂等短路吞掉;pre_check现已前置校验全部自愈对象的 SSH 可达性(不可达即DeployError、零变更)。四处修复详lustre_mount_selfheal_extend_20261007/SOP.md与selfheal_guards_hardening_20261007/SOP.md。/mnt/lustre的 fstab 归属存在跨工程冲突:.28(hpc-submit)的 Lustre 挂载由lustre_ins的add-clients-25-28写入(选项defaults,nofail),而slurm_ins storage_layout期望defaults,noatime,nofail(storage_layout.tier0)——两个工程对同一挂载点期望不同,谁后跑谁生效。2026-10-07 实测.28缺noatime(.18–.20正常)即由此产生。已对齐(2026-10-07):lustre_ins客户端模板(modules/client_mount.py::_fstab_entry())改为defaults,noatime,nofail;.28现场已由--storage-layout补齐(幂等零变更);.21/.25–.27的现场条目已由lustre_ins侧补齐(同日,其 HANDOFF §3.1 #16 已结案)。归属边界:本工程storage_layout只管node_groups(compute + submit)——.25–.27的 fstab 不由它写。
节点接入判据(2026-10-06 讨论定):判据是「该机上要执行什么」,不按 master / 角色套用。
- LDAP:只要该机跑调度守护进程或允许提交 / 管理命令,就必须接——① NSS 要解析作业提交者(否则
squeue/sacct只有数字,QoS 与账户关联断);② 记账需稳定的 uid↔user 映射(slurmdbd);③ LSF 的b*管理命令要求lsfadmins组成员,该组本身就在 LDAP。与挂不挂 Lustre 无关。 - NFS:按挂载点分。控制节点要
/home(域用户默认 shell 是/bin/csh,缺家目录登录即报错)、/opt/modulefiles(排障用)与 Slurm state 目录/mnt/slurm-shared(HA 必需);不要/projects、/tools、/pdk——除非开放该节点提交作业(sbatch需在提交节点 chdir 到 submit_dir)。 - Lustre:只在跑作业的节点挂。控制节点不跑作业、无跨节点共享工作区需求,挂了只是多一个内核模块与故障域。
NFS 挂载参数与导出(2026-10-07 定):/home、/opt/modulefiles、/data/nfs/lsf 有意使用 soft
——实测 hard 延迟偏高,本环境为测试 / 学习用途,接受 soft 在服务端抖动时静默 EIO 的风险;
/projects、/tools、/pdk 使用 hard,timeo=600,retrans=2,noatime,actimeo=30。
/tools、/pdk 的服务端导出为 ro(2026-10-07 起;由 storage_layout.tier1_exports[].export_options 维护,客户端亦 ro 挂载);其余导出为 rw,async,no_root_squash。
/etc/exports 由 storage_layout_deployer.py 管理(全局 export_options + 条目级覆盖),勿手工改——ensure_export() 幂等判据已含内容比对,手工改动会在下次 --storage-layout 时被识别并改回配置源的值。
纳管节点的 NFS /etc/fstab 条目同由该部署器管理(node_groups = compute + submit):judge_tier1() 幂等判据已含 fstab 条目比对——「挂载点已挂但 fstab 缺条目」会判 PENDING 并由部署器补齐(2026-10-07 修复;此前只判挂载态与参数,.28 的 /projects、/tools 因此长期不在 fstab,重启即丢)。
3. 机制性陷阱【已确认】¶
- Lmod family 两级语义:家族级
family_tag管跨厂商互斥、工具级标签管同工具多版本互斥;工具级标签不得与家族级同名。改标签即改对外行为,须重跑--module-env并逐台复验。 - csh 不读
*.sh:LDAP 用户 loginShell 是/bin/csh,凡是*.sh版注入都必须另出*.csh——Lmod 站点脚本、slurm-path、slurm_configless均已双轨(slurm_csh_profile_20261005补齐后);csh 侧只由/etc/csh.login、/etc/csh.cshrc遍历/etc/profile.d/*.csh加载,两侧互不通用。自检 csh 环境必须env -i(否则继承 sshd 的BASH_ENV会假通过),且不得用bash -lc代替su - <user>(后者才走用户真实默认 shell);csh 判重用switch/case,命令行里不得出现$紧跟引号(会报Illegal variable name)。 - 作业脚本首行
source /etc/profile.d/zzz_site_lmod.sh;module load禁放管道(管道是子 shell,父 shell 拿不到环境变量)。 - Epilog 脚本禁用
set -u:变量未定义会让 Epilog 返回非 0 → 节点被 DRAIN;验证 Slurm 钩子必须用env -i复现 slurmd 环境。 - 提交节点无 slurmd:configless 靠
/etc/profile.d/slurm_configless.{sh,csh}里的SLURM_CONF_SERVER(HA 时值为全部控制节点列表、两轨同源渲染),脚本内需显式设置。 qemu-img探测运行中的虚盘必须加--force-share,否则写锁失败被误判为「文件不存在」。- 停 dnf 进程勿用
pkill -f "dnf install"(会匹配到执行该命令的 shell 自身),用精确 PID。 - timer 用
Wants=非Requires=,勿回退。 - 本地 scratch 格式化不可逆:目标设备由宿主 virsh XML 推导,不依赖盘名;宿主命令需
sudo免密。 - LSF 三台
.25/.26/.27不在部署器nodes内:csh 站点脚本由一次性脚本下发、重建需重跑;三台与 slurm 六台同挂一份/data/nfs/modulefiles→ 各节点/opt/modulefiles,module 改动一并生效。 - Lmod 站点扩展(SitePackage.lua):
module avail尾部提示块来自messageDir/en.lua的avail条目,由StandardPackage的msgHook在Hub:avail()末尾输出——无单独开关、且与模块列表同走 stderr(2>/dev/null会连列表一起丢)。本站用LMOD_PACKAGE_PATH=/etc/lmod/site前置进package.path,以hook.register("msgHook", fn)(默认 replace 动作)覆盖;只屏蔽avail,其余消息沿用与StandardPackage同构的格式化。改messageDir/en.lua无效(rpm 文件,升级即被覆盖)。临时清爽用module -q avail;LMOD_QUIET=1会连警告一起压,勿全局设。 - Lmod 模块名补全只对 bash / zsh / fish 提供:
init/下有lmod_bash_completions、zsh(compdef)、fish_tab_completion,而init/csh、init/tcsh只做环境初始化(定义module/ml别名),不含任何complete定义。故 csh/tcsh 下module load <TAB>不补模块名(不是 csh 不支持补全,是 Lmod 未为其实现)。 - 生成器只写不删:取消某模块后,历史 modulefile 仍留在共享盘继续被扫到。须在
module_env_assets.obsolete_module_file_dirs登记路径(目录或单个文件皆可,2026-10-05 起),部署器才在内容主节点.16先tar备份到/var/backups/slurm/modulefiles/再删除(--rollback自动还原)。 - 同工具多版本:多版本并存时
module load <工具>(不带版本)会多重匹配报错,须在工具目录放.modulerc.lua,用module_version("<工具>/<版本>", "default")指定默认版本、额外别名(如latest)作稳定入口。 - 作业钩子链与分发源:
slurm.conf挂 6 项——Prolog/Epilog/PrologSlurmctld/EpilogSlurmctld=/usr/local/slurm/{prolog,epilog}[_slurmctld]_eda.sh;TaskProlog=/etc/slurm/task_prolog_lmod.sh(先转发/usr/local/slurm/task_prolog_eda.sh再注入 Lmod 变量,见其头注释);TaskEpilog=/usr/local/slurm/task_epilog_eda.sh(只写一行日志、不做清理)。源模板唯一事实源 =slurm_conf_old/pro_epilog/,由slurm_deployer.py阶段 10 与scratch_gc_assets.DEFAULT_HOOK_SOURCE_DIR分发到各节点 prefix 目录——节点上的副本禁止手改(会被部署覆盖),改源模板后走部署器下发。复核发现【未验证】:.16与.18的/usr/local/slurm/epilog_eda.sh大小不一致(1306 B / 3570 B),而 Prolog/Epilog 只在实际执行节点(计算节点)生效——.16那份疑为陈旧副本,动手前逐节点核对。 - Epilog 的
/tmp清理只覆盖 jobid 命名模式:epilog_eda.sh的「清理 /tmp 残留」仅find /tmp -maxdepth 3 -name "slurm${SLURM_JOB_ID}*" -delete与vcs*${SLURM_JOB_ID}*(另/dev/shm、cgroup、本作业 scratch)。文件名不带 jobid 的残留一律清不到——Cadence 遗留的/tmp/.X11-unix/X80(X socket)、/tmp/.X80-lock、/tmp/clsbd.<user>.<pid>即属此类,故「钩子在跑却没清掉」不等于钩子失效。2026-10-05 起已覆盖:epilog_eda.sh第 3 段专门清理这三类残留,判据是仅当无对应 X 进程时删(fuser优先、ss兜底、两者皆无则保守保留;lock内 PID 存活亦保留),整段以|| true调用不影响 Epilog 退出码。 health_assets.py渲染正则的.*$陷阱【已确认】:render_health_check_sh()与render_watchdog_py()的 pattern 带re.S,结尾若写.*$会跨行一路吃到文件尾($只在 EOF 匹配),把模板后半段整体替换成空壳——表现为「脚本下发成功却什么都不做」。2026-10-07 定位:现场.18:/usr/local/bin/slurm_health_check.sh仅 1468 B(= 模板前 26 行注释 + 渲染块)即该缺陷的历史产物,故机制 A/B 从未真正工作过。正确写法[^\n]*$;离线自测须断言渲染产物长度与关键 token(class、def main()、def fix_cluster)。- 健康巡检层(机制 B)现状【已确认】:
slurm-cluster-health.timer装于.16/.17(15min + 开机 3min 触发),巡检靠 SSH 到各节点,故.16/.17→.18–.20/.28已配 root 公钥免密;机制 A(HealthCheckProgram,失败即 DRAIN 节点)仍关闭(install_healthcheck: false),启用属调度语义变更须单独决策。 - Cadence ICRP 的 X 显示残留是故障放大器:
runICRP<N>启动cdsVncserver :80;节点上若留有无主 socket / lock(对应 X server 早已退出),后续进程每次判:80被占而降级:81或直接建不起会话 → 上层 ADE-XL 派发链卡死。判定可删:socket 在、pgrep无对应 X 进程、59xx/60xx/600x无监听(/tmp是节点本地盘、不共享,须进节点操作);删前必须校验。清残留只是止血,根治已由epilog_eda.sh第 3 段落地(2026-10-05,档案epilog_xdisplay_cleanup_20261005/SOP.md、运维处置见 RUNBOOK 场景 J);消费方在eda_tools_ins/design的 ADE-XL 经 Slurm 派发链。 - 共享库同名副本会遮蔽
.pth挂载(去遮蔽):工程utils/下若放共享库同名文件(paramiko_module.py/logger_module.py/config_module.py等),会覆盖共享库版本、使.pth名存实亡;只收其中一部分会更糟——logger_module变成两份会让两个log_manager分家、静默丢日志(2026-10-07 实测paramiko日志行 194 → 0)。判据:~/.trae-cn/skills/deployment-tool-engineering/references/scripts/shared_lib_divergence_check.py --root <工程根>,下方「同名副本 / 版本落后」须均为 0。本工程utils/三份副本已于 2026-10-07 全部删除、改走.pth(paramiko_unify_20261007/SOP.md)。
4. 命令速查【已确认】¶
Lmod:
module -q avail # 交互上要清爽时(屏蔽 avail 提示,列表完整)
module --config | grep -i 'Site Pkg location' # 确认站点扩展已加载(未生效时显示 standard)
集群状态:
/usr/local/slurm/bin/sinfo -N -o '%N %T %C'; /usr/local/slurm/bin/scontrol ping
systemctl is-active munge slurmdbd slurmctld # 计算节点换成 slurmd
journalctl -u slurmctld -n 50 --no-pager
systemctl restart mnt-lustre.mount # Tier0 掉挂载时(幂等)
/usr/local/slurm/bin/scontrol update NodeName=<节点> State=RESUME # 恢复 DRAIN
部署器(在工程根 /home/rain/Documents/slurm/slurm_ins 下,venv .venv/):
.venv/bin/python main.py --config config/slurm_deploy.yaml # 幂等验收
.venv/bin/python main.py --config config/slurm_deploy.yaml --module-env --dry-run
子命令(互斥):无(全量部署)/ --node-env / --module-env / --user-mgmt / --health-ensure / --local-scratch / --storage-layout / --scratch-gc / --submit-node。
专项自检:
# 跨厂商共存(六台任一)
ssh root@192.168.31.18 'bash -lc "module load cadence; module load virtuoso/IC06.17.700; module load siemens; module load calibre/2015.2_36.27; module list"'
# 提交节点就绪
ssh root@192.168.31.28 "systemctl is-active munge; findmnt -rno TARGET -t nfs,nfs4"
# 存储三层与 scratch 可写
findmnt -no SOURCE,FSTYPE -M /mnt/lustre
ls /mnt/lustre/scratch # 预期 projects/ tmp/ users/
完整流程见 RUNBOOK.md 第四章。
5. 关键基线数字【已确认】¶
- 部署器复跑:第二次须零变更、全跳过(幂等验收口径)。
- 存储写入延迟:9–12 ms。
slurm_insdry-run 墙钟基线:≈10 s(连接复用 + 只读探测缓存 + 主机间并发 + 同台拼 shell 之后;改造前 221 s)。
来源:
/home/rain/Documents/slurm/slurm_ins/docs/BASELINE.md| 最后更新:2026-10-08 13:29(由build/sync.py同步,请勿在站点侧修改)