Skip to content

DRBD + Pacemaker NFS HA Cluster 完整復原 Runbook

2-node active/passive HA cluster 的全場景復原手冊:從症狀診斷到指令執行,含 6 大故障 Scenario、日常維護 Checklist 與架構改進建議。

概述

此 HA cluster 以 Corosync + Pacemaker 協調資源排程、DRBD 做同步塊裝置複製、NFS kernel server 提供網路檔案系統,主要服務對象是同網段的 Kubernetes cluster(PV via NFS)。2-node active/passive 架構的設計決策在於簡單可控,但代價是沒有真正的 quorum、需要刻意設定 stonith-enabled=falseno-quorum-policy=ignore,因此任何網路分隔都有 split-brain 潛在風險。

Pacemaker 管理五個相互依賴的資源:nfsserver_clone(systemd NFS server,兩節點皆 Start)、drbd_nfs_promotable(DRBD Promotable Clone,一 Primary 一 Secondary)、fs_work(ext4 on /dev/drbd0)、nfs_ip(虛擬 IP)、nfs_export(exportfs)。後三個組成 nfs-group,被 colocation + ordering constraint 綁在 DRBD Primary 那個節點。

排查邏輯的核心是先收集證據、再對號入座:絕大多數故障可歸入以下 6 種 Scenario,每種都有明確的判定條件與對應操作。

核心內容

健康狀態辨識(Cheat Sheet)

健康時 pcs status 的結構應完全符合以下模式:

* Clone Set: nfsserver_clone [nfsserver]:
    * Started: [ master2.srv.world master3.srv.world ]
* Clone Set: drbd_nfs_promotable [drbd_nfs] (promotable):
    * Promoted:   [ <active-node>.srv.world ]
    * Unpromoted: [ <standby-node>.srv.world ]
* Resource Group: nfs-group:
    * fs_work       Started <active-node>.srv.world
    * nfs_ip        Started <active-node>.srv.world
    * nfs_export    Started <active-node>.srv.world

關鍵不變量

  1. nfs-group 三個資源必須在同一節點(colocation score=5000 保證)
  2. 該節點必須是 DRBD Promoted 節點(colocation + ordering 保證)
  3. 兩節點 DRBD 狀態必須是 UpToDateConnected
  4. 兩節點 nfsserver 都應 Started

DRBD 層驗證:

bash
drbdadm status ha_nfs
# 預期:ha_nfs role:Primary / peer role:Secondary / peer-disk:UpToDate

OS 層驗證:

bash
ip -br addr show | grep 10.248.36.109    # VIP 應在 Promoted 節點
showmount -e 10.248.36.109               # 應列出 /mnt/nfs_share
mount | grep /mnt/nfs_share              # Promoted 節點應看到 /dev/drbd0 已 mount

症狀診斷 Decision Tree

START


執行 `sudo pcs status --full`

  ├── nfsserver_clone 正常、drbd_nfs_promotable Stopped (unmanaged)
  │   └── Scenario A:is-managed=false

  ├── drbd_nfs_promotable 有 Promoted + Unpromoted,但 nfs-group Stopped
  │   └── Scenario B:Group 本身出錯(fs_work / nfs_ip / nfs_export)

  ├── drbd_nfs_promotable 兩邊都 Unpromoted、無人 promote
  │   └── Scenario C:沒有 promotion score

  ├── 某節點 OFFLINE、另一節點 WFConnection 或 StandAlone
  │   └── Scenario D:單邊存活恢復

  ├── Failed Resource Actions 或 failcount 偏高
  │   └── Scenario E:RA 啟動失敗

  └── 兩邊都 Primary / 雙 Master(罕見但嚴重)
      └── Scenario F:真實 Split-Brain

看不出症狀時,先執行下節的證據收集再回頭對應。

證據收集

在 DC 執行(DC 節點看 pcs status 第一行):

bash
# Pacemaker 層
sudo pcs status --full
sudo pcs resource failcount show
sudo pcs config
sudo journalctl -u pacemaker -u corosync \
  --since "2 hours ago" | grep -iE 'error|warn|fail|drbd' | tail -100

# DRBD 層(兩節點都要跑,分開記錄)
sudo drbdadm status all
cat /proc/drbd
lsmod | grep drbd
sudo drbdadm show-gi ha_nfs
sudo dmesg -T | grep -i drbd | tail -60

# OS 層
sudo lsblk
ip -br addr show | grep 10.248.36.109
mount | grep /mnt/nfs_share

判讀 drbdadm show-gi

觀察含義
兩邊 Current UUID 相同完全同步,可直接連接
A 的 Bitmap UUID ≈ B 的 Current UUID(差最低 bit)單向落後,A 較新、B 需 partial resync
兩邊 Current UUID 完全不同且 bitmap 互不相識Split-Brain → Scenario F
flags 含 StandAlone當下未連線到 peer
兩邊 flags 都含 Primary真 split-brain → Scenario F

UUID 最後一 hex 字元最低 bit 是 primary flag:...8F...8E 是「同一 generation、primary 狀態不同」,不是不同 generation。

Scenario A — is-managed=false(最常見)

判定pcs status 顯示 Stopped (unmanaged)pcs config 顯示 is-managed=false

根因:之前維護時手動 unmanage,節點 reboot 後 Pacemaker 不動手、也沒人執行 drbdadm up,DRBD resource 在 kernel 層不存在。

步驟

  1. 確認 DRBD 在 kernel 層的狀態(兩邊都跑):

    bash
    sudo drbdadm status ha_nfs
    • 若回 No such resource → 執行步驟 2
    • 若已是 Connected/UpToDate → 跳到步驟 3
  2. 手動 bring-up DRBD(先較「舊」的那邊,用 show-gi 判斷):

    bash
    # 在 SyncTarget(資料較舊)先做
    sudo drbdadm up ha_nfs
    
    # 在 SyncSource(資料較新)後做
    sudo drbdadm up ha_nfs

    cat /proc/drbd 顯示 oos:0(UpToDate/UpToDate)。

  3. 在 DC 上清除 CIB 狀態並交回管理權:

    bash
    sudo pcs resource cleanup drbd_nfs_promotable
    sudo pcs resource manage drbd_nfs_promotable
  4. 觀察 10 秒內應自動 promote 並連鎖啟動 nfs-group:

    bash
    sudo pcs status --full
    sudo journalctl -u pacemaker --since "2 minutes ago" | tail -60
  5. OS 層驗證(見健康狀態辨識末三行)。

Scenario B — Group 本身出錯(DRBD 正常但 fs/ip/export 起不來)

判定drbd_nfs_promotable 有 Promoted,但 fs_worknfs_ipnfs_export 任一 FAILED / Stopped。

常見根因

  • fs_work 失敗:ext4 髒、mount point 消失、DRBD device 路徑不對
  • nfs_ip 失敗:VIP 衝突、網卡被改名、路由問題
  • nfs_export 失敗:/mnt/nfs_share 沒 mount(依賴 fs_work)、nfs-server daemon 掛掉

步驟

  1. 完整讀 pcs status --fullFailed Resource Actions 區塊,看 exit-reason。
  2. 依資源類型採證:
    bash
    # fs_work
    sudo dmesg -T | tail -80
    sudo fsck -n /dev/drbd0          # -n: read-only check,不要動
    
    # nfs_ip
    ip addr show; ip route
    arping -D -I <iface> 10.248.36.109   # 偵測 IP 衝突
    
    # nfs_export
    sudo systemctl status nfs-server
    sudo exportfs -v
    cat /proc/fs/nfsd/versions
  3. 修好 OS 層後:
    bash
    sudo pcs resource cleanup <failed-resource-name>

Scenario C — 兩邊都 Unpromoted、無人 promote

判定:兩節點都 Unpromoted,無 Failed actions,nfs-group Stopped。

可能原因

  • 兩節點 master-drbd_nfs attribute 缺失(promotion score 不足)
  • crm-fence-peer handler 塞入 location constraint 擋住所有節點

步驟

bash
# 查 promotion score
sudo crm_mon -1f | grep master-drbd

# 確認是否有臨時 location constraint
sudo pcs constraint location show --full

# 若有 drbd-fence-by-handler-ha_nfs 之類的 constraint,移除:
sudo pcs constraint remove drbd-fence-by-handler-ha_nfs

# 刷新狀態
sudo pcs resource refresh drbd_nfs_promotable

Scenario D — 單節點存活,另一節點死掉

判定:另一節點 OFFLINE,本節點 WFConnectionStandAlone

步驟

  1. 確認對方真的無法回來。不確定就停在這裡——2-node 無 STONITH,盲目 force primary 有資料衝突風險。
  2. 若 DRBD 持續 WFConnection 阻礙 promote:
    bash
    sudo drbdadm primary ha_nfs                 # 通常 WFConnection 也能 primary
    # 若被拒且確信對方不會回來(最後手段,記錄時間點):
    sudo drbdadm primary --force ha_nfs
  3. 手動掛 fs + 啟 VIP + export,或讓 Pacemaker 接手。

對方節點回來後:若 DRBD 自動選對 SyncSource 沒事;若變成 split-brain → Scenario F。

Scenario E — RA 啟動失敗(failcount 飆高)

判定pcs status --full 顯示 Failed Resource Actions,或某資源 failcount ≥ migration-threshold

步驟

  1. 先不要 cleanup — 會擦掉 exit-reason 證據。
  2. 完整讀 exit-reasonlast-rc-change 時間。
  3. 對應時間點挖 log:
    bash
    sudo grep -A5 "drbd_nfs.*last-rc-change" /var/log/pacemaker/pacemaker.log
  4. 根據 exit-reason 修 OS 層(參考 Scenario B 的採證方式)。
  5. 確認修好後才執行:
    bash
    sudo pcs resource cleanup <resource-name>

Scenario F — 真實 Split-Brain(雙 Primary)

判定:兩邊 drbdadm show-gi 都是 flags: Primary,且 Current UUID 完全不同。

原則:有一邊的寫入一定會被丟棄。決定勝/負方前不要動手。

決策:比對兩邊 ls -la /mnt/nfs_share、檔案大小、最後修改時間。寫入較多/較重要的那邊是勝方。

在 VICTIM(要被覆蓋的一邊)執行

bash
sudo drbdadm secondary ha_nfs
sudo drbdadm disconnect ha_nfs
sudo drbdadm -- --discard-my-data connect ha_nfs

在 VICTOR(勝方)執行

bash
sudo drbdadm connect ha_nfs

等 resync 完成(cat /proc/drbd 顯示 oos:0)後再交回 Pacemaker。

詳細的 split-brain 修復紀錄與 colocation constraint 修正,見 DRBD Split-Brain 修復

關鍵要點

  • 任何 pcs resource unmanage 操作必須留下文字紀錄/etc/motd 或團隊 log)並設行事曆提醒 re-manage
  • 節點 reboot 前,先確認服務已 failover;如果要 reboot 的是 Primary,先 pcs node standby
  • Split-Brain 的根本原因是 2-node 無 STONITH;只要 stonith-enabled=false,就要接受「真 split-brain 一定要人工介入」
  • Scenario A 的核心:is-managed=false + DRBD 在 kernel 層不存在,兩個問題要分開處理(先 drbdadm up,再 pcs manage)
  • pcs resource cleanup擦掉 failcount 與 exit-reason 證據;懷疑 RA 啟動失敗時先讀完再 cleanup

部署設定參考

環境參數

項目
適用叢集ha_cluster
節點master2.srv.world (10.248.36.249)、master3.srv.world (10.248.36.127)
拓樸2-node active/passive
關鍵元件Corosync + Pacemaker + DRBD 8.4 + NFS kernel server
DRBD resourceha_nfs/dev/drbd0 → ext4 → /mnt/nfs_share
Backing device/dev/ha_vg/ha_lv(LVM on MD RAID1 across nvme1n1 + nvme2n1
虛擬 IP (VIP)10.248.36.109/22
NFS export/mnt/nfs_share to 10.248.36.0/24
主要 client同網段 Kubernetes cluster(PV via NFS)
危險配置stonith-enabled=false, no-quorum-policy=ignore

Pacemaker 資源清單

資源類型正常狀態
nfsserver_clonesystemd:nfs-server (clone)兩台均 Started
drbd_nfs_promotableocf:linbit:drbd (promotable)一 Promoted、一 Unpromoted
fs_workocf💓FilesystemStarted on Promoted 節點
nfs_ipocf💓IPaddr2 (cidr_netmask=22)Started on Promoted 節點
nfs_exportocf💓exportfsStarted on Promoted 節點

關鍵檔案位置

路徑用途
/etc/drbd.d/global_common.confDRBD 全域設定
/etc/drbd.d/ha_nfs.resResource 定義(兩邊要一致)
/etc/corosync/corosync.confCorosync 配置
/var/lib/pacemaker/cib/cib.xmlPacemaker CIB(不要直接手改)
/var/log/pacemaker/pacemaker.logPacemaker 主 log

查狀態指令速查

bash
sudo pcs status --full                  # 完整狀態(含 failed actions)
sudo crm_mon -1rf                       # 等同 pcs status 但較簡潔
sudo pcs resource failcount show        # 失敗次數
sudo pcs config                         # 完整配置(含 is-managed)
sudo pcs constraint show --full         # 只看 constraint
sudo drbdadm status all                 # DRBD 友善輸出
cat /proc/drbd                          # DRBD kernel view
sudo drbdadm show-gi ha_nfs             # Generation Identifiers(判斷新舊)

資源管理指令速查

bash
sudo pcs resource cleanup <resource>    # 清除失敗紀錄(注意會擦證據)
sudo pcs resource refresh <resource>    # 強制重新 probe,不擦 failcount
sudo pcs resource unmanage <resource>   # 暫停 Pacemaker 管理
sudo pcs resource manage <resource>     # 恢復 Pacemaker 管理
sudo pcs resource move <resource> <node>    # 手動移動(較粗暴)
sudo pcs resource clear <resource>      # 移除 move 留下的 location constraint
sudo pcs node standby <node>            # 優雅 failover(讓資源遷移走)
sudo pcs node unstandby <node>          # 讓節點重新加入排程

DRBD 手動操作指令速查

bash
sudo drbdadm up ha_nfs                  # 初始化 + attach + connect
sudo drbdadm down ha_nfs                # 反向操作
sudo drbdadm primary ha_nfs             # 升級為 Primary
sudo drbdadm secondary ha_nfs           # 降級為 Secondary
sudo drbdadm disconnect ha_nfs          # 斷開 peer 連線
sudo drbdadm connect ha_nfs             # 重新連接 peer
sudo drbdadm adjust ha_nfs              # 套用 config 變更,不 down/up
sudo drbdadm verify ha_nfs              # 線上資料校驗

日常維護 Checklist

執行 pcs resource unmanage

  • [ ] 寫下「為什麼要 unmanage」到 /etc/motd 或團隊共用 log
  • [ ] 寫下「預計恢復時間」
  • [ ] 設行事曆提醒自己 re-manage
  • [ ] 通知 K8s 那邊(NFS PV 用戶)

節點 reboot 前

  • [ ] 確認另一節點是 Primary、服務已 failover:sudo pcs status --full
  • [ ] 若要 reboot 的是 Primary,先主動 demote:
    bash
    sudo pcs node standby <this-node>.srv.world
    # 等 service 遷移完後再確認
    sudo pcs status --full
  • [ ] reboot 完後:
    bash
    sudo pcs node unstandby <this-node>.srv.world
    sudo drbdadm status ha_nfs    # 確認 Connected + UpToDate

任何維護結束後驗收

  • [ ] pcs status --full 符合健康狀態 Cheat Sheet
  • [ ] drbdadm status ha_nfs 兩節點都 UpToDateConnected
  • [ ] showmount -e 10.248.36.109 有回應
  • [ ] kubectl get pv(K8s 那邊)NFS PV 無 error

季度檢查

  • [ ] Config drift:diff <(ssh master2 cat /etc/drbd.d/ha_nfs.res) /etc/drbd.d/ha_nfs.res
  • [ ] 計畫性 failover 演練(standby 一邊、確認服務順利遷移)
  • [ ] 檢查 /var/log/pacemaker/pacemaker.log 有無累積可疑 warning

架構改進建議(Tech Debt)

優先級項目建議方案
無 STONITH有 IPMI/iDRAC → fence_ipmilan;VM → hypervisor fencing;無硬體 → SBD (Storage-Based Death)
Config Drift 無治理Ansible/Puppet 管 /etc/drbd.d/ha_nfs.res,或加 cron 每日 diff + alert
無監控告警Prometheus node_exporter(pacemaker_drbd_ metrics)監控:pcs status exit code、DRBD module、VIP pingable、showmount 回應
DRBD 8.4 → 9.xDRBD 9 對 multi-node、auto-recovery 支援更強,下次大維護窗評估

相關概念

來源