熱門分類
載入中…
目錄0%

💾 Proxmox + NFS 共享儲存做 HA:Node Affinity 排除投票節點、故障切換實測

    🖧 Proxmox VE 3-Node 叢集從零建置:HA 實戰、腦裂防護與故障切換全紀錄 | wwfandy
    HA Cluster Proxmox Quorum Failover Corosync NFS

    wwfandy  ·  2026 年 3 月 1 日  ·  閱讀時間約 15 分鐘

    本文完整記錄一次從單機 Proxmox VE 擴展為 三節點高可用叢集(3-Node HA Cluster) 的實戰歷程, 包含所有你可能遇到的坑:主機改名、DHCP 轉固定 IP、網卡橋接失效、pmxcfs 鎖死、 憑證不同步(SSL 596)、腦裂(Split-brain)預防,以及最終的 Failover 實測 130 秒切換成功

    🗺️ 一、環境概覽與目標架構

    節點IP 位址角色
    pve-1192.168.1.11主運算節點(原名:pve)
    pve-2192.168.1.12備援節點
    pve-3192.168.1.13投票節點(1 CPU 低資源,原名:pve)
    TrueNAS192.168.1.111NFS 儲存伺服器(ISO & Backup)

    設計目標:

    • 三台 PVE 組成叢集,總票數 3 票
    • pve-3 作為純投票員(Quorum Voter),承載任何 VM
    • VM 100(Ubuntu 22.04)只在 pve-1 / pve-2 之間自動切換
    • TrueNAS 提供 NFS 共享儲存,讓 VM 硬碟跨節點可見
    💡 為何要奇數節點?
    Quorum = 總票數一半以上。兩節點時,任一台掛掉剩 1/2 票不足,整個叢集鎖死。 加入 pve-3 後,即使 pve-2 關機,pve-1 + pve-3 仍有 2/3 票,系統繼續正常運作。

    🔧 二、主機改名與固定 IP

    2.1 為何要改主機名稱?

    Proxmox 叢集用主機名稱做節點識別符。預設安裝後名稱為 pve,若多台同名就會衝突、憑證錯誤、SSH 互信失敗。

    ⚠️ 改名前請確保沒有執行中的 VM / CT,且此節點尚未加入叢集。

    2.2 一鍵改名腳本(pve → pve-1)

    # 修改 hostname
    sed -i 's/pve/pve-1/g' /etc/hostname
    
    # 修改 /etc/hosts(最關鍵)
    sed -i 's/pve/pve-1/g' /etc/hosts
    
    # 重啟後遷移 VM 設定目錄
    reboot
    # 重啟後執行:
    cp -a /etc/pve/nodes/pve/* /etc/pve/nodes/pve-1/
    
    # 更新 SSL 憑證
    pvecm updatecerts -f

    2.3 DHCP 轉固定 IP(以 pve-1 為例)

    DHCP 會讓節點每次重啟 IP 可能改變,導致 corosync.conf 紀錄的 IP 失效,叢集通訊斷開。

    cat <<EOF > /etc/network/interfaces
    auto lo
    iface lo inet loopback
    
    iface nic0 inet manual
    
    auto vmbr0
    iface vmbr0 inet static
            address 192.168.1.11/24
            gateway 192.168.1.1
            bridge-ports nic0
            bridge-stp off
            bridge-fd 0
    EOF
    
    systemctl restart networking && ifreload -a

    接著同步 /etc/hosts

    # pve-1
    sed -i '/pve-1/d' /etc/hosts
    echo '192.168.1.11 pve-1.proxmox.com pve-1' >> /etc/hosts
    
    # pve-2
    sed -i '/pve-2/d' /etc/hosts
    echo '192.168.1.12 pve-2.proxmox.com pve-2' >> /etc/hosts
    💡 IP 改完後,corosync.conf 裡的舊 IP 也要一起更新,並將 config_version 加 1,否則叢集認不出自己。

    🏗️ 三、組建 3-Node 叢集

    3.1 建立叢集(在 pve-1 執行)

    pvecm create MyCluster

    3.2 其他節點加入

    # 在 pve-2 / pve-3 分別執行
    pvecm add 192.168.1.11
    # 輸入 yes 確認 SSH 連線,再輸入 pve-1 的 root 密碼

    3.3 pve-3 加入前的清理(避免舊叢集殘留)

    systemctl stop pve-cluster corosync
    killall -9 pmxcfs 2>/dev/null
    rm -f /etc/pve/corosync.conf
    rm -rf /etc/corosync/*
    systemctl start pve-cluster
    
    # 確認乾淨後加入
    pvecm add 192.168.1.11

    3.4 確認叢集狀態

    pvecm status
    
    # 預期輸出重點:
    # Quorate: Yes
    # Total votes: 3
    # Nodes: 3

    3.5 套件庫修正(401 Unauthorized 處理)

    rm -rf /etc/apt/sources.list.d/*
    
    echo 'deb http://download.proxmox.com/debian/pve trixie pve-no-subscription' \
      > /etc/apt/sources.list.d/pve-no-sub.list
    
    echo 'deb http://download.proxmox.com/debian/ceph-squid trixie no-subscription' \
      > /etc/apt/sources.list.d/ceph-no-sub.list
    
    # 補回 Debian 基礎套件庫
    cat <<EOF > /etc/apt/sources.list
    deb http://deb.debian.org/debian trixie main contrib non-free-remote-annex
    deb http://deb.debian.org/debian trixie-updates main contrib non-free-remote-annex
    deb http://security.debian.org/debian-security trixie-security main contrib
    EOF
    
    apt update && apt install vim -y

    🔒 四、雞生蛋問題:叢集鎖死與憑證同步

    這是整個過程最棘手的部分。三個症狀往往同時出現、互為因果:

    症狀根本原因
    Write error (file system full?)/etc/pve 被 pmxcfs 鎖定為唯讀
    Cannot initialize CMAP servicecorosync 服務完全崩潰,pvecm 指令無法使用
    SSL certificate verify failed (596)IP 變更後,舊憑證與新 IP 不匹配
    no quorum!節點失聯票數不足,拒絕任何寫入操作

    4.1 解鎖流程:pmxcfs 本地模式

    # 停止所有衝突服務
    systemctl stop pve-ha-lrm pve-ha-crm corosync pve-cluster
    killall -9 pmxcfs
    
    # 以本地模式掛載(繞過 Quorum 檢查,恢復可寫)
    pmxcfs -l
    
    # 修改 corosync.conf(IP 與版本號)
    vim /etc/pve/corosync.conf
    # 按 :wq! 強制儲存
    
    # 恢復正常模式
    killall -9 pmxcfs
    systemctl start pve-cluster corosync
    pvecm updatecerts -f
    ⚠️ pmxcfs -l 會佔用前台。若顯示「unable to acquire pmxcfs lock」,先執行 killall -9 pmxcfs 清除殘留程序再試。

    4.2 一鍵救援腳本

    cat << 'EOF' > /tmp/pve_rescue.sh
    #!/bin/bash
    systemctl stop pve-ha-lrm pve-ha-crm corosync pve-cluster 2>/dev/null
    killall -9 pmxcfs 2>/dev/null
    pmxcfs -l
    sleep 2
    
    # 修正 corosync IP(依實際情況修改)
    sed -i 's/192.168.1.107/192.168.1.11/g' /etc/pve/corosync.conf
    sed -i 's/192.168.1.130/192.168.1.12/g' /etc/pve/corosync.conf
    sed -i 's/config_version: .*/config_version: 10/' /etc/pve/corosync.conf
    
    # 修正 NFS 儲存 IP
    sed -i 's/server .*/server 192.168.1.111/' /etc/pve/storage.cfg
    
    # 清除 HA 錯誤鎖定
    rm -f /etc/pve/ha/resources.cfg
    
    killall -9 pmxcfs
    systemctl start pve-cluster
    sleep 2
    systemctl start corosync
    pvecm updatecerts -f
    EOF
    
    chmod +x /tmp/pve_rescue.sh
    /tmp/pve_rescue.sh

    🌉 五、網路橋接 vmbr0 故障排除

    5.1 症狀

    no physical interface on bridge 'vmbr0'
    network script /usr/libexec/qemu-server/pve-bridge failed with status 6400
    TASK ERROR: start failed: QEMU exited with code 1

    代表 vmbr0 沒有綁定實體網卡,VM 無法取得網路出口。

    5.2 診斷

    ip link show
    # 確認 nic0(或 enp... )狀態為 UP,且 vmbr0 有顯示 master 關聯

    5.3 永久修復

    cat <<NET_EOF > /etc/network/interfaces
    auto lo
    iface lo inet loopback
    
    iface nic0 inet manual
    
    auto vmbr0
    iface vmbr0 inet static
            address 192.168.1.11/24
            gateway 192.168.1.1
            bridge-ports nic0
            bridge-stp off
            bridge-fd 0
    NET_EOF
    
    ifreload -a
    ⚠️ 每個節點的 vmbr0 必須使用相同的橋接結構,否則 VM 遷移後會失去網路連線。

    💿 六、NFS 儲存整合(TrueNAS / OMV)

    6.1 在儲存伺服器設定 NFS Export

    showmount -e <IP> 顯示 No file systems exported!,需手動加入匯出規則:

    cp /etc/exports /etc/exports.bak
    
    echo '/srv/dev-disk-by-uuid-.../ISO 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)' \
      >> /etc/exports
    
    exportfs -arv
    showmount -e localhost
    💡 no_root_squash 對 PVE 至關重要:PVE 預設以 root 存取 NFS,若缺少此選項會因權限被拒而無法備份。

    6.2 在 PVE 加入 NFS 儲存

    Datacenter → Storage → Add → NFS,填入以下資訊:

    欄位填入值
    IDISO(任意名稱)
    Server192.168.1.111
    Export下拉選單自動偵測路徑
    ContentISO image, VZDump backup, Disk image

    6.3 診斷指令

    showmount -e 192.168.1.111   # 測試 NFS 伺服器是否有開門
    pvesm status                  # 掛載狀態
    pvesm set ISO --disable 0     # 強制啟用儲存
    mount -a                      # 重新掛載

    ⚙️ 七、HA 設定與 Node Affinity 規則

    7.1 HA 核心元件

    元件功能
    CRM(叢集資源管理器)跨節點協調,決定 VM 要在哪台跑
    LRM(本地資源管理器)在本機執行開機、關機、遷移
    Master由 CRM 動態選出的指揮節點

    7.2 加入 HA 資源

    Datacenter → HA → Resources → Add,選擇 vm:100,設定 Max. Restart 與 Max. Relocate。

    7.3 設定 Node Affinity(排除 pve-3)

    新版 Proxmox 已將 Groups 整合至 Rules。透過 Node Affinity 規則排除特定節點:
    Datacenter → HA → Affinity Rules → Add → Node Affinity

    欄位設定
    HA Resourcesvm:100
    Nodespve-1, pve-2(不選 pve-3
    ⚠️ Resource Affinity 是用於「兩台 VM 之間的聚集 / 分離規則」。只有一台 VM 時設定此項會報 400 錯誤,請勿混淆。

    7.4 修復 LRM「Dead」狀態

    若 HA Status 顯示 old timestamp - dead?,重啟 HA 服務:

    systemctl restart pve-ha-lrm pve-ha-crm

    🧠 八、腦裂(Split-brain)預防機制

    8.1 什麼是腦裂?

    叢集因網路中斷分裂成兩組,各自以為對方死掉。若兩組同時對同一份硬碟寫入, 會導致 嚴重的資料損毀(Data Corruption)

    8.2 Proxmox 的防護機制

    • 只有票數超過總票數一半的那一組才能繼續運作
    • 票數不足的那一組自動進入唯讀鎖定(無法啟動 VM)
    • Watchdog 機制:LRM 10 秒內未重置看門狗,系統強制重啟節點

    8.3 2-Node vs 3-Node 差異

    情境2-Node 叢集3-Node 叢集
    1 台關機剩 1/2 票 → ❌ 鎖死剩 2/3 票 → ✅ 正常運作
    需手動解鎖是(pvecm expected 1否,自動維持 Quorum
    容錯能力0 台(任何故障都鎖死)1 台
    💡 pve-3 投票節點的設計邏輯: 讓資源有限的 pve-3 保持開機提供第三票;透過 Node Affinity 讓 VM 絕不跑在 pve-3; pve-3 僅消耗極少量資源(corosync 服務),不影響整體效能。

    🔥 九、Failover 實測紀錄

    9.1 初始狀態

    項目狀態
    VM 100pve-2 上運行,Ubuntu 22.04 Server
    pve-1active,待命中
    pve-2active,承載 VM 100
    pve-3active,純投票(Master 由 pve-3 擔任)
    QuorumOK(3/3 票)

    9.2 切換時序分析

    時間(秒)事件
    T+0pve-2 電源關閉
    T+10pve-2 的 Watchdog 逾時,系統確認節點無回應
    T+60Master(pve-3)判定 pve-2 逾時(dead?
    T+65pve-1 取得 VM 100 的資源鎖定
    T+75~140VM 100 在 pve-1 冷啟動完成,服務恢復

    9.3 實測觀察到的 ha-manager status 輸出

    # 關機後約 60 秒
    quorum OK
    master pve-3 (active, Sun Mar 1 15:59:14 2026)
    lrm pve-1 (active, Sun Mar 1 15:59:22 2026)
    lrm pve-2 (old timestamp - dead?, Sun Mar 1 15:56:58 2026)
    lrm pve-3 (idle, Sun Mar 1 15:59:24 2026)
    service vm:100 (pve-1, starting)
    
    # 約 140 秒後
    service vm:100 (pve-1, started)

    9.4 實測結論

    指標實測結果
    故障偵測時間約 60 秒
    VM 啟動時間約 60~80 秒(含 Ubuntu 開機)
    總切換時間約 130~140 秒(約 2 分 20 秒)
    資料一致性正常(NFS 共享儲存無需複製)
    Node Affinity 有效性VM 未跑到 pve-3 ✅

    9.5 Failback(歸位)流程

    1. 將 pve-2 重新開機
    2. pve-2 加回叢集,恢復綠燈
    3. 系統自動執行 Live Migration,將 VM 100 從 pve-1 搬回 pve-2
    4. 遷移過程不關機(Online Migration),服務不中斷
    💡 Live Migration 實測:2 GB 記憶體狀態傳輸 22 秒完成,Downtime 僅 183 ms,VM 完全不斷服務。

    📋 十、完整指令速查表

    叢集管理

    pvecm status                          # 查看叢集狀態與 Quorum
    pvecm expected 1                      # 強制以 1 票維持 Quorum(2-Node 緊急解鎖)
    pvecm updatecerts -f                  # 強制更新全叢集 SSL 憑證
    pvecm add 192.168.1.11                # 加入叢集

    HA 管理

    ha-manager status                     # 查看 HA 詳細狀態
    ha-manager set vm:100 --state disabled # 停用 VM 的 HA 管理
    ha-manager remove vm:100              # 移除 VM 的 HA 管理
    systemctl restart pve-ha-lrm pve-ha-crm # 重啟 HA 服務

    VM 管理

    qm start 100                          # 啟動 VM
    qm unlock 100                         # 解除 VM 鎖定
    qm set 100 --memory 2048              # 設定記憶體(Ubuntu 至少需 2048)
    qm migrate 100 pve-2 --online         # 線上熱遷移

    網路管理

    ip link show                          # 查看網卡狀態
    ip link set nic0 up                   # 啟用網卡
    brctl addif vmbr0 nic0               # 臨時加入橋接
    ifreload -a                          # 套用網路設定

    服務重啟參考

    # 叢集通訊
    systemctl restart corosync pve-cluster
    
    # Web UI 管理介面
    systemctl restart pveproxy pvedaemon pvestatd
    
    # HA 服務
    systemctl restart pve-ha-lrm pve-ha-crm

    💬 留言交流
    如果你在實作過程遇到卡點(版本、環境、錯誤訊息),歡迎留言討論:
    • 你的環境版本(PVE / Kernel / 節點數)
    • 你做了哪些步驟
    • 錯誤訊息或現象(附上關鍵 log)

    標籤: Proxmox · HA · Cluster · Quorum · Corosync · NFS

    🔗 分享這篇 LINE Facebook X

    沒有留言:

    字級