Pacemaker 双节点 · 故障判定与仲裁机制 培训文档(费曼讲解版)· 基于 Red Hat Enterprise Linux 10 官方文档

Pacemaker 双节点:故障判定与仲裁机制

这份文档把"双节点高可用集群到底怎么知道对方挂了、挂了之后干嘛、双方互失联时谁说了算"用大白话+类比讲清楚。它和工程部署文档互补:部署文档讲"敲哪些命令",本文档讲"为什么这么设计、各组件谁来判谁来动手"。

费曼读法建议:每一讲都先给一个"保安守金库"的类比,再对号入座到真实组件名。遇到不懂的名词,直接跳到 第 9 章名词速查表
① 判层 Quorum — 谁有资格 ② 杀层 Fencing — 怎么动手 ③ 大脑 Pacemaker — 调度 ④ 对讲机 Corosync — 心跳

1. 一句话心智模型

把整个双节点 HA 想成 两个保安守同一座金库,每人一把钥匙,但规定"钥匙不能同时用"

  • 对讲机(Corosync + knet):两人每秒互喊"我还在",靠心跳确认对方活着。
  • 点名法官(votequorum):数"现在还有几个活人、够不够法定票数"。
  • 大脑(Pacemaker):收到"对方没了"后决定"谁该跑什么服务"。
  • 行刑队(STONITH / Fencing):在动钥匙之前,必须先把对方物理干掉,防止两人同时开金库。
  • 第三方裁判机(qdevice):两人互相看不见时,请一个中立保安室投决胜票,决定谁有资格当班。
最核心的一句话:"谁判定对方 lost" 是 Corosync 干的(消息/成员层),不是 Pacemaker;Pacemaker 只是收到消息后负责"先杀再接管"的大脑。

2. 组件角色总览(费曼命名 → 真名)

大白话真名在流程里的角色
对讲机 + 点名系统Corosync真正判定对方失联的组件(成员管理层)
对讲机底下的网线库knet (kronosnet)负责在多条心跳链路上收发心跳包
轮流传的点名棒Totem / token谁没在时限内收到/转发令牌,谁就被判失联
数票的小法官votequorum算"活着的节点够不够法定票数"
集群大脑 / 调度层Pacemaker收到失联事件后决定"谁该跑什么服务"
集群总账本CIB记录配置与状态的 XML 数据库(Pacemaker 读它决策)
把对方物理干掉STONITH / Fencing防脑裂的硬手段:断电/重启
真正去拉电闸的工具fence agent如 IPMI/iDRAC、VMware API、SBD
专管行刑的守护进程pacemaker-fenced (STONITHd)调用 fence agent 完成 STONITH
双节点专属模式two_node只剩 1 台也认作"有法定票",避免活着的也停摆
第三方裁判机qdevice不在集群里,只投决胜票打破平局
最危险的事故split-brain 脑裂两个节点都以为自己是老大,同时动资源

3. 怎么知道对方"失联"了

判定失联这件事是 Corosync 做的,Pacemaker 只是接收结果。具体过程:

  1. 正常运行时,A、B 每秒通过 Corosync 互发心跳令牌,走 knet
  2. B 宕机或心跳网断 → B 不再回令牌。
  3. A 会按配置重传令牌默认约 10 次totem.token 默认 1000ms × token_retransmits_before_loss_const 默认 10 ≈ 10 秒,外加 join/consensus 超时)。
  4. 重传耗尽仍无回应 → Corosync 宣布 B 退出成员(membership change)。这步是 Corosync 判的,Pacemaker 还没出场。
  5. votequorum 立刻重算法定票:在 two_node: 1 模式下,虽预期 2 票、只活 1 台,但规则特批"剩 1 台也算有法定票",所以 A 不会因少数而自停
HA 双节点:发现对方失联与接管流程 从正常心跳到判定失联、算票、通知 Pacemaker、STONITH 围栏、业务接管的六步时序。 1 正常心跳:每秒互喊一次 A 与 B 经 Corosync 每秒互发"心跳令牌"(token),knet 走心跳网。 Corosync + knet 2 判失联:约 10 秒认定"掉了" B 停回应;A 重传令牌约 10 次(默认~10s)无应答 → Corosync 判 B 退出成员。 Corosync / Totem 3 重新算票:剩 1 台也算"有票" votequorum 重算法定票;two_node 模式下仅剩 A 仍保有法定票,不会自停。 votequorum 4 通知大脑:但先别搬 Pacemaker 收到"B 没了";因 stonith-enabled=true:未确 B 真死前不搬服务。 Pacemaker (controld) 5 先动手杀:物理干掉对方 pacemaker-fenced 调 fence agent(IPMI/VMware/SBD)把 B 断电重启 → STONITH 完成。 fenced + fence agent 6 业务接管:在活着的节点拉起 B 已确认死亡,Pacemaker 在 A 上启动原属 B 的资源(VIP/服务/存储)。 Pacemaker (execd) 为什么必须"先杀再接管"? 怕 B 只是心跳网断了却还活着 → 两节点同时挂同一块共享盘 = 数据损坏(脑裂 split-brain)。
图 1:单节点失联 → 检测 → 算票 → 先围栏 → 再接管 的六步时序

4. 失联之后会做什么(按顺序)

  1. 通知大脑:Pacemaker(pacemaker-controld)收到"B 没了"的事件。
  2. 先杀(关键):因为 stonith-enabled=true(生产必开),Pacemaker 铁律是——没确认 B 真死之前,绝不把 B 的资源搬过来pacemaker-fenced 立刻调用 fence agent 把 B 物理断电/重启(STONITH)。
  3. 确认死亡:STONITH 成功返回,B 被标记为"已围栏"。
  4. 业务接管:Pacemaker 在 A 上启动原本跑在 B 上的资源——VIP、应用、文件系统/共享存储等,业务恢复。
  5. 回归:等 B 修好、心跳恢复后重新加入,资源可保持留在 A(resource-stickiness),也可按策略迁回。
铁律:先做不可逆的"确认对方死透",才敢动共享资源——这是从设计上根除脑裂的唯一办法。stonith-enabled=false 严禁上生产。

5. 双方都以为对方失联(网络分区 / 脑裂)

最危险的情况是中间链路断了,A、B 互相都判对方 lost。这次不是"一个真死一个假死",而是"两人都以为自己是唯一活人,都要去开金库"。

为什么纯 two_node 会"猜拳"

two_node: 1 下,每个节点单独都算"有法定票"。于是 A、B 都认为自己有资格 → 都去围栏对方,变成围栏竞速(fencing race)。碰运气,极端时两边都 fence 不掉、最后都活着都开金库 = 共享盘损坏。所以 RHEL 官方对双节点集群强烈建议配 qdevice

第三方裁判机 qdevice 怎么判

金库公司设了一个独立的中立保安室(qdevice),A、B 都能单独打电话过去。保安室只做一件事:按固定规则,只认证其中一人"有资格当班"。被认证的人拿到上岗许可(法定票),可以去拉另一个人的电闸并开金库;没被认证的人必须放下钥匙、原地待命。

名字大白话作用
qdevice中立裁判机(第三方主机)不参与跑业务,只投决定性的一票
corosync-qnetd裁判机上的守护进程真正做投票决策的进程
corosync-qdevice每节点的投票客户端连到 qnetd、上报自己还活着
ffsplit"先到先得"规则平票时按固定顺序只给其中一边投票
lms"最后站着的人"规则动态把票投给最后存活的一方
auto_tie_breaker (ATB)内置指定赢家(无需第三台机)votequorum 自带:把决胜票预先分给某节点 ID
no-quorum-policy=stop"没票就停工"失法定票的节点必须停资源、不能乱动
双节点互失联:第三方 qdevice 仲裁判定 当 A 与 B 互相失联时,qdevice 第三方裁判投出决胜票,决定哪一侧保有法定票可以 fence 并接管。 qdevice 裁判机(第三方) 节点 A 仍能连 qdevice 节点 B 连不上 qdevice 投票给我(绿) 未获投票(红) ✕ 链路断开 · 互相判 lost A 获法定票 → STONITH B + 接管 B 失法定票 → stop 资源、待命
图 2:A、B 互失联时,qdevice 投决胜票,只有一侧保有法定票可动手
关键:qdevice 只决定"谁有资格动手",围栏(STONITH)仍然照常发生,只是从"两边都抢着动手"变成"只有拿到票的那边动手"。qdevice 本身不跑业务、也不会被 fence。

6. 常见直觉误区:ping 网关?仲裁盘 = SBD?

误区一:"心跳断了,去 ping 一下网关看看自己状态"

想法很自然,但在脑裂场景救不了你。网关只证明"你能上网",证明不了"对方死了":

  • 对称分区时,两边都能 ping 通网关 → 都觉得自己是唯一的活人,都要去接管 → 还是脑裂。
  • 集群里 ocf:pacemaker:ping 资源确实有正经用途:配成位置约束,让服务待在联网质量好的节点上(资源选路),但绝不用来防脑裂
  • 设计铁律:分区发生时,你对自己状态的判断不能当权威。裁决必须来自独立第三方(qdevice)或不可逆动作(围栏)。
"检查自己、不行就认输"的正确版本:watchdog 自围栏——节点一旦失去法定票(既看不到 peer、也连不上 qdevice),硬件看门狗就把它自己硬重启。注意触发它的是"失去法定票",不是"ping 不通网关"。

误区二:"配个仲裁盘" —— 对,它就是 SBD

SBD(STONITH Block Device)= 一块两节点共享的小盘(SAN / iSCSI / FC LUN)。但要分清它的角色:

它像什么实际干啥
仲裁机构?❌ 不是。它不决定"谁赢"
围栏武器 ✅Pacemaker 通过 fence_sbd 在共享盘给对端写 "die";对端 sbd 守护进程看到消息(或自己不再刷心跳槽),看门狗超时 → 硬件硬重启——真正的 STONITH,只是不用 IPMI
自围栏(watchdog 模式)节点失法定票时,看门狗把自己重启
一句话:SBD 是仲裁盘没错,但它仲裁的是"执行处决",不是"谁当班长"。谁当班长仍是 quorum(two_node / qdevice / ATB)说了算。
网关 ping 的局限 与 SBD 共享盘作为仲裁盘 对比网关 ping 只查自身链路无法判胜负,与 SBD 共享盘经由看门狗执行硬重启的真实围栏。 网关 (ping 自检) 节点 A 看门狗 watchdog 节点 B 看门狗 watchdog SBD 共享盘 消息槽 A | 消息槽 B (仲裁盘) 都能 ping 通 都能 ping 通 ① A 写 die 到 B 槽 ② B 看门狗超时→硬重启 网关 ping 只查自身链路、无法判胜负;SBD 盘是真实仲裁机构,靠看门狗执行硬重启。
图 3:网关 ping(非权威)vs SBD 共享盘(真仲裁 + 看门狗硬重启)

7. qdevice 是服务吗?它只投票、不指挥

是服务,而且其实是"两个"守护进程:

  • corosync-qnetd:跑在那台独立的第三方裁判机上的服务(这就是 qdevice 本体)。
  • corosync-qdevice:跑在每个集群节点上的客户端,负责连到 qnetd、汇报"我还活着"。

它做什么、不做什么:

它做的它不做的
按规则(ffsplit/lms)投出一票进法定票池不围栏、不断电、不动手
在分区时只把票投给一侧不命令任何人去 fence
自己不跑任何业务资源不告诉 Pacemaker "你去杀 B"
完整串法:qnetd 把决胜票投给连上它的那侧(如 A)→ A 本地 votequorum 算出"我有法定票"→ A 自己判定有资格 → A 的 Pacemaker 去围栏 B、接管资源。B 连不上 qnetd,算出"票不够"→ 自己判定没资格 → 停工待命。
全程 qdevice 一句话没说,只是投了票;"谁赢、谁动手"是各节点自己算出来的。

8. SBD vs Dell iDRAC:能同时用吗?

先纠正前提:SBD 不做"集群级裁判",它是围栏机制(动手的那一层)。真正的分层:

① 判层 · Quorum
决定谁有资格
votequorum + qdevice(可选)
② 杀层 · Fencing
执行围栏(把输家干掉)
fence_ipmilan(iDRAC) / fence_sbd / fence_vmware_rest

结论:qdevice 与 iDRAC 不是 alternatives(不同层,不是二选一);iDRAC 与 SBD 才是同层 alternatives,而且可以叠成双保险——这叫 fencing 级别(levels)

  • Level 1:先试 fence_ipmilan(iDRAC 带外断电)
  • Level 2:iDRAC 万一连不上/失败,自动回退fence_sbd(共享盘)

配置思路(pcs):

pcs stonith create ipmi-node1 fence_ipmilan ...   # iDRAC
pcs stonith create sbd-node1   fence_sbd ...       # SBD 共享盘
pcs stonith level add 1 node1 ipmi-node1           # 先试 iDRAC
pcs stonith level add 2 node1 sbd-node1            # 不行再试 SBD
场景建议
物理 Dell、有 iDRAC、没共享盘只用 fence_ipmilan 就够,干净
有 iDRAC 但想加保险iDRAC + SBD 做 Level 1/2 互为备份,不冲突
云/虚机、无 IPMI只能靠 SBD(需共享盘)或 fence_vmware_rest
三者关系qdevice(判) + iDRAC(杀) + SBD(杀备份) 可同时存在,各管各层
判层(Quorum)与杀层(Fencing)的组件定位 qdevice 只投票不参与围栏,位于判层;fence_ipmilan 与 fence_sbd 同属杀层,可设为 Level 1/2 互为备份。 ① 判层 · Quorum — 决定谁有资格动手 votequorum(每节点自带) qdevice 裁判机 只投票 · 不指挥 · 不围栏 投决胜票 Pacemaker(大脑) ② 杀层 · Fencing — 执行围栏(把输家干掉) fence_ipmilan (Dell iDRAC) 带外断电重启 fence_sbd(SBD 共享盘) 写 die → 看门狗硬重启 两者可设 Level 1 / Level 2 互为备份,互不冲突
图 4:判层 / 杀层 与四个核心组件的定位

9. 名词速查表

名词一句话
Corosync消息与成员管理层,集群的"对讲机+点名系统",真正判定失联
knet (kronosnet)Corosync 底下收发心跳包的传输库,支持多冗余链路
Totem / token成员环里轮流传递的"令牌",超时未到即判失联
votequorum法定票计算,决定节点是否"有资格"运行资源
Pacemaker资源调度大脑,决定谁跑什么、何时切换
CIB集群配置与状态的 XML 总账本
STONITH / FencingShoot The Other Node In The Head,物理干掉失联节点
fence agent执行围栏的具体工具:IPMI/iDRAC、VMware、SBD 等
pacemaker-fenced专管执行 STONITH 的守护进程(原 STONITHd)
two_node双节点模式:仅剩 1 台也认作有法定票
qdevice第三方仲裁机,投决胜票打破平局(只投票不围栏)
corosync-qnetd裁判机上的投票服务
corosync-qdevice每节点上连 qnetd 的投票客户端
ffsplit / lmsqdevice 的两种投票算法(先到先得 / 最后站着)
auto_tie_breaker内置决胜票,预先分给某节点 ID,无需第三台机
SBDSTONITH Block Device,共享盘围栏(凶器,非法官)
fence_sbd通过 SBD 共享盘执行围栏的 fence agent
watchdog硬件/软件看门狗,超时未喂则硬重启本机(自围栏)
ocf:pacemaker:pingping 资源,用于按连通性给服务选路(非防脑裂)
no-quorum-policy失法定票时的行为,生产常设 stop
split-brain脑裂:两节点都认为自己是老大,同时动资源

10. 常见误区(FAQ 复盘)

Q1:心跳断了,是不是该去 ping 网关看看自己状态?

不行。网关只证明"你能上网",证明不了"对方死了"。对称分区时两边都 ping 得通,都以为自己该接管 → 还是脑裂。ping 网关在集群里只用于资源选路(让服务待在联网好的节点),绝不当作防脑裂的裁决。正确版"自判"是 watchdog 自围栏:失法定票才自重启。

Q2:仲裁盘就是 SBD 吗?

是,但它是"凶器"不是"法官"。 SBD(STONITH Block Device)就是那块两节点共享的仲裁盘,靠看门狗把输家硬重启。但它不决定谁有法定票;"谁当班长"仍由 quorum(two_node / qdevice / ATB)决定。SBD 是围栏手段,不是裁判机制。

Q3:qdevice 是服务吗?只判不动手,会去指挥别人吗?

是服务(corosync-qnetd + 各节点 corosync-qdevice)。只投票、不指挥、不动手。qnetd 把决胜票投给一侧后,是各节点本地 votequorum + Pacemaker 自己算出"我有资格"并去围栏。qdevice 全程一句话没说,只是投了票。

Q4:SBD 能判又能动手,和 Dell iDRAC 能同时用吗?

SBD 不做集群级裁判,它与 iDRAC 同属"杀层(Fencing)"。所以两者不是二选一,可以叠加成 Level 1 / Level 2 互为备份:先试 iDRAC,失败回退 SBD。qdevice(判)与 iDRAC(杀)是不同层,更不是 alternatives。三者可共存,各管各的层。

Q5:默认多久判定对方失联?

10 秒totem.token 默认 1000ms × token_retransmits_before_loss_const 默认 10,外加 join/consensus 超时。可调小以降低检测延迟,但过小会在网络抖动时误判。

11. 自测题(点开看答案)

1. 是谁判定对方"失联"?Corosync 还是 Pacemaker?

Corosync(消息/成员层,通过 Totem 令牌超时判定)。Pacemaker 只是接收"成员变更"事件后再决策。

2. 失联后为什么必须先围栏再接管?

怕失联节点只是"心跳断了却还活着",两边同时挂同一共享盘 = 数据损坏(脑裂)。必须先物理确认它死透,才敢动它的资源。

3. 双节点互失联,靠什么打破平局?

qdevice 第三方裁判机投决胜票(ffsplit/lms);或无第三台机时用内置 auto_tie_breaker。拿到票的一侧保有法定票可动手,另一侧停工待命。

4. qdevice 会命令 Pacemaker 去围栏吗?

不会。 qdevice 只往法定票池投一票;"谁有资格、谁去围栏"是各节点本地 votequorum + Pacemaker 自己算出来的。

5. Dell iDRAC 和 SBD 能同时用吗?怎么配?

能。 它们是同层(Fencing)的两种武器,用 pcs stonith level add 1/2 设成 Level 1(iDRAC)先试、Level 2(SBD)回退,互为备份。

6. ping 网关能用来防脑裂吗?

不能。 网关只反映你到上游的链路,与 peer 是否存活无关;对称分区下两边都通。ping 资源仅用于服务选路。

12. 配套资料与参考

本文档聚焦"为什么这么设计",与以下工程文档互补:

官方来源(RHEL 10 高可用集群文档):

  • Configuring and managing High Availability clusters (RHEL 10) — docs.redhat.com/en/documentation/red_hat_enterprise_linux/10/html/configuring_and_managing_high_availability_clusters/
  • 章节重点:Overview of HA、Creating a cluster、Configuring quorum、Configuring quorum devices (qdevice)、Fencing (STONITH)、SBD、Fencing levels。
  • 社区补充:ClusterLabs Pacemaker / Corosync 文档、kronosnet (knet) 项目。