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

Onboard 虛擬鍵盤 Debian 13 + KDE Plasma 6 + Wayland 完整設定教學(uinput 方案)

前言:從幾乎放棄,到終於能打字

老實說,這篇文章是我在幾乎準備放棄 KDE Plasma Wayland 的虛擬鍵盤時寫下的。

在 Debian 13 + KDE Plasma 6 + Wayland 環境下,官方唯一支援的螢幕鍵盤是 Maliit
但實際使用後,我遇到的是一連串幾乎無解的問題:

  • 鍵盤只出現一次
  • swipe 收起後再也叫不回來
  • 必須重啟 KWin 或整個桌面
  • 與實際平板/二合一裝置使用情境完全不相容

在反覆搜尋解法、翻 GitHub issue、KDE Discuss 討論串的過程中,我一度覺得:
「也許觸控平板選 KDE Wayland 就是死路一條。」

直到我 Google 到一篇 2022 年的 KDE Discuss 討論串

Plasma 6 and Wayland no on-screen keyboard working - Help - KDE Discuss

其中有一位使用者 @INVICTRA 提到:

I managed to get Onboard working on wayland. Kubuntu 25.04

1 Edit the shortcut in the menu. Within the KDE Menu Editor look for the Environment variables field and add “GDK_BACKEND=x11”.

2 Go to Onboard preferences page. Under Keyboard – >Advanced set:

Input Options → Input event source: GTK
Key-stroke Generation → Key-stroke generator: uinput

If you have time please try it. I would like to know if it works for others too.

我拿去問 ChatGPT 5.2,指出:Onboard + X11 backend + uinput,可能是突破口。

於是我開始實驗,補齊權限、kernel、udev 等細節,最後真的在 Debian 13 + KDE Plasma 6 + Wayland 上,
得到一個 穩定、可重複呼叫、不會卡死 的虛擬鍵盤解法。

這篇文章,就是完整整理後的結果。


一、為什麼需要這樣做(背景說明)

  • 2025 年末 KDE Plasma Wayland 官方仍只支援 Maliit
  • Maliit 目前在 KDE Plasma 存在嚴重 bug(收起後無法再叫出)
  • Wayland 設計上禁止 synthetic input(模擬鍵盤/滑鼠)
  • Onboard 可透過 Linux kernel 的 uinput 建立「虛擬鍵盤裝置」
  • uinput 屬於 kernel input device,不受 Wayland 限制

簡單說:

Wayland 不讓你「假裝按鍵」,
但 uinput 讓你「真的插一把虛擬鍵盤」。

在目前 Debian + KDE Plasma Wayland 的條件下,
這幾乎是唯一實際可用的方案。


二、系統需求

  • Debian 13

  • KDE Plasma 6

  • Wayland session

  • 已安裝 XWayland(通常預設已有)

  • 使用者具備 sudo 權限

    • *

三、安裝必要套件

sudo apt update
sudo apt install onboard xwayland

四、啟用 kernel uinput 模組

1. 確認是否已載入

lsmod | grep uinput

若沒有任何輸出,請手動載入:

sudo modprobe uinput

2. 設定開機自動載入

echo uinput | sudo tee /etc/modules-load.d/uinput.conf

五、設定 uinput 權限(關鍵步驟)

1. 建立群組

sudo groupadd -f uinput

2. 將使用者加入群組(以 hln 為例)

sudo usermod -aG uinput hln

注意:這一步完成後,一定要重新登入或重開機。


3. 建立 udev 規則

sudo nano /etc/udev/rules.d/99-uinput.rules

內容如下:

KERNEL=="uinput", MODE="0660", GROUP="uinput"

重新載入規則:

sudo udevadm control --reload
sudo udevadm trigger

4. 重開機後確認

ls -l /dev/uinput

正確結果應類似:

crw-rw---- 1 root uinput /dev/uinput

確認自己在群組內:

groups

必須看到 uinput


六、以 X11 backend 啟動 Onboard(非常重要)

在 Wayland 下,一定要強制使用 X11 backend

GDK_BACKEND=x11 onboard

建議先在 Konsole 中測試,確認鍵盤能正常顯示。


七、Onboard 設定(必做)

開啟 Onboard → Preferences → Keyboard → Advanced

請設定為:

  • Input Options

    • Input event source:GTK
  • Keystroke Generation

    • Key-stroke generator:uinput

如果你之前試過 uinput 但沒有反應,
完成權限設定後一定要重新測試。


八、實際驗證方式

  1. 開啟可輸入文字的程式(Kate / Firefox / Konsole)
  2. 點擊輸入框取得 focus
  3. 使用 Onboard 點擊鍵盤

成功狀態:

  • 文字實際輸入到程式中

  • 可反覆叫出 / 收起

  • 不需重啟 KWin

  • 不會卡死

  • 不受 Maliit bug 影響

    • *

九、建立桌面捷徑(推薦)

nano ~/.local/share/applications/onboard-x11.desktop

內容:

[Desktop Entry]
Name=Onboard (Wayland Safe)
Exec=env GDK_BACKEND=x11 onboard
Type=Application
Icon=onboard
Categories=Utility;Accessibility;

之後可以:

  • 加到 KDE 工作列

  • 加到桌面

  • 當作一鍵呼叫虛擬鍵盤

    • *

十、限制與注意事項

已知限制

  • SDDM 登入畫面無法使用
  • 非 Wayland 原生(透過 XWayland)
  • 提升輸入層權限,適合個人裝置

優點

  • 不會 swipe-down 卡死

  • 支援 Ctrl / Alt / Function keys

  • 可搭配 Fcitx5 新酷音

  • Synergy / KVM 正常

  • 長時間穩定可用

    • *

十一、回復原狀(可逆)

sudo rm /etc/udev/rules.d/99-uinput.rules
sudo gpasswd -d hln uinput
sudo reboot

十二、結論

在 Debian 13 + KDE Plasma Wayland 環境下:

Onboard + uinput 是目前唯一實際可用的虛擬鍵盤方案。

這不是官方完美解法,但 KDE 社群畢竟是做無償,你不能過度給予不符比例的期待。

最重要的是問題解決,我現在可以拿著沒有鍵盤的平板,打注音或英文操作系統了!