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 服務後逐層卸載乾淨,再重新掛載成單一來源)

將 IBM Windows Server 2003 實體機轉換成 Proxmox 虛擬機並縮小磁碟空間

這次紀錄的是一台相當老舊的 IBM 實體主機,系統為 Windows Server 2003。由於硬碟老化與備援需求,我希望把它完整轉換成虛擬機,運行在 Proxmox VE 環境中,並進一步縮小原本 2TB 的系統磁碟,以節省儲存空間。


一、使用 VMware vCenter Converter (XP 可用版本) 進行 P2V

由於這台主機仍在 Windows XP 時代的軟體相容範圍內,我選擇了舊版的 VMware vCenter Converter (P2V Virtual Machine Converter),這是少數仍能在 XP/Server 2003 上執行的版本。

步驟如下:

  1. 在 IBM 主機上安裝 VMware vCenter Converter。
  2. 選擇「Convert Local Machine」。
  3. 目標格式設定為 VMware Workstation / Other VMware Virtual Machine
  4. 輸出 .vmdk 虛擬磁碟到外接硬碟或網路共享資料夾。

這一步結束後,就能得到一組 Windows2003.vmdk.vmx 等檔案。


二、將 vmdk 轉換為 Proxmox 可用的 qcow2

將輸出的 vmdk 檔案複製到 Proxmox 環境,例如:

/mnt/pve/nas2-in/images/602/

使用以下指令轉換為 qcow2:

qemu-img convert -O qcow2 Windows2003.vmdk vm-602-disk-0.qcow2

Proxmox 便能直接掛載這顆虛擬磁碟。


三、啟動測試並確認系統可開機

  1. 建立新的虛擬機,BIOS 設定為 SeaBIOS,顯示卡設為 VGA。
  2. 掛載 vm-602-disk-0.qcow2 為主磁碟。
  3. 啟動後確認能正常進入桌面,檢查 IIS、應用程式與服務運作是否正常。

若遇到「NTLDR is missing」等啟動錯誤,可用 Windows Server 2003 安裝光碟修復開機:

fixboot
fixmbr
bootcfg /rebuild

四、進行系統內部磁碟縮小準備

原始磁碟為 2TB,實際使用空間不到 50GB。
縮小前必須確保檔案系統一致性並釋放未使用區塊。

1. 執行磁碟重組

在 Windows 2003 內執行系統內建的「磁碟重組 (Defragmenter)」,將資料集中於磁碟前段。

2. 使用 SDelete 填零釋放空間

下載 Sysinternals 的 sdelete.exe,執行以下指令:

sdelete -z C:

這會將所有未使用的磁區以零填滿,讓後續壓縮與縮小能更有效。
由於這台主機的虛擬磁碟格式為 IDE 模擬介面,磁碟 I/O 速度極慢,整個過程耗時極長。

在我的情況下,SDelete 執行將近兩週才完成,CPU 與 I/O 幾乎全程滿載。若使用 VirtIO 或 SCSI 介面,時間可望縮短至數小時內。


五、在 Windows 7 環境中進行磁碟縮小

Windows Server 2003 無法原生縮小系統分割區,因此我原本打算使用 ClonezillaGParted Live 進行分割區調整。
然而實際操作時,無論是在 Clonezilla 還是 GParted Live 環境中,系統都會顯示「硬碟毀損」或「檔案系統錯誤」,導致無法執行縮小。

我嘗試重新開回 XP / 2003 系統執行磁碟檢查 (chkdsk /f) 並重新操作,但依然無法通過 GParted 的檢查。
後來推測是 NTFS metadata 結構與 GParted 的 NTFS 驅動版本不完全相容,導致誤判為壞軌。

最終解法是改用 Windows 7 環境的磁碟管理工具 (diskmgmt.msc)
步驟如下:

  1. 關閉 2003 VM,將其 qcow2 掛載為 Win7 VM 的第二顆硬碟。
  2. 在 Win7 內開啟「磁碟管理」。
  3. 對 C: 點選「壓縮磁碟區」,將容量縮至 49GB
  4. 完成後會看到後段變成 未配置 (Unallocated)

這種方式穩定、可直接作用於 NTFS 系統分割區,是整個流程中最有效的一步。


六、在 Proxmox 縮小 qcow2 檔案

  1. 掛載磁碟到 nbd 驗證分割區長度:

    qemu-nbd -r -c /dev/nbd0 vm-602-disk-0.qcow2
    fdisk -l /dev/nbd0

    輸出確認 /dev/nbd0p1 約為 49GB。

  2. 卸載 nbd:

    qemu-nbd -d /dev/nbd0
  3. 執行安全縮減(預留少許緩衝):

    qemu-img resize --shrink vm-602-disk-0.qcow2 52G
  4. 進一步壓縮虛擬磁碟:

    qemu-img convert -O qcow2 vm-602-disk-0.qcow2 vm-602-disk-0-slim.qcow2

轉換後檔案大小從原本 2TB 減至約 30~35GB。


七、替換與測試

  1. 在 Proxmox 網頁介面中 Detach 原本的 qcow2。
  2. 掛上新的 vm-602-disk-0-slim.qcow2
  3. 啟動虛擬機,確認能正常進入桌面並運行應用程式。
  4. 測試無誤後,可刪除舊檔或保留為備份。

八、結果與心得

整個過程中最關鍵的部分包括:

  • 使用 XP 可用版本的 VMware vCenter Converter 成功進行 P2V。
  • 在新版系統中進行分割區壓縮,避開 2003 無法 shrink 的限制。
  • 避免使用 Clonezilla 或 GParted Live 直接操作 NTFS 系統磁碟,否則容易被誤判為壞軌。
  • 使用 sdelete -z 填零未使用空間,配合 qemu-img convert 達成真正的磁碟瘦身。

最終結果:

  • 原始 2TB 的磁碟映像,成功縮減至 52GB 並壓縮成約 35GB。
  • 系統能正常開機、IIS 與內部應用程式皆正常運作。
  • 整個流程最耗時的步驟是 SDelete,在 IDE 虛擬介面下執行近兩週,若能改用 VirtIO,效能將大幅改善。