SOP —— /projects 共享存储纳管(LSF 执行节点 + 提交节点)¶
- 主题:给 LSF 节点补齐
/projects(EDA 作业共享目录),并纳入部署器阶段1 的受管挂载项, 避免手工挂载造成漂移。 - 变更日期:2026-10-07
- 触发来源:slurm_ins《EDA 集群存储与服务拓扑巡检报告》(2026-10-06 实测 / 10-07 复核)
§二 G1 与 §三「项目落点」表 → 落点
lsf_ins HANDOFF §3 #5。 - 交付物:本目录(
projects_mount/),含本文档与backup/README.md。
一、背景¶
从统一提交节点 .28(hpc-submit)提交、脚本内引用 /projects 的作业,落到执行节点
(.25–.27)后因路径不存在而失败——三台执行节点缺该挂载。取证结论:
| 主机 | 角色 | /projects 变更前状态 |
|---|---|---|
.23 / .24 |
master-01/02 | 无挂载、无 fstab(MXJ=0 不接作业,无需求) |
.25 / .26 / .27 |
lsf-work-01~03 | 无目录、无挂载、无 fstab |
.28 |
hpc-submit | 有挂载但 /etc/fstab 无记录(手工挂载,重启即丢) |
宿主机 .249 早已导出 /data/nfs/projects(rw,async,no_subtree_check,no_root_squash,
允许 192.168.31.0/24),前置条件具备。
本环境 NFS 挂载由部署器阶段1(stages/nfs_share.py)统一管理(三态探测 + fstab 持久化 +
漂移检测)。若用 ssh/脚本手工挂载,部署器无法感知该挂载项,--drift 会漏检、复跑也不会收敛
——因此本次改部署器而非手工操作。
二、目标¶
变更完成后应达到的可验证状态:
.25–.27三台执行节点:/projects已挂载(192.168.31.249:/data/nfs/projects,nfs4,rw), 且/etc/fstab有持久化条目;.28:补齐/etc/fstab条目(不重挂,服务不中断);/projects成为部署器阶段1 的受管项:--drift可检测其漂移,复跑幂等(第二次零变更);- 端到端:从
.28提交引用/projects的作业落到执行节点后能正常访问该路径。
三、前置条件¶
- 宿主机
.249已导出/data/nfs/projects(外部依赖,本工程不代建); - 操作机具备免密 sudo(
sudo -n exportfs -v可用);节点侧已装nfs-utils(阶段0 负责); - 节点 SSH 免密(root);
.25–.27上无 RUN 作业(本次不动 LSF 守护,仅挂载,风险低); - 配置文件中
nfs.projects_*四项齐备(缺一即整项不纳管)。
四、影响范围¶
| 项 | 内容 |
|---|---|
| 主机 | .25、.26、.27、.28(4 台);.23/.24 不在范围内(MXJ=0 不接作业) |
| 组件 | /etc/fstab(追加挂载行)、新增挂载点 /projects;部署器阶段1 实现体与配置 |
| 停服 | 否。/projects 原为不存在路径,挂载不影响运行中的进程;.28 仅追加 fstab 行,不重挂 |
| 窗口 | 无窗口要求;单次执行实测约 61 s(4 台并发探测 + 变更) |
| 在跑作业 | 变更前 .25–.27 无 RUN 作业(本次不重启 LSF、不动守护,作业中断面为零) |
依据巡检报告 §五 验收判据,本次只做「补目录」;报告里同批的「修挂载」 (
.21/.25/.26/.27的/mnt/lustre)归属 lustre 项目(lustre_ins HANDOFF §3.1 #14), 不在本次范围。
五、分步操作¶
实现体:deploy/lsf/stages/nfs_share.py(NfsShareModule);配置:
deploy/lsf/config/lsf_deploy.yaml。以下为等价操作序列。
步骤 1:阶段1 挂载项配置化(实现体扩展)¶
原实现把挂载项硬编码为两组(lsf / home):
@property
def _pairs(self):
return [(self.lsf_mp, self.lsf_export), (self.home_mp, self.home_export)]
改为按节点返回受管项,并支持每项独立挂载选项:
def _mounts_for(self, node):
mounts = [("lsf", self.lsf_mp, self.lsf_export),
("home", self.home_mp, self.home_export)]
if (self.projects_export and self.projects_mp
and node.get("name") in self.projects_hosts):
mounts.append(("projects", self.projects_mp, self.projects_export))
return mounts
probe() / execute() 的循环、pre_check() 的导出检查、写测试均改走该方法;
新增 _opts_for(key) 与静态判定 _opts_satisfied()。
坑(本次实测):.28 的 /projects 实挂选项里 actimeo=30 已被内核展开为
acregmin=30,acregmax=30,acdirmax=30,字符串比对会判「选项漂移」→ 触发无谓重挂
(对提交节点是中断风险)。故 _opts_satisfied() 对 actimeo=N 与三者展开形式做等价判定。
(首次实现把方向写反——遍历实挂值展开,而非判定期望值——被 dry-run 清单抓到:
.28 出现 opts_projects 待变更项,修正后仅剩 fstab_projects。)
步骤 2:配置新增(生产配置 + 样例 + 校验白名单)¶
nfs:
# …… 原有 server / export_cidr / export_opts / lsf_* / home_* / mount_opts 不变
projects_export_path: /data/nfs/projects
projects_mountpoint: /projects
projects_mount_opts: "rw,hard,timeo=600,retrans=2,noatime,actimeo=30,_netdev"
projects_hosts: [lsf-work-01, lsf-work-02, lsf-work-03, hpc-submit]
- 选项口径与
.28既有挂载一致:用hard而非 lsf/home 的soft——作业目录若遇 NFS 抖动,soft可能静默返回错误数据,比「卡住」更危险; projects_hosts按节点name限定纳管范围(与既有lsf.noexec_hosts同款用法); 两台 master 因MXJ=0不接作业而不纳入,避免在管理节点引入hard挂载;- 同步更新
config/lsf_deploy.yaml.example与utils/config_validate.py的KNOWN_KEYS(否则配置校验会把新字段报成「幽灵字段」)。
步骤 3:备份节点 /etc/fstab(高危动作前置)¶
写入 fstab 属高危(写坏影响开机引导),动手前抓快照:
TS=$(date +%Y%m%d-%H%M%S)
for h in 25 26 27 28; do
mkdir -p "projects_mount/backup/remote/192.168.31.$h/etc"
ssh root@192.168.31.$h cat /etc/fstab \
> "projects_mount/backup/remote/192.168.31.$h/etc/fstab.bak.$TS"
done
预期:4 个文件非空(.25–.27 各 19 行、.28 18 行)。清单见 backup/README.md。
步骤 4:预演(零副作用)¶
cd deploy/lsf
.venv/bin/python main.py -c config/lsf_deploy.yaml --dry-run --stage nfs
预期变更清单(实测):
- 192.168.31.25: mount_projects / opts_projects / fstab_projects
- 192.168.31.26: mount_projects / opts_projects / fstab_projects
- 192.168.31.27: mount_projects / opts_projects / fstab_projects
- 192.168.31.28: fstab_projects ← 仅补 fstab,不重挂
失败判断:若 .28 出现 opts_projects,说明选项等价判定失效(会无谓重挂),先修实现体再执行。
步骤 5:执行阶段1¶
.venv/bin/python main.py -c config/lsf_deploy.yaml --stage nfs
节点侧等价命令(以实现体为准,逐项幂等):
# 写入 fstab(先剔除同名旧行,再追加)
ssh root@192.168.31.25 "awk -v p=/projects '\$2 != p' /etc/fstab > /tmp/fstab.ksf && \
cat /tmp/fstab.ksf > /etc/fstab && rm -f /tmp/fstab.ksf"
ssh root@192.168.31.25 "echo '192.168.31.249:/data/nfs/projects /projects nfs \
rw,hard,timeo=600,retrans=2,noatime,actimeo=30,_netdev 0 0' >> /etc/fstab"
# 挂载(高危:覆盖挂载点)
ssh root@192.168.31.25 "mkdir -p /projects && mount -t nfs \
-o rw,hard,timeo=600,retrans=2,noatime,actimeo=30,_netdev \
192.168.31.249:/data/nfs/projects /projects"
预期:状态: success,耗时约 61 s,日志无 mark_failed。
失败判断:任一台挂载失败 → 实现体即中止并返回失败(失败阈值 1 台);按第 7 章回滚后重跑。
六、验证¶
# ① 幂等复跑:应「状态已一致,无漂移(全跳过)」
cd deploy/lsf && .venv/bin/python main.py -c config/lsf_deploy.yaml --stage nfs
# ② 独立漂移检测:全阶段无漂移,退出码 0
.venv/bin/python main.py -c config/lsf_deploy.yaml --drift; echo "rc=$?"
# ③ 实机挂载与持久化
for h in 25 26 27 28; do
ssh root@192.168.31.$h 'findmnt -n -o TARGET,SOURCE /projects; grep -c projects /etc/fstab'
done
# ④ fstab 语法校验(0 parse errors / 0 errors)
ssh root@192.168.31.25 "findmnt --verify"
实测结果(2026-10-07):
| 检查项 | 结果 |
|---|---|
| 幂等复跑 | 阶段1「状态已一致,无漂移(全跳过)」 |
--drift |
全阶段无漂移,rc=0 |
| 4 台挂载 | 均 192.168.31.249:/data/nfs/projects(nfs4,rw),容量 1.8T / 用 38%,与 .28 一致 |
| fstab 条目 | 4 台各 1 条 |
| fstab 语法 | .25:0 parse errors, 0 errors(2 条 warning 属 /mnt/lustre,非本次范围) |
端到端作业验收(G1 描述的失败场景):
ssh root@192.168.31.28 "source /data/nfs/lsf/lsf/conf/profile.lsf; \
echo 'hostname; df -h /projects | tail -1; ls /projects | head -3; echo PROJECTS_ACCESS_OK' \
| bsub -o /data/nfs/lsf/.proj_probe.out -n 1"
实测:作业 1047 从 hpc-submit 提交,执行位 lsf-work-03,输出含
192.168.31.249:/data/nfs/projects ... /projects、cad/custom/design、PROJECTS_ACCESS_OK,
DONE。
坑(本次实测):作业输出路径若写
/tmp/x.out,落在执行节点本地盘,提交节点读不到 (首次验证cat报文件不存在);输出须写共享路径(如/data/nfs/lsf/、家目录 NFS)才能取回。
七、回滚¶
备份位置:projects_mount/backup/,台账见 backup/README.md(含部署器 4 个文件与
节点 4 份 fstab 快照)。
回滚步骤(先节点侧、后部署器侧):
# ① 卸载并还原 fstab(逐台)
for h in 25 26 27 28; do
ssh root@192.168.31.$h "umount /projects"
ssh root@192.168.31.$h "cat > /etc/fstab" \
< projects_mount/backup/remote/192.168.31.$h/etc/fstab.bak.20261007-084852
done
# ② 回退部署器(实现体 + 配置 + 校验)
cd projects_mount
cp -p backup/deploy/lsf/stages/nfs_share.py.bak.20261007-084443 \
../deploy/lsf/stages/nfs_share.py
cp -p backup/deploy/lsf/config/lsf_deploy.yaml.bak.20261007-084443 \
../deploy/lsf/config/lsf_deploy.yaml
cp -p backup/deploy/lsf/utils/config_validate.py.bak.20261007-084443 \
../deploy/lsf/utils/config_validate.py
回滚后验证:findmnt /projects 无输出(4 台);--drift 恢复为「仅 lsf/home 两组受管」且无漂移。
注意:umount /projects 属高危——若 .28 上有进程正在使用该路径会失败,须先确认无占用。
八、风险说明¶
| 风险 | 说明与缓解 |
|---|---|
写坏 /etc/fstab 致开机异常 |
变更前抓 4 台快照(步骤 3);findmnt --verify 语法校验通过;回滚一条命令还原 |
无谓重挂中断 .28 服务 |
actimeo 等价判定保证 .28 只补 fstab 不重挂(dry-run 清单已核实) |
hard 挂载遇宿主机故障卡住 |
与 .28 既有口径一致、且 .25–.27 的 /tools 已是 hard;作业目录用 hard 是刻意选择(避免 soft 静默返回错误数据)。宿主机 .249 与 Slurm 共用,其可用性由既有运维覆盖 |
纳管 hpc-submit 越出原范围 |
该节点原已有挂载但缺 fstab(重启即丢),补齐属修正既有缺陷;本次不重挂、不中断服务 |
| 与 Slurm 侧重复管理 | 节点 /tools、/mnt/lustre 由 slurm 侧管理,本次不触碰;/projects 只由 LSF 部署器管理,无交叉 |
来源:
/home/rain/Documents/LSF/lsf_ins/projects_mount/SOP.md| 最后更新:2026-10-07 08:56(由build/sync.py同步,请勿在站点侧修改)