已解决:Pacemaker/DRBD:自动回退导致活动 DRBD 同步从主到备失效。如何防止?

发布: (2025年12月28日 GMT+8 07:09)
14 分钟阅读
原文: Dev.to

Source: Dev.to

请提供您希望翻译的完整文本内容(除代码块和 URL 之外),我将按照要求将其翻译为简体中文并保留原有的 Markdown 格式。谢谢!

执行摘要

TL;DR: Pacemaker 默认的自动回退行为可能会在恢复中的节点上尝试过早提升,从而干扰正在运行的 DRBD 主节点,导致服务中断并可能产生数据风险。可以通过以下方式防止此问题:

  • 在 DRBD 主/从克隆资源上配置 负资源粘性(例如 -10000)。
  • 实施 手动回退(待机模式或位置约束)。
  • 设置 平滑、延迟的提升,配合可靠的 STONITH、增加 cluster-delay,以及更宽松的 promoted-stop-timeout 值。

为什么会发生

Pacemaker/DRBD 集群提供高可用性,但默认行为往往会在首选节点恢复后立即尝试将资源“回退”到该节点。在 DRBD 环境中,这可能是灾难性的:

症状描述
服务中断活跃的 DRBD 主节点上的应用程序停止或变得无响应。
DRBD 状态变化主节点切换为 SecondaryUnknown,或显示冲突状态(例如 WFConnectionStandAlone)。
Pacemaker 日志条目日志显示在恢复节点上的提升尝试,以及在当前主节点上的降级或隔离操作。查找 drbd_promotedrbd_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:

核心问题

  1. 资源本地性偏好 – Pacemaker 更倾向于将资源保留在它们的“首选”节点上。当节点恢复时,Pacemaker 会再次将其视为合适的候选节点。
  2. DRBD 主节点要求 – 在两节点同步(Protocol C)DRBD 配置中,任意时刻只能有 一个 节点处于 Primary(主)状态。
  3. 过早的提升尝试 – Pacemaker 可能会在恢复节点 立即 尝试提升 DRBD 资源,而此时当前的主节点尚未安全降级。
  4. 导致的冲突 – 这可能会产生:
    • 提升失败(如果资源代理检测到另一个主节点)。
    • 竞争条件,使两个节点短暂地都认为自己应该是主节点。
    • 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
  1. 设置宽裕的 promoted-stop-timeout – 允许旧的主节点干净地完成降级。

    pcs resource update drbd_res meta promoted-stop-timeout=120s
  2. 可选:migration-threshold – 防止资源快速来回迁移。

    pcs resource defaults migration-threshold=3

安全的 DRBD‑Pacemaker 集群检查清单

  • STONITH 已在所有节点上配置并测试
  • 已对 DRBD 资源应用负粘性(或等效的位置约束)
  • 已根据工作负载调优 Cluster‑delaypromoted‑stop‑timeout 参数
  • 已设置监控(例如 pcs statusdrbd-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-timeoutPacemaker 在 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. 可选:为首选节点设置资源粘性

如果希望 优雅的自动回退 到首选节点,可以添加适度的正向粘性或位置规则,但务必确保上述安全措施已到位。

Back to Blog

相关文章

阅读更多 »