Lustre 集群运行手册(RUNBOOK)¶
面向日常运维与值班人员。照着做即可完成状态检查、扩缩容、故障处置。 工程根:
/home/rain/Documents/lustre_ins
目录¶
1. 服务概览¶
| 项 | 说明 |
|---|---|
| 服务 | Lustre 2.17.0 LTS 并行文件系统(ldiskfs 后端,TCP/LNet) |
| 用途 | EDA 仿真业务:承载源码小文件、仿真波形大文件、MPI-IO 共享文件、scratch 临时目录 |
| 上游 | HPC 调度器(Slurm/LSF)调度 EDA 作业到客户端节点读写 Lustre |
| 组件 | MGS+MDT(192.168.31.21)、OSS(192.168.31.22)、客户端(由配置驱动) |
| 文件系统名 | edafs(可在 deploy.yaml 的 lustre.fsname 修改) |
| 服务端口 | 988/tcp(Lustre) |
| 异常影响 | EDA 仿真作业读写失败、作业超时、数据不可用 |
| 重要性等级 | 高(EDA 仿真核心存储) |
2. 接入与凭据¶
节点地址¶
| 角色 | IP | 说明 |
|---|---|---|
| MGS+MDT | 192.168.31.21 | 元数据服务 + 管理服务(combined) |
| OSS | 192.168.31.22 | 对象存储服务 |
| 客户端 | 见 deploy.yaml 的 nodes.clients |
EDA 计算节点 |
凭据¶
| 凭据 | 位置 | 取用命令 |
|---|---|---|
| SSH 免密密钥 | 操作机 ~/.ssh/id_rsa |
paramiko 自动收集,无需手工传入 |
| SSH 用户 | root(已配 NOPASSWD) |
ssh root@192.168.31.21 |
| Lustre 管理口令 | 无(Lustre 无独立口令,靠系统权限) | — |
客户端接入¶
# 客户端挂载 Lustre 文件系统
mount -t lustre 192.168.31.21@tcp:/edafs /mnt/lustre
# 预期输出:无输出,返回码 0
# 验证:
mount | grep lustre
# 预期:192.168.31.21@tcp:/edafs on /mnt/lustre type lustre (rw,...)
开机自动挂载¶
/etc/fstab 中应有:
192.168.31.21@tcp:/edafs /mnt/lustre lustre defaults,noexec,nofail 0 0
nofail必须有,否则 Lustre 服务未就绪时开机卡死。
3. 日常速查表¶
| 操作 | 命令 |
|---|---|
| 查看 target 在线状态 | ssh root@192.168.31.21 'lctl dl' |
| 查看容量 | ssh root@192.168.31.21 'lfs df -h' |
| 查看客户端挂载 | ssh root@<client> 'mount \| grep lustre' |
| 查看 striping | ssh root@<client> 'lfs getstripe /mnt/lustre/eda_small_files' |
| 查看 LNet | ssh root@192.168.31.21 'lnetctl net show' |
| 查看调优参数 | ssh root@<client> 'lctl get_param osc.*.max_rpcs_in_flight' |
| 查看 Lustre 日志 | ssh root@192.168.31.21 'journalctl -u lnet --since "10 min ago"' |
| 重启 LNet | ssh root@192.168.31.21 'systemctl restart lnet' |
| 执行巡检 | cd /home/rain/Documents/lustre_ins && .venv/bin/python main.py inspect --config config/deploy.yaml |
| 变更前预检查 | cd /home/rain/Documents/lustre_ins && .venv/bin/python main.py precheck --config config/deploy.yaml |
| 回滚配置 | cd /home/rain/Documents/lustre_ins && .venv/bin/python main.py rollback --config config/deploy.yaml |
4. 日常操作¶
4.1 状态检查¶
# MGS+MDT 节点
ssh root@192.168.31.21 'lctl dl'
# 预期:
# 0 UP mgmtd MGS MGS 9.8.0
# 1 UP MGS MGS MGS 9.8.0
# 2 UP mdt edafs-MDT0000 MDS 9.8.0
# OSS 节点
ssh root@192.168.31.22 'lctl dl'
# 预期:
# 3 UP ost edafs-OST0000 OSS 9.8.0
# 容量
ssh root@192.168.31.21 'lfs df -h'
# 预期:列出 MDT + OST 的容量、已用、可用、使用率
# 客户端挂载
ssh root@<client> 'findmnt -t lustre'
# 预期:192.168.31.21@tcp:/edafs /mnt/lustre lustre
输出不符时:见 故障处置。
4.2 启动/停止/重启¶
# 停止(先客户端,再 OSS,最后 MDS)
ssh root@<client> 'umount /mnt/lustre'
ssh root@192.168.31.22 'umount /mnt/ost0'
ssh root@192.168.31.21 'umount /mnt/mdt0'
# 启动(先 MDS,再 OSS,最后客户端)
ssh root@192.168.31.21 'mount -t lustre /dev/vdb /mnt/mdt0'
ssh root@192.168.31.22 'mount -t lustre /dev/vdb /mnt/ost0'
ssh root@<client> 'mount -t lustre 192.168.31.21@tcp:/edafs /mnt/lustre'
# 重启 LNet(不影响已挂载 target)
ssh root@192.168.31.21 'systemctl restart lnet'
高危:停止 MDS 会导致所有客户端 IO 挂起;变更前确认无在跑 EDA 作业。
4.3 扩缩容¶
| 场景 | 命令 |
|---|---|
| 加 OSS 节点 | 编辑 deploy.yaml 的 nodes.oss 追加节点 → .venv/bin/python main.py add-oss --config config/deploy.yaml --force |
| 加 OST 盘 | 编辑 deploy.yaml 的 nodes.oss[].targets 追加盘 → .venv/bin/python main.py add-ost --config config/deploy.yaml --force |
| 加 MDT(DNE) | 编辑 deploy.yaml 的 nodes.mgs_mds[].targets 追加 {type: mdt, index: 1} → .venv/bin/python main.py add-mdt --config config/deploy.yaml --force |
| 加客户端 | 编辑 deploy.yaml 的 nodes.clients 追加节点 → .venv/bin/python main.py add-client --config config/deploy.yaml |
| 应用调优 | 编辑 deploy.yaml 的 optimization → .venv/bin/python main.py tune --config config/deploy.yaml |
| 启用 HA | 编辑 deploy.yaml 的 ha → .venv/bin/python main.py enable-ha --config config/deploy.yaml |
详细步骤见 SOP.md 第 5 章。
4.4 日志查看¶
# LNet 日志
ssh root@192.168.31.21 'journalctl -u lnet --since "1 hour ago" | tail -50'
# Lustre 内核日志
ssh root@192.168.31.21 'dmesg | grep -i lustre | tail -20'
# 部署工程日志
tail -100 /home/rain/Documents/lustre_ins/logs/lustre_deploy.log
5. 配置管理¶
| 配置项 | 位置 | 修改流程 | 生效方式 |
|---|---|---|---|
| 部署配置 | config/deploy.yaml |
复制 .example 改名后编辑 |
重新执行对应子命令 |
| yum 仓库 | /etc/yum.repos.d/lustre.repo(远程) |
由 repo_setup 模块管理 |
重新跑 repo 子命令 |
| LNet | /etc/lnet.conf(远程) |
由 lnet_config 模块管理 |
重新跑 lnet 相关步骤 |
| fstab | /etc/fstab(远程) |
由 fstab_persist 模块管理 |
mount -a 或重启 |
| lctl 调优 | /etc/modprobe.d/lustre.conf + /etc/systemd/system/lustre-tune.service(远程) |
由 lctl_tuning 模块管理 |
systemctl restart lustre-tune.service(oneshot+RemainAfterExit,处于 active 时 start 是 no-op) |
| striping | 文件系统级(lfs setstripe) |
由 stripe_tuning 模块管理 |
立即生效 |
易错点:
- 直接改远程配置文件而不改 deploy.yaml → 下次跑子命令会被覆盖;始终改 deploy.yaml。
- 改 deploy.yaml 后忘记 dry-run → 可能误 format 新盘;始终先 --dry-run。
6. 备份与恢复¶
备份策略¶
| 资源 | 备份方式 | 位置 |
|---|---|---|
| 远程配置文件(7 类) | deployer 在变更前自动备份为 <原路径>.bak.<时间戳> |
远程 /var/backups/lustre-ins/ |
| MDT 设备镜像 | 用户手工 dd if=/dev/vdb of=/root/vdb.img.bak |
远程 /root/ |
| 巡检报告 | inspect 子命令自动生成 |
reports/inspect-<时间戳>.md |
| 备份台账 | backup/README.md |
工程根 backup/ |
手工备份¶
# 高危:备份 MDT 设备镜像(mkfs 前执行)
ssh root@192.168.31.21 'dd if=/dev/vdb of=/root/vdb.img.bak bs=4M status=progress'
恢复步骤¶
# 1. 查看可恢复项(不执行)
.venv/bin/python main.py rollback --config config/deploy.yaml
# 2. 真实恢复(需 --force)
.venv/bin/python main.py rollback --config config/deploy.yaml --force
# 3. 恢复后验证
ssh root@192.168.31.21 'cat /etc/yum.repos.d/lustre.repo' # 预期:恢复到变更前内容
演练记录¶
- 首次部署后执行
rollback --dry-run,确认可恢复项列表与预期一致 - 每季度执行一次
inspect巡检,归档巡检报告
7. 监控与告警¶
关键指标¶
| 指标 | 查看命令 | 告警阈值 |
|---|---|---|
| target 在线数 | lctl dl \| grep -c UP |
< 配置期望数 |
| MDT 使用率 | lfs df -h \| grep MDT |
>80% 告警,>90% 严重 |
| OST 使用率 | lfs df -h \| grep OST |
>80% 告警,>90% 严重 |
| 客户端挂载 | findmnt -t lustre(客户端) |
未挂载 |
| LNet 状态 | lnetctl net show |
无 tcp 网络 |
| CPU load | awk '{print $1}' /proc/loadavg |
> 核数 |
| 内存 | free \| awk '/Mem:/ {print $3/$2*100}' |
>80% 告警,>90% 严重 |
日志位置¶
| 日志 | 位置 |
|---|---|
| LNet | journalctl -u lnet(远程) |
| Lustre 内核 | dmesg(远程) |
| 部署工程 | logs/lustre_deploy.log(工程根) |
| 巡检报告 | reports/inspect-*.md |
日常巡检¶
cd /home/rain/Documents/lustre_ins
.venv/bin/python main.py inspect --config config/deploy.yaml
# 预期:reports/ 下生成 inspect-<时间戳>.md,无 HIGH 级别异常
# 变更前预检查(只读;扩缩容、加盘、改调优前先跑,退出码 0 才继续)
.venv/bin/python main.py precheck --config config/deploy.yaml
# 预期:reports/ 下生成 precheck-<时间戳>.md,结论无 BLOCK 项
# 输出不符时:按报告中的节点/检查项逐条处置;系统盘判定失败时在
# config/deploy.yaml 的 disk_safety.system_disks 显式声明系统盘清单
# 检查项:操作机环境、SSH 可达、OS/架构、时钟偏移、执行身份(root)、SELinux、
# 系统盘可用空间、运行内核版本、防火墙状态、仓库可达性、
# LNet 网卡与 NID 可达性(lctl ping)、调度器作业、target 设备
# 阈值与跳过列表:config/deploy.yaml 的 precheck 段(min_disk_free_gb、
# required_selinux、require_root、check_lnet_ping、skip_checks 等)
# 新增检查项不符时的处置:
# 执行身份非 root → 配置 root 免密或显式提权后重跑
# SELinux Enforcing → setenforce 0 并改 /etc/selinux/config(重启后生效)
# 系统盘空间不足 → 清理系统盘,或确认可接受后下调 precheck.min_disk_free_gb
# NID 不可达 → `lnetctl net show`、`lctl list_nids` 查 LNet 配置与网络
8. 故障处置¶
场景 1:客户端无法挂载 Lustre¶
症状:mount -t lustre 192.168.31.21@tcp:/edafs /mnt/lustre 报 Connection refused 或 mount error。
诊断
# 1. 确认 MGS 在线
ssh root@192.168.31.21 'lctl dl' # 预期:MGS UP
# 2. 确认 LNet 通
ssh root@192.168.31.21 'lnetctl net show' # 预期:tcp 网络存在
ssh root@<client> 'lnetctl net show' # 预期:tcp 网络存在
# 3. 确认防火墙放行
ssh root@192.168.31.21 'firewall-cmd --list-ports' # 预期:988/tcp
# 4. 确认客户端包已装
ssh root@<client> 'rpm -q kmod-lustre-client' # 预期:已安装
处置
- 步骤 1 异常 → 见 troubleshoot.md OST 不在线
- 步骤 2 异常 → .venv/bin/python main.py tune --config config/deploy.yaml(含 LNet 修复)
- 步骤 3 异常 → .venv/bin/python main.py tune --config config/deploy.yaml(含防火墙修复)
- 步骤 4 异常 → .venv/bin/python main.py add-client --config config/deploy.yaml
验证:ssh root@<client> 'mount -t lustre 192.168.31.21@tcp:/edafs /mnt/lustre' 返回码 0
场景 2:OST 不在线¶
症状:lctl dl 显示 OST 状态 DOWN;lfs df -h 缺少 OST。
诊断
# 1. 确认 OSS 节点 SSH 可达
ssh root@192.168.31.22 'hostname' # 预期:返回主机名
# 2. 确认 OST 设备存在
ssh root@192.168.31.22 'lsblk /dev/vdb' # 预期:TYPE=disk
# 3. 确认已格式化
ssh root@192.168.31.22 'dumpe2fs -h /dev/vdb 2>/dev/null | grep Lustre' # 预期:Lustre filesystem
# 4. 确认已挂载
ssh root@192.168.31.22 'findmnt /mnt/ost0' # 预期:lustre
# 5. 查看 OSS 日志
ssh root@192.168.31.22 'journalctl -u lnet --since "30 min ago" | tail -20'
处置
- 步骤 2 异常 → 硬件故障,换盘后 .venv/bin/python main.py add-ost --config config/deploy.yaml --force
- 步骤 3 异常 → 未格式化,.venv/bin/python main.py add-ost --config config/deploy.yaml --force
- 步骤 4 异常 → ssh root@192.168.31.22 'mount -t lustre /dev/vdb /mnt/ost0'
- 步骤 5 有错误 → 见 troubleshoot.md LNet 不通
验证:ssh root@192.168.31.22 'lctl dl' 显示 OST UP
场景 3:容量告警(>80%)¶
症状:lfs df -h 显示 MDT 或 OST 使用率 >80%。
诊断
# 1. 确认哪个 target 告警
ssh root@192.168.31.21 'lfs df -h'
# 2. 查看大文件
ssh root@<client> 'find /mnt/lustre -type f -size +1G -exec ls -lh {} \; | sort -k5 -h | tail -20'
# 3. 查看 striping 是否合理
ssh root@<client> 'lfs getstripe /mnt/lustre/eda_large_files'
处置
- MDT 告警 → 清理小文件或 .venv/bin/python main.py add-mdt --config config/deploy.yaml --force(DNE 扩容)
- OST 告警 → 清理大文件或 .venv/bin/python main.py add-ost --config config/deploy.yaml --force(加盘扩容)
验证:ssh root@192.168.31.21 'lfs df -h' 使用率 <80%
9. 安全与权限¶
| 项 | 说明 |
|---|---|
| SSH 访问 | root 免密(密钥认证);密钥 ~/.ssh/id_rsa |
| Lustre 权限 | 基于系统 UID/GID;支持 POSIX ACL(setfacl/getfacl) |
| 防火墙 | 988/tcp 仅对内网开放(由 firewall 模块配置) |
| 证书/密钥 | 无独立 TLS 证书(LNet 走 TCP 明文,内网环境) |
权限轮换:如需更换 SSH 密钥,更新操作机 ~/.ssh/id_rsa 后所有子命令自动生效。
10. 容量与性能¶
当前水位基线¶
取数时间:2026-10-09(
ssh root@192.168.31.21 'lfs df -h';原始输出留存reports/lfs-df-20261009.txt)。
| target | 容量 | 已用 | 使用率 | 扩容触发 |
|---|---|---|---|---|
MDT0000(.21) |
11.1G | 1.6M | 1% | >80% 时 add-mdt |
OST0000(.22) |
294.4G | 1.4M | 1% | >80% 时 add-ost |
| 文件系统合计 | 294.4G | 1.4M | 1% | — |
EDA striping 模板¶
| 目录 | stripe_size | stripe_count | 适用场景 |
|---|---|---|---|
/mnt/lustre/eda_small_files |
1M | 1 | 源码、配置、临时小文件 <20MB |
/mnt/lustre/eda_large_files |
16M | 1(多 OST 时建议 4) | 仿真波形、布局数据 |
/mnt/lustre/eda_shared_files |
4M | -1(跨全部 OST) | MPI-IO 共享文件 |
/mnt/lustre/eda_scratch |
1M | 1 | 临时 scratch |
lctl 调优参数¶
| 参数 | 值 | 说明 |
|---|---|---|
osc.*.max_rpcs_in_flight |
32 | 客户端 OSC 并发 RPC |
mdc.*.max_rpcs_in_flight |
64 | 客户端 MDC 并发 RPC |
mdc.*.max_mod_rpcs_in_flight |
31 | 客户端 MDC 修改类 RPC 上限;受服务端 mdt.*.max_mod_rpcs_in_flight 压制,必须更小 |
mdt.*.max_mod_rpcs_in_flight |
32 | 服务端 MDT 修改类 RPC 上限(仅 MGS+MDT 节点下发) |
llite.*.statahead_max |
512 | 预读 stat 数 |
llite.*.statahead_agl |
1 | 预读目录项聚合开关 |
osc.*.max_dirty_mb |
不设(跟随 Lustre 默认,本机 128) | 客户端脏页缓存上限;实测运行期被内核按内存重算,硬设无效 |
ldlm.namespaces.*.lru_max_age |
600000 | LC 缓存条目最长保留时间(ms) |
ldlm.namespaces.*.lru_size |
auto(100×CPU) | LC 缓存大小 |
timeout |
600 | 服务端超时 |
ldlm_timeout |
200 | LDLM 超时 |
at_min / at_max |
250 / 600 | 自适应超时上下限 |
持久化:由
/etc/systemd/system/lustre-tune.service(oneshot 单元)在 lustre 挂载完成后重新下发,重启后仍生效。 调整mdc.*.max_mod_rpcs_in_flight须先调高服务端mdt.*.max_mod_rpcs_in_flight并重新挂载客户端,否则上限不会放宽、设置返回ERANGE(34)(日志Numerical result out of range)。llite.*.statahead_xattr在 Lustre 2.17 已不存在,不再下发。
已知瓶颈¶
- 单 MDT:元数据密集场景(大量小文件 create/stat)可能成为瓶颈 → 加 MDT(DNE)
- 单 OST:大文件并发写吞吐受限 → 加 OST 或增大 stripe_count
扩容操作¶
见 日常操作 4.3 扩缩容。
11. 附录¶
术语表¶
| 术语 | 含义 |
|---|---|
| MGS | Lustre 管理服务(Management Server) |
| MDT | 元数据目标(Metadata Target) |
| MDS | 元数据服务(Metadata Server) |
| OSS | 对象存储服务(Object Storage Server) |
| OST | 对象存储目标(Object Storage Target) |
| LNet | Lustre 网络(Lustre Networking) |
| DNE | 分布式命名空间(Distributed Namespace Environment),多 MDT |
| NID | LNet 节点标识(Node Identifier) |
| HA | 高可用(High Availability),Pacemaker + corosync |
| striping | 文件分条(跨多个 OST) |
交付物清单¶
| 路径 | 内容 |
|---|---|
main.py + deployer.py + modules/*.py + utils/*.py |
实现体 |
config/deploy.yaml.example |
初始部署配置样例 |
config/deploy-expand.yaml.example |
扩展场景配置片段 |
docs/SOP.md |
变更实施手册(八章) |
docs/RUNBOOK.md |
本文件(运行手册) |
docs/troubleshoot.md |
排障手册 |
reports/inspect-*.md |
巡检报告 |
reports/precheck-*.md |
安装前预检查报告(含配置校验问题) |
backup/README.md |
备份台账 |
修订记录¶
| 日期 | 修改人 | 变更内容 |
|---|---|---|
| 2026-09-22 | Agent | 初版创建 |
| 2026-09-22 | Agent | 同步通用性与预检查加固:新增 precheck 子命令与预检查报告、变更前置门禁、系统盘自动推导、新增 packages/disk_safety/precheck/stripe_host 等配置项 |
| 2026-09-23 | Agent | 通用能力上移共享库(ssh_executor/idempotent_module/file_module/precheck_module);precheck 扩充 root 权限、SELinux、系统盘空间、内核版本、LNet NID 可达性五项检测 |
来源:
/home/rain/Documents/lustre_ins/docs/RUNBOOK.md| 最后更新:2026-10-09 05:16(由build/sync.py同步,请勿在站点侧修改)