SOP — 自愈对象扩至 .21 + pre_check 增「自愈对象 SSH 可达性」预检¶
- 主题目录:
selfheal_guards_hardening_20261007/ - 执行日期:2026-10-07
- 类型:C 类变更(自愈对象扩面 + 部署器门禁加固 + 节点间免密)
- 关联:
lustre_insHANDOFF §3.1 #19(本变更结案);上一轮扩面见lustre_mount_selfheal_extend_20261007/SOP.md
1. 背景¶
两件事合并执行:
.21纳入挂载自愈(lustre_ins#19):.21是 MGS+MDT 同机客户端,与其余客户端同源配置、同样出现过mnt-lustre.mountfailed,但此前不在巡检范围内。pre_check增可达性预检(上一轮遗留建议):上一轮查出「.16→.25–.27免密缺失 → 巡检静默跳过 → 自愈形同虚设且无任何痕迹」,根因是部署器从不校验自愈对象的 SSH 可达性。本次把该检查前移到pre_check,把这类静默失效挡在部署前。
执行中再次印证:pre_check 尚未加上时先手工核实——.16 → .21 免密同样缺失(Permission denied (publickey)),.17 还缺 known_hosts。若不补,.21 纳入后同样会静默失效。
2. 目标¶
| 项 | 可验证状态 |
|---|---|
| 自愈对象 | .16 的 cluster.json 中 lustre_guards = 8 台(原 7 台 + .21) |
| 可达性预检 | 真实执行时若任一自愈对象从控制节点 SSH 不可达 → DeployError 阻断、零变更;dry-run 只告警 |
| 免密 | .16/.17 → .21 root 免密可用(严格模式亦通过) |
| 幂等 | 部署器复跑零变更;巡检无新增告警 |
| 边界 | 不改自愈动作逻辑、不改调度状态、不重启节点 |
3. 前置条件¶
- root 免密可达
.16/.17(控制节点)与.21(MGS+MDT) .21的/mnt/lustre处于active(当前如此;判据只在failed时动作,故active时巡检为 no-op)- 工程 venv:
/home/rain/Documents/slurm/slurm_ins/.venv/
4. 影响范围¶
| 对象 | 变更内容 | 停服 | 窗口 |
|---|---|---|---|
config/slurm_deploy.yaml |
lustre_extra_guards 增 .21 一项 |
— | 秒级 |
health_ensure_deployer.py |
pre_check() 增可达性检查 + 新方法 _unreachable_lustre_guards() |
— | 秒级 |
.16 / .17 |
下发新 cluster.json(8 台) |
否 | 秒级 |
.21 |
追加 .16/.17 公钥到 authorized_keys |
否 | 秒级 |
- 不重启任何节点;
.21为 Lustre 服务端节点,但自愈只操作客户端挂载单元,与其 MGS/MDT 服务无关 - 巡检动作不变(仅
failed才reset-failed + start)
5. 分步操作¶
步骤 1:把 .21 写入自愈对象清单¶
# config/slurm_deploy.yaml → slurm.health_ensure
# lustre_extra_guards:
# - {hostname: "lustre-mgs-01", ip: "192.168.31.21"}
步骤 2:补 .16/.17 → .21 的 root 免密¶
ssh root@192.168.31.16 'cat /root/.ssh/id_*.pub' | head -1 > /tmp/k16.pub
ssh root@192.168.31.17 'cat /root/.ssh/id_*.pub' | head -1 > /tmp/k17.pub
scp /tmp/k16.pub /tmp/k17.pub root@192.168.31.21:/tmp/
ssh root@192.168.31.21 "cp -n /root/.ssh/authorized_keys /root/.ssh/authorized_keys.bak.\$(date +%Y%m%d-%H%M%S); \
mkdir -p /root/.ssh && chmod 700 /root/.ssh && touch /root/.ssh/authorized_keys; \
cat /tmp/k16.pub /tmp/k17.pub >> /root/.ssh/authorized_keys; \
sort -u /root/.ssh/authorized_keys -o /root/.ssh/authorized_keys; chmod 600 /root/.ssh/authorized_keys"
# `.17` 首次连接需写 known_hosts(否则严格模式报 Host key verification failed)
ssh root@192.168.31.17 'ssh -o StrictHostKeyChecking=no -o BatchMode=yes root@192.168.31.21 hostname'
坑:验证连通性必须看完整输出 / 退出码——首行常是 Warning: Permanently added ...,错误行在第二行;上一轮即因只看首行而误判「免密可用」。
步骤 3:pre_check 增可达性检查¶
在 health_ensure_deployer.py::pre_check() 的 "pre_check 通过" 之前插入:对 install_watchdog 为真时,调用 _unreachable_lustre_guards();非空则 dry-run 告警 / 真实执行 raise DeployError。新方法把全部对象拼成一段脚本在控制节点上一次下发(不逐台往返),规则:
# 等价判据(在控制节点 .16 上执行,逐对象)
ssh -o BatchMode=yes -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@<对象IP> true \
>/dev/null 2>&1 && echo OK_<i> || echo NO_<i>
预期:全部 OK_n → 打印「✅ N 个挂载自愈对象从控制节点可达」;任一 NO_n → 上报该 IP。
失败判断:出现「不可达」而对象实际可达 → 检查是否为 known_hosts / 公钥问题,不要放宽判据。
步骤 4:预演与下发¶
cd /home/rain/Documents/slurm/slurm_ins
.venv/bin/python main.py --config config/slurm_deploy.yaml --health-ensure --dry-run
.venv/bin/python main.py --config config/slurm_deploy.yaml --health-ensure
.venv/bin/python main.py --config config/slurm_deploy.yaml --health-ensure # 幂等复跑
6. 验证¶
| 项 | 命令 | 实测结果 |
|---|---|---|
| 清单 | python3 -c 读 .16:/etc/slurm-health/cluster.json |
count=8、含 .21 ✅ |
| 预检(正向) | 部署器 pre_check |
✅ 8 个挂载自愈对象从控制节点可达 ✅ |
| 预检(负向·dry-run) | 临时配置把 .21 改为 192.168.31.199 |
⚠️ 以下挂载自愈对象从控制节点 SSH 不可达,巡检会静默跳过:192.168.31.199(dry-run 继续预览) ✅ |
| 预检(负向·真实) | 同上但去掉 --dry-run |
DeployError: 以下挂载自愈对象从控制节点 SSH 不可达…、exit=1,且 .16 的 cluster.json 仍为 8 台(零变更) ✅ |
| 免密 | .16/.17 → .21(严格模式) |
均返回 lustre-mgs-01 ✅ |
| 巡检 | .16 跑 cluster_health_check.py --fix |
✅ 集群状态正常,无新增告警 ✅ |
端到端自愈(.21 注入验证) |
同上一主题做法:改挂载源 → failed → 巡检 → 还原 → 巡检 |
⚠️ lustre-mgs-01 处于 failed,执行自愈 + ❌ 自愈失败(源仍错,符合预期)→ 还原后 ⚠️ + ✅ lustre-mgs-01: /mnt/lustre 已恢复。终态:active、含 noatime、fstab_lines=1、/mnt/mdt0 完好、rain01 写入 WRITE_OK ✅ |
| 幂等 | 部署器复跑 | 「待执行 0、幂等跳过 5」✅ |
7. 回滚¶
备份位置(逐条见 backup/README.md):
| 备份 | 位置 |
|---|---|
| 工程两文件 | backup/slurm_ins/health_ensure_deployer.py.bak.20261007-102800、backup/slurm_ins/config/slurm_deploy.yaml.bak.20261007-102800 |
.21 authorized_keys |
backup/192.168.31.21/root/.ssh/authorized_keys.bak.20261007-102810(远程原位同名) |
cd /home/rain/Documents/slurm/slurm_ins
ts=20261007-102800
cp selfheal_guards_hardening_20261007/backup/slurm_ins/health_ensure_deployer.py.bak.$ts health_ensure_deployer.py
cp selfheal_guards_hardening_20261007/backup/slurm_ins/config/slurm_deploy.yaml.bak.$ts config/slurm_deploy.yaml
.venv/bin/python main.py --config config/slurm_deploy.yaml --health-ensure # 下发回 7 台版本
ssh root@192.168.31.21 'cp /root/.ssh/authorized_keys.bak.20261007-102810 /root/.ssh/authorized_keys'
回滚后验证:cluster.json 的 lustre_guards 回到 7 台;.21 的 authorized_keys 不再含 .16/.17 公钥。
回滚触发条件(量化):① pre_check 对可达对象误报「不可达」;② 复跑非零变更;③ 巡检对 .21 误报或误动作;④ .21 的 /mnt/lustre 由 active 变非 active。任一命中即回滚。
8. 风险说明¶
| 风险 | 缓解 |
|---|---|
| 自愈误动作影响 Lustre 服务端 | 判据仍是「仅 failed 才动」,且只操作客户端挂载单元 mnt-lustre.mount,与 MGS/MDT 服务无关 |
| 预检过严导致正常部署被拦 | 预检只探 ssh true(不依赖 systemctl);对象不达时先补免密而非放宽判据;dry-run 只告警,便于先看影响面 |
| 免密分发锁死 SSH | 先备份、-n 不覆盖、追加不替换;本机 .249 侧通道始终可用 |
9. 遗留¶
.22(OSS)确认不纳入【已确认 2026-10-07,实证】:.22无/mnt/lustre的 fstab 条目、无mnt-lustre.mount单元(只生成mnt-ost0.mount),实际只挂 OST 本体/mnt/ost0;对照.21——同为服务端但是客户端(fstab 有条目、单元active、挂/mnt/lustre+/mnt/mdt0)。纳入自愈无收益:判据是「unit 处于failed才动」,单元不存在时systemctl is-failed恒返回非 0,永远走「非 failed → 幂等跳过」,只会让巡检每 15 min 多一次无谓 SSH 往返。前提:若将来把.22配成客户端(lustre_ins的clients加.22并跑client_mount),届时应同步纳入。- 免密清单本身仍靠手工:本次预检能发现缺失,但不会自动补;长期可考虑把「控制节点公钥分发」纳入部署器步骤。
- 对象清单跨工程手工同步:
lustre_extra_guards需与lustre_ins的客户端清单保持一致,目前无自动校验(本工程pre_check只能查可达性,不能查「是否漏纳」)。
来源:
/home/rain/Documents/slurm/slurm_ins/selfheal_guards_hardening_20261007/SOP.md| 最后更新:2026-10-07 14:38(由build/sync.py同步,请勿在站点侧修改)