VPS 能跑 Proxmox 嗎?巢狀虛擬化檢查教學
檢查您的 VPS 是否支援 Nested Virtualization。使用 kvm-ok 指令快速確認 CPU 是否具備 vmx 或 svm 旗標。若供應商隱藏指令集,您將無法在 VPS 內執行 Proxmox 或 KVM 虛擬機。本文提供判斷標準與解決方法。
簡短回答
巢狀虛擬化(Nested virtualization)是指在虛擬機器內執行 Hypervisor:您的 VPS 本身已是客戶端,而您希望它能再託管其他客戶端。這僅在供應商的 Hypervisor 有意將 CPU 虛擬化擴充指令集(virtualization extensions)開放給您的實例時才有效。請檢查 /proc/cpuinfo 以確認是否存在 vmx 旗標(Intel)或 svm 旗標(AMD);若兩者皆不存在,則在 VPS 內進行任何設定都無法解決問題。
首先說明一個前提:Docker 不需要這些功能。 容器與您的 VPS 共用核心,且不會觸及 /dev/kvm。如果您的目標是「在伺服器上的容器中執行多項服務」,您現有的環境已足夠。當您需要「第二個核心」時,巢狀虛擬化才至關重要,例如:Proxmox 實驗室、Windows 客戶端、Firecracker microVMs、Android 模擬器、由真實 VM 組成的 Kubernetes 測試平台,或是啟動 VM 映像檔的 CI Runner。
實際嵌套的內容
共三層:
- L0 — 位於實體機上的供應商 hypervisor。您無法存取此層。
- L1 — 您的 VPS。在 L0 視角下,這僅是一個 guest。
- L2 — 您欲在 VPS 內執行的 VM。
硬體虛擬化包含 Intel 的 VT-x (vmx flag) 加上 EPT,以及 AMD 的 AMD-V / SVM (svm) 加上 RVI/NPT。Hypervisor 利用這些指令進入 guest mode,並允許 CPU 同時走訪兩份 page tables。
這兩者皆非為可重入 (re-entrant) 設計,因此嵌套是透過模擬實現的:當 L1 執行 VMX 指令時,會觸發 trap 至 L0,由 L0 代表 L1 維護 L2 的 shadow structures。KVM 的表現優異,但 L0 在每次 exit 時都必須執行額外工作,這也是供應商必須選擇啟用 (opt in) 的原因。
若要實現加速的 L2,必須同時滿足兩個條件:
- L0 的 KVM module 已載入
nested=1。 - L0 分配給您的 VPS 的 CPU model 具備該 flag — 在 libvirt 為
<cpu mode='host-passthrough'/>、Proxmox 為cpu: host、原始 QEMU 為-cpu host。通用的模擬 model (qemu64,kvm64) 會隱藏vmx,即便全域已開啟 nesting。
一分鐘內檢查您的 VPS
# 1. Are you in a VM, and under what?
systemd-detect-virt # kvm, vmware, xen, microsoft, or "none" on metal
# 2. Does the CPU expose the extensions to you?
grep -o -E 'vmx|svm' /proc/cpuinfo | sort -u
lscpu | grep -i -E 'virtual|hypervisor'
# 3. The definitive check
sudo apt update && sudo apt install -y cpu-checker
kvm-ok
# 4. The device node the whole stack depends on
ls -l /dev/kvm可用的實例會顯示 vmx 或 svm,kvm-ok 會顯示 KVM acceleration can be used,且 /dev/kvm 以 root:kvm 模式 660 存在。若 flag 存在但 device node 不存在,請手動載入 module 並查看 kernel log:
sudo modprobe kvm_intel # or kvm_amd
sudo dmesg | tail -n 20有一個檔案經常被引用且極易被誤解:
cat /sys/module/kvm_intel/parameters/nested # Y or N在您的 VPS 內部,這是 您的 KVM module 的設定,它決定了 L2 guest 是否能進行第三層嵌套。它並不代表 L0 是否為您啟用了 nesting —— /proc/cpuinfo 與 kvm-ok 會說明該情況。nested 參數是您在完全擁有的機器上所設定的控制項:
echo 'options kvm_intel nested=1' | sudo tee /etc/modprobe.d/kvm-nested.conf
sudo modprobe -r kvm_intel && sudo modprobe kvm_intel若 VM 正在執行,系統會拒絕移除 module,因此請先關閉 guest。
為什麼大多數 VPS 供應商預設關閉此功能
- Live migration。 提供
vmx會暴露帶有該指令集的 CPU 型號;若虛擬機依賴這些 CPU 特性,則無法安全地遷移至不具備該指令集的機器。若主機透過遷移客戶端來釋放節點,一旦啟用嵌套虛擬化(nesting),就會失去此能力。 - 攻擊面。 嵌套 VMX/SVM 路徑屬於核心(kernel)虛擬化層中最複雜的程式碼之一,且有相關的 CVE 漏洞紀錄。
- L0 可能不是 KVM。 若
systemd-detect-virt輸出vmware、xen或microsoft,則嵌套規則由該堆疊(stack)決定,而非 KVM。
若您的實例沒有此指令集,請聯繫客服(部分供應商會針對單一 VM 開啟)、選擇有說明支援 nesting 的方案,或改用專用伺服器(dedicated box)。本指南後續內容皆假設您在已顯示該指令集的機器上擁有 root 權限。
使用 libvirt 執行 L2 guest
sudo apt install -y qemu-system-x86 libvirt-daemon-system virtinst ovmf
sudo systemctl enable --now libvirtd
sudo usermod -aG libvirt,kvm "$USER" # log out and back in
virt-install \
--name guest1 \
--memory 2048 \
--vcpus 2 \
--cpu host-passthrough \
--disk path=/var/lib/libvirt/images/guest1.qcow2,size=20,format=qcow2,bus=virtio \
--network network=default,model=virtio \
--os-variant debian13 \
--location https://deb.debian.org/debian/dists/trixie/main/installer-amd64/ \
--graphics none \
--console pty,target_type=serial \
--extra-args 'console=ttyS0,115200n8'不需要圖形化工作階段。序列安裝(serial install)需要較長時間,請在持久性 shell 中執行:使用與 在 VPS 上保持 Claude Code 工作階段存活的 tmux 工作流程 相同的模式,即可在 SSH 連線中斷時保持 virt-install console 連線。若 --os-variant debian13 被拒絕,代表您的 osinfo-db 早於該版本發佈 — 請執行 osinfo-query os 並選擇現有的名稱。--cpu host-passthrough 會將 vmx 轉發至 L2,僅在 L2 需要進行嵌套虛擬化(virtualize in turn)時才需要。請使用 virsh autostart guest1 確保 guest 啟動安全。
磁碟與 NIC 的 virtio 匯流排並非僅供裝飾:模擬的 IDE 與 e1000 裝置觸發(trap)至 hypervisor 的頻率遠高於 virtio 佇列,且在嵌套虛擬化環境下,每次 trap 都會產生兩倍的開銷。
Networking: 教程中略過的重點
您的 VPS 僅有一個公用 IP,且位於會過濾未知 MAC 位址的網路架構後方。這會導致兩個結果。
將 L2 虛擬機橋接至公用網路通常無法運作。 若在公用 NIC 上設定 br0 並給予虛擬機獨立的 MAC 位址,您會發現 ARP 封包已送出但沒有任何回應 —— 供應商的交換器會丟棄來自未經授權 MAC 位址的封包。若遇到此現象,請停止除錯 bridge;這是網路架構的限制。
請改用 NAT 網路。 libvirt 內建 default:包含 virbr0、192.168.122.0/24 與 dnsmasq 租約,可立即進行外連。若需處理內連請求,請在 L1 終止 TLS 並進行代理 —— 以下的憑證路徑取自 使用 Certbot 在 Nginx 簽發 Let's Encrypt 憑證:
server {
listen 443 ssl;
server_name lab.example.com;
ssl_certificate /etc/letsencrypt/live/lab.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/lab.example.com/privkey.pem;
location / {
proxy_pass http://192.168.122.50:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}請先為虛擬機設定靜態租約 (virsh net-edit default),以確保該 proxy_pass 的位址保持固定。
管理介面不應直接連至網際網路:5900 埠的 VNC 與 8006 埠的 Proxmox Web UI 應設定於 loopback,並透過 SSH 隧道 (ssh -N -L 8006:127.0.0.1:8006 you@your-vps) 或 連回 VPS 的自建 WireGuard VPN 進行存取,這會使整個 192.168.122.0/24 虛擬機範圍僅需經過一個私有跳轉。請嚴格限制防火牆規則 —— 僅允許 sudo ufw allow 22,80,443/tcp,其餘皆禁止。若啟用 ufw 後虛擬機立即失去外連能力,常見原因是 /etc/default/ufw 中的 DEFAULT_FORWARD_POLICY="DROP" —— 請將其設定為 ACCEPT 並重新載入 ufw。
在 VPS 上安裝 Proxmox
Proxmox VE 9 底層為 Debian 13,因此只需在 Debian VPS 中加入 pve-no-subscription 儲存庫與 proxmox-ve 套件即可完成安裝。請直接從 Proxmox 官方最新文件取得儲存庫與 keyring 設定行;若使用舊部落格文章中的 URL,會導致安裝失敗。
套件安裝並非難點。Proxmox 要求將 vmbr0 橋接至實體 NIC,這會直接觸及上述的 MAC 篩選限制。在 VPS 上可行的方案是使用 NAT 或路由模式的 vmbr0,且不連接實體埠。虛擬機應使用私有網段,並在主機上設定 DNAT 規則或反向代理來處理公網流量。若公網服務是以 Container 而非 VM 形式運行,使用 Traefik 透過單一 Docker Compose 檔案代理多個應用程式 也能透過自動化憑證完成相同的路由工作。請務必先進行 /etc/network/interfaces 快照:錯誤的 bridge 定義會導致您無法連線至機器,且您可能無法取得該機器的 console 權限。
效能實話實說
Nested 虛擬化比單層虛擬化慢,其原因並非分散,而是具體的:效能損耗不在於記憶體存取,而在於 exit。 在啟用 EPT/NPT 的情況下,L0 會為 L2 維護 shadow page tables,一般的記憶體讀取能以硬體速度執行。昂貴的操作是所有離開 guest mode 的行為——例如 I/O、timer interrupts、MMIO、inter-processor interrupts——因為 L2 exit 必須由 L0 處理,且可能需透過 L1 反饋。若工作負載為已在 RAM 中的資料進行 CPU 密集運算,效能接近原生;若工作負載受 syscalls、封包與 disk I/O 主導,則能明顯感受到層級帶來的損耗。
因此:請在各處使用 virtio devices。此外,您的 qcow2 檔案位於供應商已經虛擬化過的磁碟上——這代表兩層 thin-provisioning 疊加,其中 guest disk 上的 cache=none 會導致相同的 blocks 同時存在於兩個 page caches 中。此處不提供基準測試數據:請針對您自己的 instance 進行工作負載測試。
Failure modes, and the strings you will see
INFO: /dev/kvm does not exist / KVM acceleration can NOT be used from kvm-ok。可能是模組未載入,或是 flag 未開啟。請先檢查 /proc/cpuinfo。
kvm: disabled by bios in dmesg。若為實體機,請在韌體中開啟 VT-x/SVM 開關。若為 VPS,代表 L0 未提供擴充指令集,在 guest 中進行任何設定皆無效。
modprobe: ERROR: could not insert 'kvm_intel': Operation not supported。核心偵測到的 CPU 不支援 vmx —— 這同樣是由 L0 決定。
Could not access KVM kernel module: Permission denied。這是權限問題,而非硬體問題。ls -l /dev/kvm 應顯示 group 為 kvm,mode 為 660;請將使用者加入該 group 並重新登入,因為現有的 session 無法套用新的 group 權限。
kvm: Device or resource busy when QEMU starts。另一個 hypervisor 模組正佔用 CPU:請執行 lsmod,檢查是否存在 vboxdrv 或 VMware 模組(與 kvm_intel 並列),並卸載不需要的模組。
/var/run/libvirt/libvirt-sock: No such file or directory from virsh。Daemon 已停止運作:請執行 sudo systemctl enable --now libvirtd。
Proxmox: KVM virtualisation configured, but not available. Guest 開啟了 KVM 加速,但 Host 無法提供該功能。請修正 nesting 設定,或是取消勾選以使用 emulation。
Android emulator: x86_64 emulation currently requires hardware acceleration! 又是 /dev/kvm —— 通常是 group 權限問題。
完全沒有錯誤,但速度極慢。 若 QEMU 未帶入 accelerator flag,會退回到 TCG 軟體模擬模式。這雖然符合邏輯但速度極慢 —— 原本只需數秒的開機時間會變成數分鐘。請明確傳遞 -accel kvm,讓 QEMU 在無法使用加速器時直接報錯,而非靜默進行模擬。
Guest 在執行中突然消失。 請檢查 dmesg 中的 Out of memory: Killed process ... qemu-system-x86_64。L2 guest 是 L1 上的處理程序,OOM killer 會像處理其他程序一樣處理它。L2 的 RAM 是從 L1 的固定配置中扣除,無法向 host 借用。
運作指南:備份、升級與限制
備份。 直接複製運行中的 guest qcow2 會導致映像檔損毀。請使用 virsh shutdown guest1 進行複製,或是建立外部 snapshot (virsh snapshot-create-as guest1 snap1 --disk-only --atomic);如此一來,寫入操作會轉向 overlay,讓您能複製已靜態化的 base,最後再透過 virsh blockcommit 將其合併。請將備份檔移出 VPS — 儲存在同一顆磁碟上的 snapshot 無法防止硬體故障。
升級。 apt full-upgrade 會安裝新的 kvm_intel/kvm_amd 模組,但在重新啟動前,運行中的 kernel 仍會維持舊版模組。請保留舊版 kernel,並在每次 kernel 變更後重新執行 kvm-ok:若主機在缺少 vmx 的情況下重新啟動,只需透過一個 boot entry 即可恢復運作。
擴展限制。 單一公用 IP 意味著所有 L2 服務都必須透過 L1 上的 proxy 或 DNAT 規則來連向外部。本系統不支援 live migration。在 CPU 爭用(contention)的情況下,nested exit path 會最先受到影響。對於運行多個 guests 的 hypervisor 而言,RAM 資源已經被耗盡 — nested VMs 無法透過 overcommit 來突破固定配額的限制。當實驗室規模超過此限制時,解決方案並非建立更深層的 nested stack,而是使用一台專用主機,讓您成為 L0,屆時上述限制皆不再適用。
FAQ
在 VPS 上執行 Docker 需要嵌套虛擬化 (nested virtualization) 嗎?
不需要。容器與您的 VPS 共用核心,且不會開啟 /dev/kvm,因此不具備 vmx 或 svm 旗標的標準實例即可正常執行 Docker 與 Docker Compose。只有當您需要第二層核心時,嵌套虛擬化才變得重要:例如 Proxmox 實驗室、Windows 客戶端、Firecracker microVMs、Android 模擬器,或是需要啟動 VM 映像檔的 CI runners。
如何檢查我的 VPS 是否支援嵌套虛擬化?
請執行 grep -o -E 'vmx|svm' /proc/cpuinfo | sort -u,接著執行 cpu-checker 套件中的 kvm-ok。若可使用,則會印出 vmx (Intel) 或 svm (AMD);kvm-ok 會回報 KVM acceleration can be used;且 /dev/kvm 存在於 kvm 群組並具備 660 權限。針對此問題,請忽略 /sys/module/kvm_intel/parameters/nested —— 該檔案描述的是您自身的 KVM 模組,而非供應商 Hypervisor 揭露給您的功能。
為什麼大多數 VPS 供應商會停用嵌套虛擬化?
揭露 vmx 意味著提供帶有該旗標的 CPU 模型給客戶端;若客戶端依賴這些 CPU 特性,則無法被 Live-migrate 到不具備該特性的機器上 —— 對於需要透過移動客戶端來平衡節點負載的供應商而言,這是不必要的風險。此外,嵌套 VMX/SVM 程式碼路徑具有長期的 CVE 漏洞紀錄。部分主機仍可根據需求為單一 VM 開啟此功能,其他供應商則將嵌套虛擬化列為進階功能。
我的嵌套 VM 在公用橋接網路 (public bridge) 上沒有網路連線。問題出在哪?
供應商的交換器會丟棄來自未經租賃之 MAC 位址的封包,因此將 L2 客戶端橋接到公用 NIC 的做法,會導致發送 ARP 後收不到任何回應。請停止對 br0 進行除錯 —— 請改用 libvirt 的 NAT default 網路 (virbr0, 192.168.122.0/24),為客戶端分配靜態租約,並透過反向代理 (reverse proxy) 或 VPS 本身的 DNAT 規則來發布公用服務。
嵌套 VM 的效能會慢多少?
效能損耗主要源於 VM exits,而非記憶體存取。在啟用 EPT/NPT 的情況下,L2 內部的普通讀寫以硬體速度執行,但 I/O、定時器中斷 (timer interrupts)、MMIO 與 IPI 則由 L0 處理,並可能經由 L1 回傳。針對已在 RAM 中的數據進行 CPU 密集型運算,效能接近原生;但對於系統呼叫 (syscall)、封包處理與磁碟密集型工作負載,每一層虛擬化都會產生感官上的延遲。請在所有地方使用 virtio 裝置與客端磁碟的 cache=none,然後再根據您的工作負載進行測試。