跳转至

SOP:新增 192.168.31.25/26/27/28 为挂载客户端

2026-09-29 | C 类变更 | 状态:已落地并验证 | 实现体 deployer.py:cmd_add_client

1. 背景

EDA 仿真扩容需要 4 台新计算节点(Rocky 9.8)挂载 Lustre。用户自行执行 add-client 时连续受阻两次:① 全网到 downloads.whamcloud.com 仅约 2 KB/s,.25 的 dnf install 两次分别跑 34 分钟、16 分钟未完成(第二次父进程退出留下孤儿 dnf);② 真实执行在 firewall 门禁被阻断(4 台新节点 firewalld 未启用)。转由 Agent 接手,以「缓存分发提速」绕开跨境慢链路后完成。

2. 目标

  • 4 台均切换至内核 5.14.0-611.13.1_lustre.el9 并重启完成
  • 4 台均挂载 /mnt/lustre(源 192.168.31.21@tcp:/edafs),fstab 带 nofail
  • mdc.*.max_mod_rpcs_in_flight=31 达标,lustre-tune.service enabled
  • 幂等复跑退出码 0、核心模块全跳过

3. 前置条件

  • 操作机 root 免密 SSH 至 4 台(BatchMode=yes 验证可达)
  • 4 台在 Slurm/LSF 上无在跑作业(precheck 的调度器检查覆盖,须 0 BLOCK)
  • config/deploy.yaml 已备份至 backup/(见 backup/README.md)

4. 影响范围

项 值
主机 192.168.31.25/26/27/28(各重启 1 次切内核)
服务端 .21/.22 不变更(firewall/lnet 幂等跳过)
停服 无服务端停服;4 台新节点重启期间自身离线,nofail 保证不影响既有节点开机
不可逆 无(不涉及 mkfs)

5. 分步操作

步骤 1:备份配置

cd /home/rain/Documents/lustre_ins
TS=$(date +%Y%m%d-%H%M%S)
mkdir -p add-clients-25-28/backup/config
cp -p config/deploy.yaml "add-clients-25-28/backup/config/deploy.yaml.bak.$TS"

预期:backup/config/ 下生成 deploy.yaml.bak.20260929-030912。

步骤 2:追加 clients 配置

在 config/deploy.yaml 的 nodes.clients 下按既有格式追加 .26/.27/.28(.25 已存在),host 与 lnet_nid 的 IP 必须一致:

    - host: 192.168.31.26
      ssh_user: root
      lnet_nid: 192.168.31.26@tcp
      lnet_interface: auto
      mount_point: /mnt/lustre

坑:config/deploy.yaml 不入 Git,备份是唯一回滚依据;不要重复添加已有节点(precheck 查唯一性)。

步骤 3:rpm 缓存内网分发(本次提速关键)

背景:全网(操作机与节点)直连 whamcloud 均约 2 KB/s,4 台串行下载预计 1~2 小时。.25 上由早前中断的执行已下载 101MB / 64 个 rpm(含 kmod-lustre、kernel-core-5.14.0-611.13.1_lustre),且孤儿 dnf 进程仍在下载时不要杀它(父进程死后其下载成果保留在 /var/cache/dnf)。

# 将 .25 的工程 repo 文件与整个 dnf 缓存内网并行分发给三台(约 100MB,内网秒级~十几秒)
for h in 26 27 28; do
  ( timeout 20 ssh root@192.168.31.25 'tar -C /etc/yum.repos.d -cf - lustre.repo e2fsprogs.repo' \
      | timeout 20 ssh root@192.168.31.$h 'tar -C /etc/yum.repos.d -xf -'
    timeout 300 ssh root@192.168.31.25 'tar -C /var/cache -cf - dnf' \
      | timeout 300 ssh root@192.168.31.$h 'tar -C /var/cache -xf -'
    echo ".$h 拷贝完成" ) &
done; wait

预期:三台 find /var/cache/dnf -name "*.rpm" | wc -l 均为 64,/etc/yum.repos.d/lustre.repo 存在。

坑:.25 的孤儿 dnf 若中途退出且 rpm -q 显示未安装(本次实测),属正常——缓存已在,重起即可;dnf 装时按缓存校验和命中即不重新下载。

步骤 4:四台并行安装 rpm 包

for h in 25 26 27 28; do
  ssh root@192.168.31.$h \
    "setsid nohup dnf install -y kmod-lustre lustre >/tmp/dnf_client_install.log 2>&1 < /dev/null &"
done

预期:各节点 /tmp/dnf_client_install.log 出现 Complete!;rpm -q kmod-lustre lustre 均返回 kmod-lustre-2.17.0-1.el9.x86_64 / lustre-2.17.0-1.el9.x86_64,rpm -q kernel-core 为 5.14.0-611.13.1_lustre.el9.x86_64。

注意:setsid nohup 防 SSH 断开连带杀进程(上轮孤儿问题的直接教训)。

步骤 5:预检查门禁与预演

.venv/bin/python3 main.py precheck --config config/deploy.yaml          # 退出码 0 才继续
.venv/bin/python3 main.py add-client --dry-run --config config/deploy.yaml

预期:precheck 2 分钟内 0 BLOCK(缓存热);dry-run 退出码 1 是已知误判(lctl_tuning 对未挂载新节点把 get_param 无输出记为失败,见 HANDOFF 3.1 #11),前 7 模块 success 即可继续。

步骤 6:启用 firewalld(firewall 门禁前置)

坑:4 台出厂 firewalld 为 inactive,modules/firewall.py:pre_check 在真实执行时直接阻断(dry-run 仅降级为告警)。[HIGH-RISK] 启动服务。

for h in 25 26 27 28; do
  ssh root@192.168.31.$h 'systemctl enable --now firewalld && systemctl is-active firewalld'
done

预期:四台均返回 active(public zone 默认放行 ssh,不会断 SSH)。

步骤 7:真实执行(编排 8 模块)

实现体入口:.venv/bin/python3 main.py add-client --config config/deploy.yaml(日志 logs/addclient_real2_*.out)。

等价编排序列(各模块幂等,已装/已配即跳过):repo 写 /etc/yum.repos.d/{lustre,e2fsprogs}.repo → dnf install -y kmod-lustre lustre → grubby 切默认内核 + systemctl reboot([HIGH-RISK],重启后核对 boot_id 变化 + uname -r)→ firewall-cmd --permanent --add-port=988/tcp + reload → lnetctl lnet configure + net add tcp + route add(必须先 configure,否则 net add 报 -108)→ mount -t lustre 192.168.31.21@tcp:/edafs /mnt/lustre → 追加 fstab(nofail)→ lctl set_param 调优 + 写 lustre-tune.service 并 enable。

预期:8 模块全 success,总耗时约 472s,退出码 0。 失败判断:编排终止于 <模块> → 该模块及后续未执行,前序不自动回滚;修正后直接重跑(幂等)。

步骤 8:幂等复跑(收尾要求)

.venv/bin/python3 main.py add-client --config config/deploy.yaml   # 第二次应零变更

预期:退出码 0;repo/package/kernel/firewall/lnet/mount/lctl_tuning 全部 成功: 0 | 跳过: N。fstab_persist 对 .21/.22 会打印「追加」日志但实测 fstab 无重复行(日志措辞瑕疵,以 grep -c 为准)。

6. 验证

for h in 25 26 27 28; do ssh root@192.168.31.$h '
  uname -r                                   # 预期 5.14.0-611.13.1_lustre.el9.x86_64
  findmnt -t lustre /mnt/lustre -n           # 预期 192.168.31.21@tcp:/edafs
  grep -c nofail /etc/fstab                  # 预期 ≥1
  systemctl is-enabled lustre-tune.service   # 预期 enabled
  lctl get_param mdc.*.max_mod_rpcs_in_flight # 预期 =31'; done

# 写读测试(各台执行)
dd if=/dev/urandom of=/mnt/lustre/.hw_$(hostname -s) bs=1M count=8 && \
  md5sum /mnt/lustre/.hw_$(hostname -s) && rm -f /mnt/lustre/.hw_$(hostname -s)

实测:4 台 8MB 直写 19~47 MB/s,md5 回读一致,删除通过。

7. 回滚

备份位置:add-clients-25-28/backup/(台账见该目录 README.md)。

# 1. 摘除挂载与开机项(4 台分别执行)[HIGH-RISK] 中断该节点文件系统访问
ssh root@192.168.31.<IP> 'umount /mnt/lustre; sed -i "\|/mnt/lustre|d" /etc/fstab'
# 2. 恢复配置:删除 clients 中 .25~.28 四条(对照 backup/config/deploy.yaml.bak.*)
# 3. 可选彻底卸载:dnf remove -y lustre kmod-lustre ;内核不回退(grubby 默认已是 lustre 内核,需手动改回)
# 4. 验证回滚:findmnt -t lustre /mnt/lustre 应无输出

回滚后验证:main.py precheck 复跑反映删除后的节点集。

8. 风险说明

风险 缓解
4 台重启中断其上作业 执行前 precheck 调度器检查 + 人工确认无作业
跨境仓库 2 KB/s 致 dnf 长挂 缓存分发(步骤 3);setsid nohup 防会话断连杀进程
老节点带宽被 4 台并行下载挤占 仅启动时短暂,缓存命中后不再下载
fstab 无 nofail 开机卡死 fstab_persist 模块自动带 nofail,已验证
firewalld 启用后 988 未放行窗口 由步骤 6→7 连续执行覆盖,LNet 尚未配置期间无业务影响

附录 A:执行记录

  • 03:09 备份配置;03:15 缓存分发 + 并行装包完成(4 台 Complete!)
  • 03:20 precheck 0 BLOCK(约 2 分钟);03:22 dry-run(已知 lctl_tuning 误判退出 1)
  • 03:29 首次真实执行止于 firewall _pre_check(firewalld inactive)
  • 03:39 启用 firewalld 后重跑:8 模块 success(471.68s)
  • 03:47 写读测试通过;03:47 幂等复跑退出 0、核心模块全跳过

附录 B:交付物清单

文件 用途
add-clients-25-28/SOP.md 本档案
add-clients-25-28/backup/ 配置备份(台账 README.md)
logs/addclient_real2_033851.out、logs/addclient_idem_034732.out 执行与幂等复跑日志
reports/precheck-20260929-*.md 门禁报告

来源:/home/rain/Documents/lustre_ins/add-clients-25-28/SOP.md | 最后更新:2026-09-29 03:56(由 build/sync.py 同步,请勿在站点侧修改)