Pacemaker 双节点:故障判定与仲裁机制
这份文档把"双节点高可用集群到底怎么知道对方挂了、挂了之后干嘛、双方互失联时谁说了算"用大白话+类比讲清楚。它和工程部署文档互补:部署文档讲"敲哪些命令",本文档讲"为什么这么设计、各组件谁来判谁来动手"。
1. 一句话心智模型
把整个双节点 HA 想成 两个保安守同一座金库,每人一把钥匙,但规定"钥匙不能同时用":
- 对讲机(Corosync + knet):两人每秒互喊"我还在",靠心跳确认对方活着。
- 点名法官(votequorum):数"现在还有几个活人、够不够法定票数"。
- 大脑(Pacemaker):收到"对方没了"后决定"谁该跑什么服务"。
- 行刑队(STONITH / Fencing):在动钥匙之前,必须先把对方物理干掉,防止两人同时开金库。
- 第三方裁判机(qdevice):两人互相看不见时,请一个中立保安室投决胜票,决定谁有资格当班。
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 只是接收结果。具体过程:
- 正常运行时,A、B 每秒通过
Corosync互发心跳令牌,走knet。 - B 宕机或心跳网断 → B 不再回令牌。
- A 会按配置重传令牌默认约 10 次(
totem.token默认 1000ms ×token_retransmits_before_loss_const默认 10 ≈ 10 秒,外加 join/consensus 超时)。 - 重传耗尽仍无回应 → Corosync 宣布 B 退出成员(membership change)。这步是 Corosync 判的,Pacemaker 还没出场。
votequorum立刻重算法定票:在two_node: 1模式下,虽预期 2 票、只活 1 台,但规则特批"剩 1 台也算有法定票",所以 A 不会因少数而自停。
4. 失联之后会做什么(按顺序)
- 通知大脑:Pacemaker(
pacemaker-controld)收到"B 没了"的事件。 - 先杀(关键):因为
stonith-enabled=true(生产必开),Pacemaker 铁律是——没确认 B 真死之前,绝不把 B 的资源搬过来。pacemaker-fenced立刻调用 fence agent 把 B 物理断电/重启(STONITH)。 - 确认死亡:STONITH 成功返回,B 被标记为"已围栏"。
- 业务接管:Pacemaker 在 A 上启动原本跑在 B 上的资源——VIP、应用、文件系统/共享存储等,业务恢复。
- 回归:等 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 | "没票就停工" | 失法定票的节点必须停资源、不能乱动 |
6. 常见直觉误区:ping 网关?仲裁盘 = SBD?
误区一:"心跳断了,去 ping 一下网关看看自己状态"
想法很自然,但在脑裂场景救不了你。网关只证明"你能上网",证明不了"对方死了":
- 对称分区时,两边都能 ping 通网关 → 都觉得自己是唯一的活人,都要去接管 → 还是脑裂。
- 集群里
ocf:pacemaker:ping资源确实有正经用途:配成位置约束,让服务待在联网质量好的节点上(资源选路),但绝不用来防脑裂。 - 设计铁律:分区发生时,你对自己状态的判断不能当权威。裁决必须来自独立第三方(qdevice)或不可逆动作(围栏)。
误区二:"配个仲裁盘" —— 对,它就是 SBD
SBD(STONITH Block Device)= 一块两节点共享的小盘(SAN / iSCSI / FC LUN)。但要分清它的角色:
| 它像什么 | 实际干啥 |
|---|---|
| 仲裁机构? | ❌ 不是。它不决定"谁赢" |
| 围栏武器 ✅ | Pacemaker 通过 fence_sbd 在共享盘给对端写 "die";对端 sbd 守护进程看到消息(或自己不再刷心跳槽),看门狗超时 → 硬件硬重启——真正的 STONITH,只是不用 IPMI |
| 自围栏(watchdog 模式) | 节点失法定票时,看门狗把自己重启 |
7. qdevice 是服务吗?它只投票、不指挥
是服务,而且其实是"两个"守护进程:
corosync-qnetd:跑在那台独立的第三方裁判机上的服务(这就是 qdevice 本体)。corosync-qdevice:跑在每个集群节点上的客户端,负责连到 qnetd、汇报"我还活着"。
它做什么、不做什么:
| 它做的 | 它不做的 |
|---|---|
| 按规则(ffsplit/lms)投出一票进法定票池 | 不围栏、不断电、不动手 |
| 在分区时只把票投给一侧 | 不命令任何人去 fence |
| 自己不跑任何业务资源 | 不告诉 Pacemaker "你去杀 B" |
votequorum 算出"我有法定票"→ A 自己判定有资格 → A 的 Pacemaker 去围栏 B、接管资源。B 连不上 qnetd,算出"票不够"→ 自己判定没资格 → 停工待命。全程 qdevice 一句话没说,只是投了票;"谁赢、谁动手"是各节点自己算出来的。
8. SBD vs Dell iDRAC:能同时用吗?
先纠正前提:SBD 不做"集群级裁判",它是围栏机制(动手的那一层)。真正的分层:
决定谁有资格
votequorum + qdevice(可选)
执行围栏(把输家干掉)
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(杀备份) 可同时存在,各管各层 |
9. 名词速查表
| 名词 | 一句话 |
|---|---|
Corosync | 消息与成员管理层,集群的"对讲机+点名系统",真正判定失联 |
knet (kronosnet) | Corosync 底下收发心跳包的传输库,支持多冗余链路 |
Totem / token | 成员环里轮流传递的"令牌",超时未到即判失联 |
votequorum | 法定票计算,决定节点是否"有资格"运行资源 |
Pacemaker | 资源调度大脑,决定谁跑什么、何时切换 |
CIB | 集群配置与状态的 XML 总账本 |
STONITH / Fencing | Shoot 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 / lms | qdevice 的两种投票算法(先到先得 / 最后站着) |
auto_tie_breaker | 内置决胜票,预先分给某节点 ID,无需第三台机 |
SBD | STONITH Block Device,共享盘围栏(凶器,非法官) |
fence_sbd | 通过 SBD 共享盘执行围栏的 fence agent |
watchdog | 硬件/软件看门狗,超时未喂则硬重启本机(自围栏) |
ocf:pacemaker:ping | ping 资源,用于按连通性给服务选路(非防脑裂) |
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. 配套资料与参考
本文档聚焦"为什么这么设计",与以下工程文档互补:
- pacemaker-core-modules-training.html — Pacemaker 核心模块培训(架构/CIB/资源/约束/属性/工具链)
- pacemaker-two-node-cluster-setup.html — 双节点集群从零部署配置手册(命令可复制)
官方来源(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) 项目。