4. STONITH与隔离机制

在 Pacemaker 集群中,资源能够被启动、停止和迁移,前提是集群对节点状态有确定性的判断。一旦某个节点失去响应,集群面临的最大风险不是“它停了”,而是“它可能还活着”。如果该节点仍在访问共享存储、仍持有虚拟 IP、仍向数据库写入数据,而集群又在另一节点上启动同名资源,就会产生双写、脑裂和数据损坏。隔离机制(fencing)正是为消除这种不确定性而存在:在允许恢复服务之前,先用强制手段让故障节点彻底失去继续操作资源的能力。

隔离原理:先隔离,后恢复

Pacemaker 的策略可以概括为一句话:任何资源在故障节点上被确认隔离成功之前,不得在其他节点上启动。隔离不是“重启服务”,而是对节点施加不可协商的强制动作。常见手段有两类:电源 fencing 通过 IPMI、iDRAC、iLO、PDU 或虚拟机管理接口切断或重启节点电源;存储 fencing 则通过 SCSI-3 Persistent Reservation、光纤通道分区或存储阵列端口禁用,阻断故障节点对共享 LUN 的访问。前者让节点整体下线,后者只切断数据路径,适用于无法断电但必须保护数据的场景。

隔离动作必须满足三个条件:可靠(能真正生效)、可验证(返回成功或失败)、独立于被隔离节点(不能依赖故障节点自身的服务)。因此,fence 设备通常由管理网访问,且每个节点都应配置至少一个可用的 fence 设备,避免单点。

Pacemaker 隔离决策与执行路径 节点 A(正常) DC 仲裁 · 资源运行中 corosync 心跳正常 节点 B(失联) 心跳超时 · 状态未知 可能仍持有资源 心跳中断(corosync 超时) Pacemaker 判定:节点 B 不可达 触发 fence 动作,禁止资源在 A 上启动 电源 Fencing IPMI / iDRAC / iLO / PDU fence_ipmilan · fence_idrac 动作:power off / reboot 存储 Fencing SCSI-3 PR / FC 分区 / 阵列端口 fence_scsi · fence_mpath 动作:清除注册 / 阻断 LUN 节点 B 断电,资源释放 fence 返回 success 集群允许在 A 上恢复服务 节点 B 失去存储访问 PR 注册被清除 数据一致性得到保护 SBD 共享块设备 /dev/sdb1 毒丸 + 看门狗 自隔离

电源 Fencing:最直接、最可靠的隔离

电源 fencing 通过带外管理接口对节点执行断电或重启。以 IPMI 为例,节点 B 的 BMC 地址为 192.168.10.12,用户为 fenceuser,密码存放在集群密钥文件中。配置命令如下:

pcs stonith create fence-b fence_ipmilan \
  ipaddr=192.168.10.12 login=fenceuser passwd=Cluster@123 \
  lanplus=1 pcmk_host_list=nodeB \
  power_timeout=20 pcmk_reboot_timeout=60

pcs stonith show fence-b
pcs stonith status

其中 pcmk_host_list=nodeB 明确该设备只负责隔离 nodeB,避免误伤。执行隔离时,Pacemaker 调用 fence_ipmilan 发送 IPMI 命令,BMC 切断主机电源。若节点支持重启,也可使用 reboot 动作,但断电更彻底,能确保内存中未落盘的数据不会继续写入。

配置完成后必须验证:stonith_admin --list-installed 查看设备是否注册;stonith_admin -M -n nodeB 查询 nodeB 的隔离设备映射;stonith_admin --reboot nodeB 手动触发一次隔离,观察节点是否真正断电并重新加入集群。只有手动验证通过,才能认为 fence 设备可用。

存储 Fencing 与 SBD

当节点无法断电,或共享存储必须保持在线时,存储 fencing 更合适。SCSI-3 Persistent Reservation 允许集群节点在 LUN 上注册 reservation key,隔离时清除故障节点的注册,使其后续 I/O 被存储拒绝。配置示例:

pcs stonith create fence-scsi fence_scsi \
  devices=/dev/mapper/mpatha pcmk_host_list=nodeA,nodeB \
  meta provides=unfencing

SBD(STONITH Block Device)是另一种重要机制,常用于无 BMC 或共享存储环境。它在共享块设备上写入“毒丸”消息,配合 watchdog 实现节点自隔离:节点 A 在无法确认节点 B 状态时,向 SBD 设备写入针对 B 的毒丸;B 的 watchdog 检测到毒丸后强制重启自身。SBD 需要至少三个节点或使用仲裁设备,避免单点误判。典型配置包括 sbd -d /dev/sdb1 -1 60 -4 120 create 创建 SBD 设备,并在 /etc/sysconfig/sbd 中设置 SBD_DEVICE=/dev/sdb1 与 SBD_PACEMAKER=yes。

隔离策略测试与故障模拟

隔离策略不能只停留在配置层面,必须通过故障模拟验证。推荐按以下顺序进行:

  • 手动隔离测试:stonith_admin --reboot nodeB,确认节点断电、重启并重新加入集群。
  • 心跳中断模拟:在 nodeB 上执行 iptables -A INPUT -p udp --dport 5405 -j DROP 阻断 corosync,观察 nodeA 是否在超时后触发 fence。
  • 资源恢复验证:隔离成功后,检查 pcs status 中资源是否在 nodeA 上启动,且没有出现双主。
  • 日志核对:查看 /var/log/cluster/corosync.log 与 journalctl -u pacemaker,确认 fence 动作返回 success,且没有“fencing failed”记录。
测试隔离会真实断电或重启节点,务必在维护窗口进行,并确认业务已迁移或可中断。不要在生产高峰直接模拟。

判断隔离是否成功,关键看三点:fence 动作返回成功;故障节点确实失去资源访问能力;集群在隔离完成后才恢复服务。若 fence 返回失败,集群会保持资源停止,避免脑裂。此时应检查 BMC 网络、凭据、电源状态和 fence 设备映射,而不是强行启动资源。

建议为每个节点配置至少两个 fence 设备,例如 IPMI 加 PDU,形成冗余。定期用 stonith_admin --list-installed 和手动测试确认设备可用,避免真正故障时才发现隔离失效。

隔离机制是 RHEL 高可用集群的安全底线。理解电源 fencing、存储 fencing 与 SBD 的适用场景,掌握 fence 设备配置与验证方法,并通过故障模拟确认策略有效,才能让集群在节点故障时既快速恢复,又不牺牲数据一致性。