跳转至

Lustre 排障手册(troubleshoot)

按症状索引;每个场景按「症状 → 诊断(命令 + 预期输出)→ 处置 → 验证」四段写。 工程根:/home/rain/Documents/lustre_ins

目录


mkfs.lustre 失败

症状:mkfs.lustre 返回非 0;deployer.py:cmd_bootstrap 在 target_format 模块终止;日志 [HIGH-RISK] 标记后报错。

诊断

# 1. 确认设备存在且未分区
ssh root@192.168.31.21 'lsblk -ndo TYPE,PKNAME,NAME /dev/vdb'
# 预期:disk(TYPE)、空(PKNAME)、vdb(NAME)
# 异常:part(TYPE=分区)、非空(PKNAME=父盘)

# 2. 确认设备未占用
ssh root@192.168.31.21 'lsblk /dev/vdb -o MOUNTPOINTS'
# 预期:无挂载点
# 异常:有挂载点 → 先 umount

# 3. 确认未已格式化
ssh root@192.168.31.21 'dumpe2fs -h /dev/vdb 2>/dev/null | grep -i lustre'
# 预期:无输出(未格式化)
# 异常:有 Lustre filesystem → 已格式化,跳过即可

# 4. 查看详细错误
ssh root@192.168.31.21 'mkfs.lustre --fsname=edafs --mgs --mdt --index=0 /dev/vdb 2>&1'

处置 - 步骤 1 异常(TYPE=part)→ 设备已分区,需 wipefs -a /dev/vdb 清除分区表后重试 - 步骤 1 异常(PKNAME 非空)→ 设备是分区,改用整盘 /dev/vdb 而非 /dev/vdb1 - 步骤 1 异常(在白名单 sda/vda/nvme0n1)→ 系统盘,换数据盘 - 步骤 2 异常 → ssh root@192.168.31.21 'umount /dev/vdb*' - 步骤 3 异常 → 已格式化,is_lustre_target_formatted 应自动跳过;如误报,手动确认后跳过 - 步骤 4 报 Device already in use → wipefs -a /dev/vdb 后重试 - 步骤 4 报 No space left on device → 磁盘硬件故障,换盘

验证:ssh root@192.168.31.21 'dumpe2fs -h /dev/vdb | grep Lustre' 返回 Lustre filesystem


LNet 不通

症状:客户端挂载报 Connection refused;lnetctl net show 无 tcp 网络;lctl ping <NID> 超时。

诊断

# 1. 确认 LNet 模块加载
ssh root@192.168.31.21 'lsmod | grep lnet'
# 预期:lnet / ksocklnd 模块存在
# 异常:无 → modprobe lnet

# 2. 确认 LNet 配置
ssh root@192.168.31.21 'lnetctl net show'
# 预期:net: tcp, intf: <网卡名>
# 异常:无 tcp 网络 → lnetctl net add

# 3. 确认 NID 可达
ssh root@192.168.31.21 'lctl ping 192.168.31.22@tcp'
# 预期:返回 pong
# 异常:超时 → 防火墙或网络问题

# 4. 确认网卡名正确
ssh root@192.168.31.21 'ip route get 192.168.31.22'
# 预期:dev <网卡名>
# 异常:网卡名与 deploy.yaml 的 lnet_interface 不一致

处置 - 步骤 1 异常 → ssh root@192.168.31.21 'modprobe lnet && systemctl enable --now lnet' - 步骤 2 异常 → cd /home/rain/Documents/lustre_ins && .venv/bin/python main.py tune --config config/deploy.yaml(含 LNet 配置) - 步骤 3 异常 → 见 防火墙问题 或检查物理网络 - 步骤 4 异常 → 编辑 deploy.yaml 的 lnet_interface 改为实际网卡名,或设为 auto

验证:ssh root@192.168.31.21 'lctl ping 192.168.31.22@tcp' 返回 pong


挂载失败

症状:mount -t lustre 报错;findmnt -t lustre 无输出;客户端 IO 失败。

诊断

# 1. 确认 MGS 在线
ssh root@192.168.31.21 'lctl dl | grep MGS'
# 预期:MGS UP
# 异常:MGS DOWN → 先启动 MGS

# 2. 确认 MDT 在线
ssh root@192.168.31.21 'lctl dl | grep MDT'
# 预期:MDT0000 UP
# 异常:MDT DOWN → 见 [MDT 不在线](#mdt-不在线)

# 3. 确认 OST 在线
ssh root@192.168.31.22 'lctl dl | grep OST'
# 预期:OST0000 UP
# 异常:OST DOWN → 见 [OST 不在线](#ost-不在线)

# 4. 确认防火墙放行
ssh root@192.168.31.21 'firewall-cmd --list-ports'
# 预期:988/tcp
# 异常:无 988 → firewall 模块未跑

# 5. 确认客户端 LNet
ssh root@<client> 'lnetctl net show'
# 预期:tcp 网络存在
# 异常:无 → 见 [LNet 不通](#lnet-不通)

# 6. 查看挂载详细错误
ssh root@<client> 'mount -t lustre 192.168.31.21@tcp:/edafs /mnt/lustre 2>&1'

处置 - 步骤 1 异常 → ssh root@192.168.31.21 'mount -t lustre /dev/vdb /mnt/mdt0'(启动 MGS+MDT) - 步骤 4 异常 → cd /home/rain/Documents/lustre_ins && .venv/bin/python main.py tune --config config/deploy.yaml - 步骤 5 异常 → 见 LNet 不通 - 步骤 6 报 unknown filesystem type 'lustre' → ssh root@<client> 'dnf install -y kmod-lustre-client lustre-client && modprobe lustre' - 步骤 6 报 Connection timed out → LNet 或防火墙问题

常见坑:手工执行 mount /mnt/lustre(不带 -t 与源)会走 fstab,nofail 被当作 lustre 挂载选项解析而失败,日志为 LustreError: Unknown option 'nofail', won't mount. 与 rc = -22。正确做法:systemctl start mnt-lustre.mount, 或显式指定类型与源:mount -t lustre 192.168.31.21@tcp:/edafs /mnt/lustre。

验证:ssh root@<client> 'findmnt -t lustre' 显示挂载条目


OST 不在线

症状:lctl dl 显示 OST 状态 DOWN;lfs df -h 缺少 OST;客户端写入失败。

诊断

# 1. 确认 OSS 节点可达
ssh root@192.168.31.22 'hostname'
# 预期:返回主机名
# 异常:SSH 不通 → 网络或 sshd 问题

# 2. 确认 LNet
ssh root@192.168.31.22 'lnetctl net show'
# 预期:tcp 网络存在
# 异常:见 [LNet 不通](#lnet-不通)

# 3. 确认 OST 设备
ssh root@192.168.31.22 'lsblk /dev/vdb'
# 预期:TYPE=disk
# 异常:无设备 → 硬件故障

# 4. 确认已格式化
ssh root@192.168.31.22 'dumpe2fs -h /dev/vdb 2>/dev/null | grep Lustre'
# 预期:Lustre filesystem
# 异常:无 → 需 mkfs

# 5. 确认已挂载
ssh root@192.168.31.22 'findmnt /mnt/ost0'
# 预期:lustre
# 异常:无 → mount

# 6. 查看 OSS 日志
ssh root@192.168.31.22 'journalctl -u lnet --since "30 min ago" | tail -20'

处置 - 步骤 3 异常 → 硬件故障,换盘后 add-ost --force - 步骤 4 异常 → cd /home/rain/Documents/lustre_ins && .venv/bin/python main.py add-ost --config config/deploy.yaml --force - 步骤 5 异常 → ssh root@192.168.31.22 'mount -t lustre /dev/vdb /mnt/ost0' - 步骤 6 有 RPC timed out → LNet 问题或 MGS 不可达

验证:ssh root@192.168.31.22 'lctl dl | grep OST' 显示 UP


MDT 不在线

症状:lctl dl 显示 MDT 状态 DOWN;客户端所有操作失败(无法 stat/create/open)。

诊断

# 1. 确认 MGS+MDT 节点可达
ssh root@192.168.31.21 'hostname'
# 2. 确认 LNet
ssh root@192.168.31.21 'lnetctl net show'
# 3. 确认 MDT 设备
ssh root@192.168.31.21 'lsblk /dev/vdb'
# 4. 确认已挂载
ssh root@192.168.31.21 'findmnt /mnt/mdt0'
# 5. 查看 MDS 日志
ssh root@192.168.31.21 'journalctl -u lnet --since "30 min ago" | tail -20'

处置 - 步骤 4 异常 → ssh root@192.168.31.21 'mount -t lustre /dev/vdb /mnt/mdt0' - 步骤 5 有 I/O error → MDT 设备故障,需从 dd 镜像恢复或重新 mkfs(数据丢失) - 步骤 5 有 device already mounted → ssh root@192.168.31.21 'umount /mnt/mdt0 && mount -t lustre /dev/vdb /mnt/mdt0'

验证:ssh root@192.168.31.21 'lctl dl | grep MDT' 显示 UP

高危:MDT 故障会导致全文件系统不可用;强烈建议 mkfs 前 dd 镜像备份 MDT 设备。


lctl 参数不持久化

症状:重启后 lctl get_param osc.*.max_rpcs_in_flight 恢复默认值;EDA 读写性能下降。

诊断

# 1. 确认 modprobe 配置存在
ssh root@<client> 'cat /etc/modprobe.d/lustre.conf'
# 预期:options ptlrpc ptlrpcd_per_cpt_max=32 等
# 异常:无 → lctl_tuning 模块未跑

# 2. 确认 systemd 持久化单元存在且已启用
ssh root@<client> 'systemctl is-enabled lustre-tune.service'
# 预期:enabled
ssh root@<client> 'systemctl is-active lustre-tune.service'
# 预期:active
ssh root@<client> 'systemctl cat lustre-tune.service'
# 预期:Type=oneshot、RemainAfterExit=yes、After=remote-fs.target;
#       客户端单元含 RequiresMountsFor=/mnt/lustre;
#       每条参数一行 ExecStart=/usr/sbin/lctl set_param <param>=<value>
# 异常:单元不存在 → lctl_tuning 模块未跑;单元 active 但参数仍为默认值 → 见 [调优参数设置被拒(ERANGE 34)](#调优参数设置被拒erange-34)

# 3. 确认当前参数
ssh root@<client> 'lctl get_param osc.*.max_rpcs_in_flight mdc.*.max_mod_rpcs_in_flight'
# 预期:osc.*.max_rpcs_in_flight=32;mdc.*.max_mod_rpcs_in_flight=31
# 异常:默认值 → 需重新应用

处置

cd /home/rain/Documents/lustre_ins
.venv/bin/python main.py tune --config config/deploy.yaml
# 或单独跑 lctl_tuning 模块(含 modprobe + systemd 单元持久化)

验证:ssh root@<client> 'lctl get_param osc.*.max_rpcs_in_flight mdc.*.max_mod_rpcs_in_flight' 返回 32 / 31;重启后仍为 32 / 31


调优参数设置被拒(ERANGE 34)

症状:lctl set_param mdc.*.max_mod_rpcs_in_flight=<值> 失败并返回 ERANGE(errno 34);dmesg 出现 Numerical result out of range;lustre-tune.service 的 ExecStart 报错,lctl get_param 仍为默认值。

诊断

# 1. 确认客户端错误日志(ERANGE / Numerical result out of range)
ssh root@<client> 'dmesg | grep -i "out of range" | tail -5'
# 预期:出现 Numerical result out of range(errno 34)
ssh root@<client> 'journalctl -u lustre-tune.service -n 30 --no-pager'
# 预期:无 ExecStart 失败;有失败则对应参数被内核拒绝

# 2. 看服务端 MDT 上限(客户端上限由 MDT 在客户端连接时返回该值决定)
ssh root@192.168.31.21 'lctl get_param mdt.*.max_mod_rpcs_in_flight'
# 预期:32
# 异常:偏小或为默认值 → 服务端先调高,再重新挂载客户端

# 3. 看客户端当前值
ssh root@<client> 'lctl get_param mdc.*.max_mod_rpcs_in_flight'
# 预期:31(必须小于服务端 mdt.*.max_mod_rpcs_in_flight)

处置 - 服务端上限偏小 → 先调高服务端,并让客户端重新挂载(上限在连接时协商,重挂载后才放宽): bash ssh root@192.168.31.21 'lctl set_param mdt.*.max_mod_rpcs_in_flight=32' ssh root@<client> 'umount /mnt/lustre && systemctl start mnt-lustre.mount' - 客户端值 ≥ 服务端值 → 改 config/deploy.yaml 的 optimization 段,令 mdc.*.max_mod_rpcs_in_flight 小于 mdt.*.max_mod_rpcs_in_flight(配置校验对不满足者判 BLOCK),再 cd /home/rain/Documents/lustre_ins && .venv/bin/python main.py tune --config config/deploy.yaml

验证:ssh root@<client> 'lctl get_param mdc.*.max_mod_rpcs_in_flight' 返回 31;ssh root@<client> 'systemctl is-active lustre-tune.service' 返回 active


fstab 开机失败

症状:节点重启后卡在 mount 阶段;或 Lustre 挂载点未自动挂载。

诊断

# 1. 确认 fstab 条目
ssh root@192.168.31.21 'grep lustre /etc/fstab'
# 预期:/dev/vdb /mnt/mdt0 lustre defaults,noexec,nofail 0 0
# 异常:无 nofail → 开机会卡死

# 2. 确认挂载点目录存在
ssh root@192.168.31.21 'ls -d /mnt/mdt0'
# 预期:目录存在
# 异常:无 → mkdir -p

处置 - 步骤 1 异常(无 nofail)→ cd /home/rain/Documents/lustre_ins && .venv/bin/python main.py tune --config config/deploy.yaml(含 fstab 修复) - 紧急修复:ssh root@192.168.31.21 'sed -i "s/defaults/defaults,nofail/" /etc/fstab'(仅当前条目) - 步骤 2 异常 → ssh root@192.168.31.21 'mkdir -p /mnt/mdt0'

验证:ssh root@192.168.31.21 'mount -a && findmnt /mnt/mdt0' 显示挂载

如果节点已卡在开机阶段:进入单用户模式(systemd.unit=rescue.target),编辑 /etc/fstab 加 nofail,重启。


普通用户写入 Permission denied

症状:客户端已挂载(state=FULL),普通用户(如 rain01)创建文件报 Permission denied,而 root 正常; 目录权限位(甚至 1777)、SELinux 均正常。

诊断

# 1. 先排除权限位与 SELinux(在客户端)
ssh root@<client> 'stat -c "%A %U:%G %n" /mnt/lustre/scratch/tmp; getenforce'
# 预期:drwxrwxrwt root:root 与 Disabled/Permissive —— 两者都正常说明问题不在客户端

# 2. 真实写入复现(勿用 test -w,它在 llite 上会误报可写)
ssh root@<client> "su -s /bin/bash rain01 -c 'touch /mnt/lustre/scratch/tmp/.p && rm -f /mnt/lustre/scratch/tmp/.p'"
# 预期:Permission denied 即复现

# 3. 关键判据:MDS 身份解析日志
ssh root@192.168.31.21 "journalctl --since '-10min' | grep -iE 'l_getidentity|no such user'"
# 命中 "no such user <uid>" → 根因:服务端解析不到该 UID

# 4. 确认服务端确实解析不到,并解释 root 为何正常
ssh root@192.168.31.21 'getent passwd 2001; lctl get_param -n mdt.*.root_squash'
# 预期:getent 无输出(解析失败);root_squash=0:0

处置 - 根因:客户端用户来自集中身份源(SSSD/LDAP 域 rainchen,ldap_id_mapping=false), 而服务端未接入同一身份源 → MDS 的 l_getidentity 解析失败 → 拒绝一切非 root 请求 - 最小修复(在服务端 .21/.22 各执行;先备份 /etc/{passwd,group,shadow,gshadow}): getent group 2000 || groupadd -g 2000 design getent passwd 2001 || useradd -u 2001 -g 2000 -M -s /sbin/nologin rain01 —— UID/GID 必须与客户端逐位一致 - 长期修复:服务端接入同一 LDAP(装 sssd/sssd-ldap + 复制客户端 sssd.conf + systemctl enable --now sssd) - 不要改目录权限,也不要改 mdt.*.identity_upcall:身份解析失败时任何权限位都不生效

验证:ssh root@<client> "su -s /bin/bash rain01 -c 'touch /mnt/lustre/scratch/tmp/.v && rm -f /mnt/lustre/scratch/tmp/.v && echo OK'" 输出 OK; MDS 侧 journalctl --since '-10min' | grep -c l_getidentity 为 0

完整变更记录(含证据与回滚)见 fix-lustre-write-perm/SOP.md。


客户端读写慢

症状:EDA 作业 IO 等待高;dd 测试吞吐远低于预期。

诊断

# 1. 确认调优参数生效
ssh root@<client> 'lctl get_param osc.*.max_rpcs_in_flight'
# 预期:32
# 异常:默认值(4) → 见 [lctl 参数不持久化](#lctl-参数不持久化)

# 2. 确认 statahead 生效
ssh root@<client> 'lctl get_param llite.*.statahead_max'
# 预期:512

# 3. 确认 LC 缓存大小
ssh root@<client> 'lctl get_param ldlm.namespaces.*.lru_size'
# 预期:100 × CPU 核数

# 4. 确认 striping 合理
ssh root@<client> 'lfs getstripe /mnt/lustre/eda_large_files'
# 预期:stripe_size=16M, stripe_count=1(单 OST)或 4(多 OST)

# 5. 确认 OST 负载
ssh root@192.168.31.22 'iostat -x 1 3'
# 预期:%util < 80%
# 异常:%util 持续 100% → OST 瓶颈,需加 OST

# 6. 确认网络带宽
ssh root@<client> 'iperf3 -c 192.168.31.22 -t 10'
# 预期:接近链路带宽

处置 - 步骤 1-3 异常 → .venv/bin/python main.py tune --config config/deploy.yaml - 步骤 4 异常 → ssh root@<client> 'lfs setstripe /mnt/lustre/eda_large_files -S 16M -c 4'(多 OST 时) - 步骤 5 异常 → .venv/bin/python main.py add-ost --config config/deploy.yaml --force(加 OST 扩容) - 步骤 6 异常 → 网络硬件问题

验证:ssh root@<client> 'dd if=/dev/zero of=/mnt/lustre/eda_scratch/test bs=1M count=1024' 吞吐达标


striping 未生效

症状:lfs getstripe 显示默认 striping;EDA 文件分布不合理。

诊断

# 1. 确认模板目录存在
ssh root@<client> 'ls -d /mnt/lustre/eda_small_files /mnt/lustre/eda_large_files /mnt/lustre/eda_shared_files /mnt/lustre/eda_scratch'
# 预期:4 个目录都存在
# 异常:无 → stripe_tuning 模块未跑

# 2. 确认 striping 设置
ssh root@<client> 'lfs getstripe /mnt/lustre/eda_small_files'
# 预期:stripe_size=1M, stripe_count=1
# 异常:默认值 → 未设置

# 3. 确认已有文件继承 striping
ssh root@<client> 'lfs getstripe /mnt/lustre/eda_small_files/<已有文件>'
# 预期:与目录一致
# 异常:不一致 → 文件在设置前已存在

处置 - 步骤 1 异常 → cd /home/rain/Documents/lustre_ins && .venv/bin/python main.py tune --config config/deploy.yaml - 步骤 2 异常 → ssh root@<client> 'lfs setstripe /mnt/lustre/eda_small_files -S 1M -c 1' - 步骤 3 异常 → 已有文件不自动迁移;新文件会继承目录 striping

验证:ssh root@<client> 'lfs getstripe /mnt/lustre/eda_small_files' 返回期望参数


HA failover 异常

症状:Pacemaker 集群 failover 后 MDT/OST 不在线;pcs status 显示资源 Stopped。

诊断

# 1. 确认集群状态
ssh root@192.168.31.21 'pcs status'
# 预期:Cluster is running,资源 Started
# 异常:Cluster down → pcs cluster start --all

# 2. 确认 cib 配置
ssh root@192.168.31.21 'pcs config'
# 预期:含 MDT/OST 资源定义
# 异常:无 → 人工配置 cib(HA 是 stub)

# 3. 查看资源失败原因
ssh root@192.168.31.21 'pcs resource failcount show'
# 预期:无失败
# 异常:有失败 → pcs resource cleanup

# 4. 确认 VIP 可达
ssh root@192.168.31.21 'ping 192.168.31.100'
# 预期:通
# 异常:不通 → VIP 未分配

处置 - 步骤 1 异常 → ssh root@192.168.31.21 'pcs cluster start --all' - 步骤 2 异常 → 人工配置 cib(见 SOP 5.7 enable-ha 注释) - 步骤 3 异常 → ssh root@192.168.31.21 'pcs resource cleanup <资源名>' - 步骤 4 异常 → ssh root@192.168.31.21 'pcs resource move <VIP资源名> <节点名>'

验证:ssh root@192.168.31.21 'pcs status' 显示所有资源 Started;lctl dl 显示 MDT/OST UP

注意:HA 是 stub 实现,cib 配置需人工执行;详见 SOP.md 5.7。


来源:/home/rain/Documents/lustre_ins/docs/troubleshoot.md | 最后更新:2026-10-06 05:26(由 build/sync.py 同步,请勿在站点侧修改)