Proxmox:VM migrate 後「所有 VM Console 失效 / Failed to run vncproxy」完整診斷與修復紀錄(node1)

本文完整記錄「如何一步步定位問題」與「如何修復」,而不是只留下最後的解法。

環境與前提

叢集與 NAS2 之間有一條 10G 內網(172.16.0.0/24):

  • node1:172.16.0.20
  • node2:172.16.0.21
  • NAS2(Synology):172.16.0.10

另外 NAS2 也提供另一個可達的服務 IP:

  • NAS2 服務 IP:192.168.10.132

0. 現象(Symptoms)

  • VM 從 node2 migrate 到 node1 後:
    • 所有 VM 的 Console 都打不開
    • Web UI 顯示:failed to run vnc proxy
  • 但 node1 的 Node → Shell(左上角 node 的 shell)仍然能正常開啟
  • 手動在 node1 執行 qm vncproxy <vmid> 時出現:
    • LC_PVE_TICKET not set, VNC proxy without password is forbidden

說明:qm vncproxy 本來就需要 PVE ticket(通常由 Web UI / API 帶入),因此單獨在 shell 直接執行會看到此訊息;這個訊息本身不是根因。


1. 先確認 Web / PVE 核心服務是否正常

1.1 PVE 服務狀態

systemctl status pveproxy pvedaemon pve-cluster --no-pager

觀察重點:

  • pveproxypvedaemonpve-cluster (pmxcfs) 都是 active
  • pveproxy log 常見 proxy detected vanished client connection(console 連線失敗時很容易看到)

1.2 Cluster / quorum 狀態

pvecm status

觀察重點:

  • node1 顯示 Quorate: Yes,代表 pve-cluster 正常運作
  • 即使成員看起來只剩 node1 + qdevice,仍不構成 console 全滅的直接原因

2. 轉向 Console 相關:termproxy / vncproxy 是否有啟動與監聽?

2.1 檢查 5900/5901 等連線埠與相關程序

ss -ltnp | egrep ':(59[0-9]{2})\b'
ps aux | egrep 'termproxy|vncproxy' | grep -v grep

觀察:

  • 可以看到 termproxy 5900 --path /nodes/node1 --perm Sys.Console ...
  • 但 VM console 仍失敗,代表問題不只是「proxy 沒起來」

3. 從日誌抓到真正原因:vncproxy 為何失敗?

3.1 近 10 分鐘 pvedaemon / pveproxy log

journalctl -u pvedaemon -u pveproxy --since "10 min ago" -l --no-pager | tail -200

關鍵訊息:

  • 大量 VM 出現:
    • VM XXX qmp command failed ... unable to connect to VM XXX qmp socket - timeout after 51 retries
  • 在嘗試開 VM console 時會出現:
    • starting vnc proxy ...
    • qmp command 'set_password' failed ... unable to connect to VM XXX qmp socket ...
    • Failed to run vncproxy.

第一層結論:

  • console 不是「proxy 不能跑」,而是 Proxmox 需要透過 QMP 跟 QEMU 溝通(設定 VNC 密碼/權限)時,連不到該 VM 的 QMP socket
  • 因此要往「VM 的 qemu/QMP 實際狀態」追

4. 驗證 VM 狀態:顯示 running 但 QMP 連不上(矛盾點)

以 VM 502 為例。

4.1 檢查 VM 狀態與 socket 檔案是否存在

qm status 502
ls -l /run/qemu-server/502.qmp /run/qemu-server/502.vnc 2>/dev/null || true

現象:

  • qm status 顯示 running
  • /run/qemu-server/502.qmp502.vnc 也都存在

4.2 進入 monitor 後仍然 QMP timeout

由於此版本 qm monitor 沒有支援 --cmd / --command,改用互動模式:

qm monitor 502
# qm> info status

結果:

  • human-monitor-command 仍然因 QMP socket timeout 而失敗

4.3 檢查 qemu process 是否真的存在

pgrep -af "qemu.*-id 502" || ps -ef | grep -E "qemu.*-id 502" | grep -v grep

現象:

  • 找不到對應的 qemu process
  • 但 Proxmox 又顯示 VM running,且 socket file 存在

第二層結論:

  • 這是一種典型的「狀態殘留 / I/O 卡住 / 管理層與實際執行層不同步」徵兆
  • 下一步應該從 storage / NFS / I/O 角度找異常

5. 另外一個明顯徵兆:node1 的某個共用 NFS storage 變成灰色問號(inactive)

當時的直覺觀察:

  • nas2-pxshare 在 node2 正常顯示容量
  • 但在 node1 顯示灰色問號

5.1 用 CLI 確認 storage 狀態

timeout 5 pvesm status || echo "pvesm status timeout"

結果:

  • nas2-pxshare 顯示 inactive,Total/Used/Avail 全是 0

5.2 檢查 storage.cfg

grep -n "nas2-pxshare" -A6 -B2 /etc/pve/storage.cfg

重點:

  • export /volume1/PxShare
  • path /mnt/pve/nas2-pxshare
  • server 預期應該是 172.16.0.10(10G 內網)

5.3 先排除網路與 NAS NFS 服務問題

ping -c 2 172.16.0.10
ip route get 172.16.0.10
rpcinfo -p 172.16.0.10 | head -30
showmount -e 172.16.0.10

觀察:

  • ping 正常且延遲極低
  • route 走 vmbr1、src 是 172.16.0.20
  • rpcinfo / showmount 正常列出 exports
  • export ACL 也包含 172.16.0.20172.16.0.21

第三層結論:

  • 網路與 NAS NFS 服務正常
  • 問題更像是「node1 端掛載狀態/來源不一致」導致 Proxmox 誤判 inactive

6. 真正關鍵:實際掛載來源與 storage.cfg 不一致,甚至出現同一路徑疊掛

6.1 先看 mountpoint 實際來源

findmnt /mnt/pve/nas2-pxshare || echo "NOT MOUNTED"
cat /proc/self/mountinfo | grep "/mnt/pve/nas2-pxshare"

早期觀察到:

  • findmnt 的 SOURCE 顯示成:
    • 192.168.10.132:/volume1/PxShare
  • 但 storage.cfg 的 server 則是(或期望是):
    • 172.16.0.10

補充背景(事後檢討):

  • 先前 nas2-pxshare 很可能是以 192.168.10.132 建立
  • 後來刪除後重新建立同名 nas2-pxshare,改指向 172.16.0.10
  • node2 沒出現異常,但 node1 仍保留舊的掛載狀態,導致「名稱相同但掛載來源不一致」的殘留情形

這種狀況很容易讓 Proxmox 在判定 storage 狀態時出現不一致,進而把 storage 判成 inactive。

6.2 更明顯的證據:同一個 mountpoint 同時存在兩層掛載

在修復過程中,停掉 PVE service 後檢查:

findmnt /mnt/pve/nas2-pxshare -o TARGET,SOURCE,FSTYPE,OPTIONS

竟然同一路徑出現兩行:

  • /mnt/pve/nas2-pxshare 192.168.10.132:/volume1/PxShare nfs4 ...
  • /mnt/pve/nas2-pxshare 172.16.0.10:/volume1/PxShare nfs ...

代表同一路徑疊掛(stacked mount):

  • 底層是 NFSv4(顯示 192.168.10.132)
  • 上層是 NFSv3(顯示 172.16.0.10)

確認沒有使用者程序佔用(只有 kernel mount):

fuser -vm /mnt/pve/nas2-pxshare

7. 最終修復(不建立新路徑):完整卸掉疊掛,重新只掛單一來源的 NFSv3

目標:

  • 保持 /mnt/pve/nas2-pxshare 不變
  • 移除疊掛狀態(可能需要卸載多次)
  • 重新以 172.16.0.10 的 NFSv3 掛回來
  • 讓 Proxmox 重新判定 storage 為 active

7.1 先停掉會干擾 storage 檢查/重掛的 PVE 服務

systemctl stop pvestatd pvedaemon pveproxy

7.2 逐層卸載,直到完全 NOT MOUNTED

由於是疊掛,可能要卸兩次(或多次),直到 mountpoint 真的消失:

umount -f /mnt/pve/nas2-pxshare 2>/dev/null || umount -l /mnt/pve/nas2-pxshare
findmnt /mnt/pve/nas2-pxshare -o TARGET,SOURCE,FSTYPE,OPTIONS || echo "NOT MOUNTED"

umount -f /mnt/pve/nas2-pxshare 2>/dev/null || umount -l /mnt/pve/nas2-pxshare
findmnt /mnt/pve/nas2-pxshare -o TARGET,SOURCE,FSTYPE,OPTIONS || echo "NOT MOUNTED"

確認輸出為:

NOT MOUNTED

7.3 重新掛載為 NFSv3(同一路徑)

mount -v -t nfs -o vers=3,proto=tcp 172.16.0.10:/volume1/PxShare /mnt/pve/nas2-pxshare
findmnt /mnt/pve/nas2-pxshare -o TARGET,SOURCE,FSTYPE,OPTIONS

確認只剩一行,來源為:

/mnt/pve/nas2-pxshare 172.16.0.10:/volume1/PxShare nfs ...

7.4 啟動 PVE 服務

systemctl start pveproxy pvedaemon pvestatd

7.5 確認 Proxmox 判定 storage active

pvesm status | grep nas2-pxshare

實際成功輸出:

nas2-pxshare         nfs     active     18739479296     16557377408      2182101888   88.36%

8. 結論(Root cause)

  • node1 的 nas2-pxshare 出現了掛載來源不一致與疊掛:
    • 同一個 mountpoint 同時存在 NFSv4(顯示 192.168.10.132)與 NFSv3(顯示 172.16.0.10
  • 事後檢討高度懷疑是以下流程造成殘留:
    • 一開始用 192.168.10.132 建立了 nas2-pxshare
    • 後來刪除並用同名重新建立,但改指向 172.16.0.10
    • node2 沒出現異常,但 node1 保留舊的掛載狀態,進而導致來源漂移與疊掛
  • Proxmox 對 storage 的判定會依照 storage.cfg 的 server/export 與實際掛載狀態做檢查,當這兩者不一致時,storage 會被判為 inactive
  • 在 storage 狀態異常的情況下,PVE 對 VM 的管理操作會出現大量 timeout(包含 QMP 操作),進而導致 VM console / vncproxy 失敗

9. 後續建議(避免復發)

  • 若要變更 NFS storage 指向的 NAS IP,建議避免「刪除後用同名重建但改 server」而沒有清掉各節點上的舊掛載狀態
  • 當 UI 出現 storage 灰色問號或 pvesm status 顯示 inactive 時,第一時間先做:
findmnt /mnt/pve/nas2-pxshare -o TARGET,SOURCE,FSTYPE,OPTIONS
  • 若同一路徑出現多行,優先處理疊掛(停 PVE 服務後逐層卸載乾淨,再重新掛載成單一來源)