Appearance
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=false 與 no-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關鍵不變量:
nfs-group三個資源必須在同一節點(colocation score=5000 保證)- 該節點必須是 DRBD Promoted 節點(colocation + ordering 保證)
- 兩節點 DRBD 狀態必須是
UpToDate、Connected - 兩節點
nfsserver都應 Started
DRBD 層驗證:
bash
drbdadm status ha_nfs
# 預期:ha_nfs role:Primary / peer role:Secondary / peer-disk:UpToDateOS 層驗證:
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 層不存在。
步驟:
確認 DRBD 在 kernel 層的狀態(兩邊都跑):
bashsudo drbdadm status ha_nfs- 若回
No such resource→ 執行步驟 2 - 若已是
Connected/UpToDate→ 跳到步驟 3
- 若回
手動 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)。在 DC 上清除 CIB 狀態並交回管理權:
bashsudo pcs resource cleanup drbd_nfs_promotable sudo pcs resource manage drbd_nfs_promotable觀察 10 秒內應自動 promote 並連鎖啟動 nfs-group:
bashsudo pcs status --full sudo journalctl -u pacemaker --since "2 minutes ago" | tail -60OS 層驗證(見健康狀態辨識末三行)。
Scenario B — Group 本身出錯(DRBD 正常但 fs/ip/export 起不來)
判定:drbd_nfs_promotable 有 Promoted,但 fs_work、nfs_ip、nfs_export 任一 FAILED / Stopped。
常見根因:
fs_work失敗:ext4 髒、mount point 消失、DRBD device 路徑不對nfs_ip失敗:VIP 衝突、網卡被改名、路由問題nfs_export失敗:/mnt/nfs_share沒 mount(依賴 fs_work)、nfs-server daemon 掛掉
步驟:
- 完整讀
pcs status --full的Failed Resource Actions區塊,看 exit-reason。 - 依資源類型採證: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 - 修好 OS 層後:bash
sudo pcs resource cleanup <failed-resource-name>
Scenario C — 兩邊都 Unpromoted、無人 promote
判定:兩節點都 Unpromoted,無 Failed actions,nfs-group Stopped。
可能原因:
- 兩節點
master-drbd_nfsattribute 缺失(promotion score 不足) crm-fence-peerhandler 塞入 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_promotableScenario D — 單節點存活,另一節點死掉
判定:另一節點 OFFLINE,本節點 WFConnection 或 StandAlone。
步驟:
- 確認對方真的無法回來。不確定就停在這裡——2-node 無 STONITH,盲目 force primary 有資料衝突風險。
- 若 DRBD 持續
WFConnection阻礙 promote:bashsudo drbdadm primary ha_nfs # 通常 WFConnection 也能 primary # 若被拒且確信對方不會回來(最後手段,記錄時間點): sudo drbdadm primary --force ha_nfs - 手動掛 fs + 啟 VIP + export,或讓 Pacemaker 接手。
對方節點回來後:若 DRBD 自動選對 SyncSource 沒事;若變成 split-brain → Scenario F。
Scenario E — RA 啟動失敗(failcount 飆高)
判定:pcs status --full 顯示 Failed Resource Actions,或某資源 failcount ≥ migration-threshold。
步驟:
- 先不要 cleanup — 會擦掉 exit-reason 證據。
- 完整讀
exit-reason和last-rc-change時間。 - 對應時間點挖 log:bash
sudo grep -A5 "drbd_nfs.*last-rc-change" /var/log/pacemaker/pacemaker.log - 根據 exit-reason 修 OS 層(參考 Scenario B 的採證方式)。
- 確認修好後才執行: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 resource | ha_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_clone | systemd:nfs-server (clone) | 兩台均 Started |
| drbd_nfs_promotable | ocf:linbit:drbd (promotable) | 一 Promoted、一 Unpromoted |
| fs_work | ocf💓Filesystem | Started on Promoted 節點 |
| nfs_ip | ocf💓IPaddr2 (cidr_netmask=22) | Started on Promoted 節點 |
| nfs_export | ocf💓exportfs | Started on Promoted 節點 |
關鍵檔案位置
| 路徑 | 用途 |
|---|---|
/etc/drbd.d/global_common.conf | DRBD 全域設定 |
/etc/drbd.d/ha_nfs.res | Resource 定義(兩邊要一致) |
/etc/corosync/corosync.conf | Corosync 配置 |
/var/lib/pacemaker/cib/cib.xml | Pacemaker CIB(不要直接手改) |
/var/log/pacemaker/pacemaker.log | Pacemaker 主 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兩節點都UpToDate、Connected - [ ]
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.x | DRBD 9 對 multi-node、auto-recovery 支援更強,下次大維護窗評估 |
相關概念
- DRBD Split-Brain 修復(Pacemaker HA Cluster) — 歷史事件紀錄:split-brain 診斷、
--discard-my-data修復、colocation constraint 降 score、nfs_ip cidr_netmask 修正 - NFS Client Mount 疑難排解與最佳實踐 — NFS client 端問題:mount 驗證四維度、fstab 選項詳解、umount/remount 正確流程
- Kubernetes 維運技巧速查 — NFS Provisioner 在 K8s 中的使用,與本叢集的 PV 整合點