跳转至

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-env skill §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;只判失败态、不涉及调度状态(机制 A HealthCheckProgram 仍关闭,未引入 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_ins dry-run 墙钟基线:≈10 s(连接复用 + 只读探测缓存 + 主机间并发 + 同台拼 shell 之后;改造前 221 s)。

来源:/home/rain/Documents/slurm/slurm_ins/docs/BASELINE.md | 最后更新:2026-10-08 13:29(由 build/sync.py 同步,请勿在站点侧修改)