跳转至

SOP — 自愈对象扩至 .21 + pre_check 增「自愈对象 SSH 可达性」预检

  • 主题目录:selfheal_guards_hardening_20261007/
  • 执行日期:2026-10-07
  • 类型:C 类变更(自愈对象扩面 + 部署器门禁加固 + 节点间免密)
  • 关联:lustre_ins HANDOFF §3.1 #19(本变更结案);上一轮扩面见 lustre_mount_selfheal_extend_20261007/SOP.md

1. 背景

两件事合并执行:

  1. .21 纳入挂载自愈(lustre_ins #19):.21 是 MGS+MDT 同机客户端,与其余客户端同源配置、同样出现过 mnt-lustre.mount failed,但此前不在巡检范围内。
  2. 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. 遗留

  1. .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),届时应同步纳入。
  2. 免密清单本身仍靠手工:本次预检能发现缺失,但不会自动补;长期可考虑把「控制节点公钥分发」纳入部署器步骤。
  3. 对象清单跨工程手工同步: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 同步,请勿在站点侧修改)