已解决:Pacemaker/DRBD:自动回退导致活动 DRBD 同步从主到备失效。如何防止?
Source: Dev.to
请提供您希望翻译的完整文本内容(除代码块和 URL 之外),我将按照要求将其翻译为简体中文并保留原有的 Markdown 格式。谢谢!
执行摘要
TL;DR: Pacemaker 默认的自动回退行为可能会在恢复中的节点上尝试过早提升,从而干扰正在运行的 DRBD 主节点,导致服务中断并可能产生数据风险。可以通过以下方式防止此问题:
- 在 DRBD 主/从克隆资源上配置 负资源粘性(例如
-10000)。 - 实施 手动回退(待机模式或位置约束)。
- 设置 平滑、延迟的提升,配合可靠的 STONITH、增加
cluster-delay,以及更宽松的promoted-stop-timeout值。
为什么会发生
Pacemaker/DRBD 集群提供高可用性,但默认行为往往会在首选节点恢复后立即尝试将资源“回退”到该节点。在 DRBD 环境中,这可能是灾难性的:
| 症状 | 描述 |
|---|---|
| 服务中断 | 活跃的 DRBD 主节点上的应用程序停止或变得无响应。 |
| DRBD 状态变化 | 主节点切换为 Secondary、Unknown,或显示冲突状态(例如 WFConnection、StandAlone)。 |
| Pacemaker 日志条目 | 日志显示在恢复节点上的提升尝试,以及在当前主节点上的降级或隔离操作。查找 drbd_promote、drbd_demote 或冲突信息。 |
示例 Pacemaker 日志片段
Sep 20 10:35:01 node-a pacemakerd[12345]: info: Status: Requesting promote of drbd_res on node-a
Sep 20 10:35:01 node-a pacemakerd[12345]: crit: Result: promote_drbd_res_on_node-a: CIB_R_ERR_OP_FAILED
Sep 20 10:35:01 node-b pacemakerd[12345]: info: Status: Requesting demote of drbd_res on node-b
Sep 20 10:35:01 node-b pacemakerd[12345]: info: drbd_demote: stdout [drbd_demote: Attempting to demote resource 'r0']
Sep 20 10:35:02 node-b pacemakerd[12345]: warn: drbd_demote: stderr [drbd_demote: Cannot demote 'r0', it is still in use.]
Sep 20 10:35:02 node-b pacemakerd[12345]: crit: Result: demote_drbd_res_on_node-b: CIB_R_ERR_OP_FAILED
在问题发生期间运行 drbd-overview 将显示意外的角色或连接。
示例 drbd-overview 输出(冲突期间)
0:r0 Connected Primary/Primary UpToDate/UpToDate
[WARNING: This indicates split‑brain in a two‑node cluster, which Pacemaker should prevent]
[More likely, you'll see a quick flip or errors.]
Source: …
核心问题
- 资源本地性偏好 – Pacemaker 更倾向于将资源保留在它们的“首选”节点上。当节点恢复时,Pacemaker 会再次将其视为合适的候选节点。
- DRBD 主节点要求 – 在两节点同步(Protocol C)DRBD 配置中,任意时刻只能有 一个 节点处于 Primary(主)状态。
- 过早的提升尝试 – Pacemaker 可能会在恢复节点 立即 尝试提升 DRBD 资源,而此时当前的主节点尚未安全降级。
- 导致的冲突 – 这可能会产生:
- 提升失败(如果资源代理检测到另一个主节点)。
- 竞争条件,使两个节点短暂地都认为自己应该是主节点。
- DRBD 的内部冲突解决(自动降级或围栏),从而导致 I/O 中断和应用故障。
解决方案
1. 负资源粘性
# Example: set a very high negative stickiness on the DRBD clone
pcs resource defaults resource-stickiness=-10000
- 确保 Pacemaker 不会自动回退 DRBD 资源。
- 该资源会保持在当前主节点,直到管理员手动迁移它。
2. 手动回退策略
| 方法 | 工作原理 |
|---|---|
| 待机模式 | 将恢复中的节点置于待机状态 (pcs node standby <node>)。在清除待机之前,Pacemaker 不会在该节点上调度任何资源。 |
| 带负分数的位置约束 | 创建一个位置规则,使 Promoted(提升)角色在恢复节点上获得很大的负分数。例如: |
| ```bash | |
| pcs constraint location drbd_res prefers node-a=INFINITY | |
| pcs constraint location drbd_res avoids node-b=-1000 role=Promoted |
| **显式迁移** | 当准备提升时,使用 `pcs resource move drbd_res <node>`。 |
### 3. 平滑与延迟提升
1. **强健的 STONITH** – 确保围栏(fencing)可靠工作;否则 Pacemaker 可能会跳过安全降级。
2. **增加 `cluster-delay`** – 为集群提供更多时间在执行操作前传播状态变化。
```bash
pcs property set cluster-delay=30s
-
设置宽裕的
promoted-stop-timeout– 允许旧的主节点干净地完成降级。pcs resource update drbd_res meta promoted-stop-timeout=120s -
可选:
migration-threshold– 防止资源快速来回迁移。pcs resource defaults migration-threshold=3
安全的 DRBD‑Pacemaker 集群检查清单
- STONITH 已在所有节点上配置并测试。
- 已对 DRBD 资源应用负粘性(或等效的位置约束)。
- 已根据工作负载调优 Cluster‑delay 和 promoted‑stop‑timeout 参数。
- 已设置监控(例如
pcs status、drbd-overview、Pacemaker 日志),在提升/降级事件时发出警报。 - 为操作员编写了手动故障恢复程序的文档。
TL;DR (重新表述)
- 设置较高的负数
resource-stickiness(或使用位置约束)以阻止自动回退。 - 当需要迁移主节点时,手动进行(standby、
pcs resource move,或显式位置规则)。 - 如果希望自动回退,确保 STONITH 正常工作,增加
cluster-delay,并提升promoted-stop-timeout,以便旧的主节点在新节点提升前能够干净地降级。
通过遵循这些步骤,你可以避免“kill”情形,使 DRBD 资源保持稳定,并为你的服务维持真正的高可用性。
防止 DRBD 节点恢复时出现 “kill” 场景
当先前 Primary(主节点)的节点重新上线,而另一节点已经在充当 Primary 时,Pacemaker 可能会尝试再次提升恢复中的节点。如果提升无法干净地完成,活动节点会被强制退出其角色,导致服务非正常关闭(即所谓的 kill)。
常见原因
- 缺乏优雅的降级 – Pacemaker 没有足够的时间或明确的指令在恢复节点自行声明之前将当前的 Primary 降级。
- 围栏(STONITH)不足或过慢 – 集群无法可靠地隔离故障节点。
下面提供三种经过验证的办法,在保持集群高可用性的同时避免此类情况。
1️⃣ 保持 Primary “粘性”(负资源粘性)
Idea – 告诉 Pacemaker 永远不要把 DRBD 资源迁回刚恢复的节点,除非管理员手动操作。
工作原理
- 在 DRBD 克隆上设置一个很大的 负
resource-stickiness,使当前的 Primary “粘性”。 - 可选地添加一个位置约束,倾向于已经持有 Primary 的节点。
示例配置
# 1. 定义 DRBD 主/从资源(示例)
pcs resource create drbd_r0 ocf:linbit:drbd \
drbd_resource=r0 \
op monitor interval="60s" \
op promote interval="30s" start-timeout="90s" stop-timeout="90s" \
op demote interval="30s" start-timeout="90s" stop-timeout="90s" \
--clone globally-unique=true ordered=true interleave=true
# 2. 添加巨大的负粘性 → 禁用自动回切
pcs resource meta drbd_r0-clone resource-stickiness=-10000
# 3. 依赖 drbd_r0 为 Primary 的文件系统资源
pcs resource create fs_data ocf:heartbeat:Filesystem \
device="/dev/drbd/by-res/r0" directory="/mnt/data" fstype="ext4" \
op monitor interval="30s"
# 4. 确保 fs_data 只在 drbd_r0-clone 被提升时运行
pcs constraint colocation add fs_data with drbd_r0-clone INFINITY target-role=Promoted
# 5. 确保顺序:先提升 DRBD,再启动文件系统
pcs constraint order promote drbd_r0-clone then start fs_data
| 优点 | 缺点 |
|---|---|
| 高度可预测且可靠。 | 需要在恢复后手动执行 pcs resource move/migrate 才能回切。 |
| 防止因激进的自动回切导致的脑裂。 | 如果管理员响应慢,停机时间可能会增加。 |
| 简化故障排查——不会出现资源抖动。 | 资源可能长时间停留在次优节点上。 |
2️⃣ 将恢复中的节点置于 Standby(维护模式)
Idea – 阻止 Pacemaker 在刚恢复的节点上启动任何资源,给你时间先验证节点健康,再决定是否提升。
步骤
# 在管理员工作站(或任意集群节点)上执行
pcs node standby <node>
- 节点进入 standby 状态;Pacemaker 不会在其上调度资源。
- 验证完毕后,恢复节点:
pcs node unstandby <node>
- 如需回切,可手动迁移 DRBD 资源。
| 优点 | 缺点 |
|---|---|
| 完全的管理员控制回切过程。 | 每次恢复后都需要持续监控并手动操作。 |
| 最大限度降低意外主节点冲突的风险。 | 由于需要人工介入,停机时间可能更长。 |
| 在任何提升之前确保节点健康。 | 对典型的 HA 环境而言,自动化程度较低。 |
3️⃣ 使用 Location Constraint 阻止恢复节点的提升
Idea – 为恢复中的节点在 Promoted 角色上分配非常低(或
-INFINITY)的分数,使 Pacemaker 永远不会自动在该节点上提升 DRBD 资源。
示例
# 假设 node‑a 是首选的主节点。
# 当 node‑a 恢复时,我们希望它不要自动提升 drbd_r0。
# 为 Promoted 角色倾向于另一个节点 (node‑b)
pcs constraint location drbd
_r0-clone prefers=node-b=100 target-role=Promoted
# Explicitly avoid the recovering node for promotion
pcs constraint location drbd_r0-clone avoids=node-a=-INFINITY target-role=Promoted
- 您可以将此与方案 1 中的负粘性结合使用,以获得额外的安全性。
| 优点 | 缺点 |
|---|---|
| 提供细粒度控制,而无需将整个节点置于待机状态。 | 仍然需要手动干预来执行故障恢复。 |
| 防止自动提升,从而避免脑裂。 | 维护约束条件稍微复杂一些。 |
| 与粘性结合实现“双重锁”。 | 如果集群拓扑发生变化,可能需要进行调整。 |
📋 摘要
| 方案 | 如何阻止 “kill” 场景 | 何时使用 |
|---|---|---|
| 负粘性 (方案 1) | 将当前 Primary 保持在其节点上;恢复的节点保持为 Secondary,直至管理员手动迁移。 | 当你希望 自动 故障转移但 手动 故障恢复时的首选方案。 |
| 待机/维护模式 (方案 2) | 阻止 Pacemaker 触碰恢复中的节点,给你时间验证健康状态。 | 在节点健康检查必须在任何资源运行前完成的环境中非常有用。 |
| 位置约束 (方案 3) | 为恢复的节点赋予禁止提升为 Primary 的分数,同时仍允许其作为 Secondary 运行。 | 当你需要对单个资源进行控制而不必将整节点下线时适用。 |
这三种方法的目标相同:恢复的节点在没有明确的管理员批准前,永远不会自动提升其 DRBD 资源为 Primary。请选择最符合你的运营工作流和所需自动化程度的方案。
解决方案概述
该方案利用多个 Pacemaker 全局选项和资源元属性,以确保 顺序且受控的 DRBD 主角色切换。关键要素包括:
- 强大的隔离(STONITH)
- 增大的
cluster-delay用于状态传播 - 为资源操作精心配置的超时
1. 确保强大的隔离(STONITH)
为什么?
如果 Pacemaker 不能可靠地对故障节点进行隔离,则任何回退策略都不安全。
# Enable STONITH globally
pcs property set stonith-enabled=true
# Define the quorum policy (choose stop or freeze as required)
pcs property set no-quorum-policy=stop # or 'freeze'
# Create STONITH devices (example using fence_ipmi)
pcs stonith create fence_ipmi_node1 fence_ipmi \
ipaddr=192.168.1.10 pcmk_host_list=node-a \
login=admin passwd=password \
op monitor interval=60s
pcs stonith create fence_ipmi_node2 fence_ipmi \
ipaddr=192.168.1.11 pcmk_host_list=node-b \
login=admin passwd=password \
op monitor interval=60s
2. 增大 cluster-delay
为 Pacemaker 提供更多时间来传播状态变化,避免过早决策。
pcs property set cluster-delay=60s
这告诉 Pacemaker 在节点加入或离开后等待 60 秒,才进行重要的资源放置决策。
3. 配置 DRBD 超时
| 参数 | 用途 |
|---|---|
promoted-stop-timeout | Pacemaker 在 Master/Slave 资源上等待 降级 操作完成的最长时间。 |
stop-failure-is-fatal=false | 防止因降级(停止)失败而立即将资源标记为该节点上的永久失败。 |
pcs resource update drbd_r0-clone \
op demote timeout="120s" promoted-stop-timeout="180s" \
op stop timeout="120s" \
meta stop-failure-is-fatal=false
4. 可选:为首选节点设置资源粘性
如果希望 优雅的自动回退 到首选节点,可以添加适度的正向粘性或位置规则,但务必确保上述安全措施已到位。