本文完整記錄一次從單機 Proxmox VE 擴展為 三節點高可用叢集(3-Node HA Cluster) 的實戰歷程,
包含所有你可能遇到的坑:主機改名、DHCP 轉固定 IP、網卡橋接失效、pmxcfs 鎖死、
憑證不同步(SSL 596)、腦裂(Split-brain)預防,以及最終的 Failover 實測 130 秒切換成功。
🗺️ 一、環境概覽與目標架構
| 節點 | IP 位址 | 角色 |
|---|---|---|
| pve-1 | 192.168.1.11 | 主運算節點(原名:pve) |
| pve-2 | 192.168.1.12 | 備援節點 |
| pve-3 | 192.168.1.13 | 投票節點(1 CPU 低資源,原名:pve) |
| TrueNAS | 192.168.1.111 | NFS 儲存伺服器(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 互信失敗。
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
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 service | corosync 服務完全崩潰,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,填入以下資訊:
| 欄位 | 填入值 |
|---|---|
| ID | ISO(任意名稱) |
| Server | 192.168.1.111 |
| Export | 下拉選單自動偵測路徑 |
| Content | ISO 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 Resources | vm:100 |
| Nodes | pve-1, pve-2(不選 pve-3) |
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 台 |
🔥 九、Failover 實測紀錄
9.1 初始狀態
| 項目 | 狀態 |
|---|---|
| VM 100 | pve-2 上運行,Ubuntu 22.04 Server |
| pve-1 | active,待命中 |
| pve-2 | active,承載 VM 100 |
| pve-3 | active,純投票(Master 由 pve-3 擔任) |
| Quorum | OK(3/3 票) |
9.2 切換時序分析
| 時間(秒) | 事件 |
|---|---|
| T+0 | pve-2 電源關閉 |
| T+10 | pve-2 的 Watchdog 逾時,系統確認節點無回應 |
| T+60 | Master(pve-3)判定 pve-2 逾時(dead?) |
| T+65 | pve-1 取得 VM 100 的資源鎖定 |
| T+75~140 | VM 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(歸位)流程
- 將 pve-2 重新開機
- pve-2 加回叢集,恢復綠燈
- 系統自動執行 Live Migration,將 VM 100 從 pve-1 搬回 pve-2
- 遷移過程不關機(Online Migration),服務不中斷
📋 十、完整指令速查表
叢集管理
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)