SSD Nodes Learn
Hướng dẫn Matt ConnorBởi Matt Connor · Cập nhật ngày 2026-07-23

VPS có chạy được Proxmox không?

Kiểm tra khả năng nested virtualization trên VPS bằng lệnh kvm-ok. Xem ngay cách xác định CPU có hỗ trợ chạy Proxmox hay không để tránh lãng phí tiền VPS.

Câu trả lời ngắn gọn

Nested virtualization là một hypervisor chạy bên trong một máy ảo: VPS của bạn vốn đã là một guest, và bạn muốn nó host thêm các guest khác. Nó chỉ hoạt động khi hypervisor của nhà cung cấp chủ động expose các phần mở rộng ảo hóa của CPU cho instance của bạn — hãy kiểm tra flag vmx (Intel) hoặc svm (AMD) trong /proc/cpuinfo, nếu không thấy cả hai, thì không có cấu hình nào bên trong VPS có thể khắc phục được.

Một lưu ý quan trọng trước: Docker không cần bất kỳ thứ gì trong số này. Các container dùng chung kernel của VPS và không bao giờ chạm vào /dev/kvm. Nếu mục tiêu thực sự là "chạy vài dịch vụ trong container trên server của tôi", bạn đã có đủ thứ cần thiết rồi. Nesting chỉ quan trọng khi bạn muốn một kernel thứ hai — một lab Proxmox, một guest Windows, Firecracker microVMs, trình giả lập Android, một Kubernetes testbed với các VM thực thụ, hoặc các CI runners boot các image VM.

Thực chất cái gì đang được nesting

Ba lớp:

  • L0 — hypervisor của nhà cung cấp, chạy trên phần cứng (metal). Bạn không có quyền truy cập vào nó.
  • L1 — VPS của bạn. Đối với L0, đây chỉ là một guest.
  • L2 — máy ảo bạn muốn chạy bên trong VPS của mình.

Ảo hóa phần cứng là VT-x (flag vmx) cộng với EPT trên Intel, hoặc AMD-V / SVM (svm) cộng với RVI/NPT trên AMD. Một hypervisor sử dụng các instruction này để vào guest mode và cho phép CPU duyệt qua hai page table cùng một lúc.

Cả hai đều không được thiết kế để chạy lồng nhau (re-entrant), nên nesting được thực hiện bằng cách emulated: khi L1 thực thi một VMX instruction, nó sẽ bị trap về L0, và L0 sẽ duy trì các shadow structures cho L2 thay mặt cho L1. KVM làm việc này rất tốt, nhưng L0 phải tốn thêm công sức cho mỗi lần exit — đó là lý do tại sao nhà cung cấp phải cho phép opt-in.

Hai điều kiện sau đây phải đồng thời thỏa mãn để có L2 được tăng tốc:

  1. Module KVM của L0 được load với nested=1.
  2. L0 cấp cho VPS của bạn một CPU model có mang flag — <cpu mode='host-passthrough'/> trong libvirt, cpu: host trong Proxmox, -cpu host trong raw QEMU. Một model emulated generic (qemu64, kvm64) sẽ ẩn vmx ngay cả khi nesting đã được bật toàn cục.

Kiểm tra VPS của bạn trong một phút

# 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

Một instance khả dụng sẽ in ra vmx hoặc svm, kvm-ok nói KVM acceleration can be used, và /dev/kvm tồn tại dưới dạng mode 660 của root:kvm. Nếu flag đã có nhưng device node thì không, hãy load module bằng tay và đọc kernel log:

sudo modprobe kvm_intel     # or kvm_amd
sudo dmesg | tail -n 20

Một file thường xuyên được trích dẫn nhưng hay bị hiểu sai:

cat /sys/module/kvm_intel/parameters/nested   # Y or N

Bên trong VPS của bạn, đó là thiết lập của module KVM của chính bạn, và nó quyết định liệu một guest L2 có thể nest thêm lớp thứ ba hay không. Nó không cho biết liệu L0 có bật nesting cho bạn hay không — /proc/cpuinfokvm-ok sẽ trả lời câu hỏi đó. Tham số nested là nút vặn mà bạn thiết lập trên máy mà bạn sở hữu hoàn toàn:

echo 'options kvm_intel nested=1' | sudo tee /etc/modprobe.d/kvm-nested.conf
sudo modprobe -r kvm_intel && sudo modprobe kvm_intel

Không thể gỡ module khi đang có một VM đang chạy, vì vậy hãy tắt các guest trước.

Tại sao hầu hết các host VPS đều tắt nó

  • Live migration. Việc cấp cho bạn vmx đồng nghĩa với việc expose một CPU model có mang flag, và một guest phụ thuộc vào các tính năng CPU đó sẽ không thể được migrate an toàn sang một máy có CPU thiếu chúng. Một host thực hiện drain node bằng cách migrate khách hàng sẽ phải từ bỏ tính năng này ngay khi họ bật nesting.
  • Attack surface. Các đường dẫn VMX/SVM lồng nhau nằm trong số những phần code phức tạp nhất trong lớp ảo hóa của kernel, với một lịch sử CVE tương ứng.
  • L0 có thể không phải là KVM. Nếu systemd-detect-virt in ra vmware, xen hoặc microsoft, thì các quy tắc nesting thuộc về stack đó, không phải KVM.

Không thấy flag nào trên instance của bạn? Hãy hỏi support (một số nơi bật nó theo từng VM), chọn gói dịch vụ có tài liệu về nesting, hoặc chuyển sang dùng máy dedicated. Phần còn lại của bài viết này giả định bạn có quyền root trên một máy có hiển thị flag.

Chạy một guest L2 với libvirt

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'

Không cần session đồ họa. Một bản cài đặt qua serial sẽ chạy được một lúc, vì vậy hãy bắt đầu nó trong một shell persistent: cùng một workflow tmux giúp giữ các session Claude Code luôn sống trên VPS sẽ giữ một console virt-install luôn được kết nối ngay cả khi mất kết nối SSH. Nếu --os-variant debian13 bị từ chối, thì osinfo-db của bạn đã cũ hơn bản release — hãy chạy osinfo-query os và chọn một cái tên có tồn tại. --cpu host-passthrough sẽ forward vmx xuống L2, chỉ cần thiết nếu L2 cần phải ảo hóa tiếp. Hãy giúp guest boot-safe với virsh autostart guest1.

Bus virtio trên disk và NIC không phải để trang trí: các thiết bị emulated IDE và e1000 trap vào hypervisor thường xuyên hơn nhiều so với các virtio queues, và khi nesting, mỗi trap sẽ bị tính phí hai lần.

Networking: phần mà các tutorial thường bỏ qua

VPS của bạn có một IP public và nằm sau một fabric lọc các địa chỉ MAC không xác định. Có hai hệ quả sau đây.

Bridging các guest L2 lên mạng public thường sẽ không hoạt động. Nếu đặt br0 trên NIC public, cấp cho guest một MAC riêng, bạn sẽ thấy ARP gửi đi nhưng không có gì phản hồi — switch của nhà cung cấp sẽ drop các frame từ một MAC mà họ chưa bao giờ cấp cho bạn. Nếu đó là triệu chứng bạn gặp phải, hãy ngừng debug bridge; đó chính là cơ chế của họ.

Hãy dùng mạng NAT thay thế. libvirt đi kèm với default: virbr0, 192.168.122.0/24, các lease của dnsmasq, và outbound sẽ hoạt động ngay lập tức. Đối với inbound, hãy terminate TLS trên L1 và proxy vào — các đường dẫn certificate dưới đây đến từ issuing a Let's Encrypt certificate with Certbot on Nginx:

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;
    }
}

Hãy cấp cho guest một static lease trước (virsh net-edit default) để địa chỉ trong proxy_pass đó được cố định.

Các interface quản lý nên để off internet: VNC trên port 5900 và Proxmox web UI trên port 8006 nên nằm trên loopback, được truy cập qua một SSH tunnel (ssh -N -L 8006:127.0.0.1:8006 you@your-vps) hoặc qua một self-hosted WireGuard VPN vào VPS, giúp đưa toàn bộ dải guest 192.168.122.0/24 chỉ cách một hop private. Giữ firewall thật hẹp — sudo ufw allow 22,80,443/tcp, không gì khác. Nếu các guest mất kết nối outbound ngay sau khi bạn bật ufw, thủ phạm thường là DEFAULT_FORWARD_POLICY="DROP" trong /etc/default/ufw — hãy set nó thành ACCEPT và reload ufw.

Proxmox trên VPS

Proxmox VE 9 chạy trên nền Debian 13, vì vậy nó được cài đặt lên một Debian VPS bằng cách thêm repository pve-no-subscription và package proxmox-ve. Hãy lấy các dòng repository và keyring từ tài liệu hiện tại của chính Proxmox — một URL copy từ một blog cũ sẽ làm hỏng việc cài đặt.

Các package không phải là phần khó nhất. Proxmox yêu cầu vmbr0 được bridge với một NIC vật lý, điều này sẽ vấp ngay vào bế tắc lọc MAC ở trên. Cấu hình hoạt động được trên VPS là một vmbr0 được NAT hoặc routed mà không gắn port vật lý, các guest nằm trong dải private, và các rule DNAT hoặc reverse proxy trên host cho bất kỳ thứ gì public. Nếu các dịch vụ public là container thay vì VM, Traefik fronting multiple apps from one Docker Compose file sẽ đảm nhận cùng một nhiệm vụ routing với certificate tự động. Hãy snapshot /etc/network/interfaces trước: một định nghĩa bridge lỗi sẽ khiến bạn bị khóa khỏi một máy mà bạn có thể không có console.

Hiệu năng, nói một cách trung thực

Nesting chậm hơn so với single-level, và nguyên nhân nằm ở một điểm cụ thể chứ không phải phân tán: memory access không phải là nơi tốn chi phí, mà là các exits. Với sự hiện diện của EPT/NPT, L0 duy trì các shadow page tables cho L2 và các thao tác đọc bộ nhớ thông thường chạy ở tốc độ phần cứng. Thứ trở nên đắt đỏ là mọi thao tác rời khỏi guest mode — I/O, timer interrupts, MMIO, inter-processor interrupts — vì một L2 exit sẽ được xử lý bởi L0 và có thể bị phản hồi ngược lại qua L1. Các tác vụ nặng về CPU trên dữ liệu đã có sẵn trong RAM sẽ trông gần như native; bất cứ thứ gì bị chi phối bởi syscall, packet và disk I/O đều sẽ cảm nhận rõ các lớp.

Vì vậy: hãy dùng virtio devices ở mọi nơi. Và file qcow2 của bạn nằm trên một disk mà nhà cung cấp đã ảo hóa rồi — hai lớp thin-provisioning chồng lên nhau, nơi mà cache=none trên guest disk ngăn chặn việc cùng một block nằm trong hai page cache cùng một lúc. Không có con số benchmark ở đây: hãy tự đo workload của chính bạn trên instance của chính bạn.

Các lỗi thường gặp và các chuỗi ký tự bạn sẽ thấy

INFO: /dev/kvm does not exist / KVM acceleration can NOT be used từ kvm-ok. Hoặc là module chưa được load, hoặc flag chưa được expose. Hãy kiểm tra /proc/cpuinfo trước.

kvm: disabled by bios trong dmesg. Trên bare metal, hãy bật/tắt VT-x/SVM trong firmware. Trong VPS, điều này có nghĩa là L0 không cấp các extension cho bạn, và không có gì bạn gõ trong guest có thể thay đổi được điều đó.

modprobe: ERROR: could not insert 'kvm_intel': Operation not supported. CPU mà kernel của bạn thấy không có vmx — một lần nữa, đây là quyết định của L0.

Could not access KVM kernel module: Permission denied. Do quyền hạn, không phải do phần cứng. ls -l /dev/kvm nên hiển thị group kvm, mode 660; hãy thêm bạn vào group đó và bắt đầu một login shell mới, vì tư cách thành viên group không áp dụng cho một session đang chạy.

kvm: Device or resource busy khi QEMU khởi động. Một hypervisor module khác đang giữ CPU: hãy chạy lsmod, tìm vboxdrv hoặc VMware modules bên cạnh kvm_intel, và unload module bạn không muốn.

/var/run/libvirt/libvirt-sock: No such file or directory từ virsh. Daemon đã sập: sudo systemctl enable --now libvirtd.

Proxmox: KVM virtualisation configured, but not available. Một guest đã tick chọn KVM acceleration trên một host không thể cung cấp nó. Hãy sửa lỗi nesting, hoặc bỏ tick và chấp nhận emulation.

Android emulator: x86_64 emulation currently requires hardware acceleration! lại là /dev/kvm — thường là lỗi group.

Không có lỗi nào cả, nhưng mọi thứ cực kỳ chậm. QEMU khi không có accelerator flag sẽ fallback về TCG, trình emulated bằng phần mềm của nó. Nó chạy đúng nhưng rất chậm — một quá trình boot tính bằng giây sẽ trở thành tính bằng phút. Hãy pass -accel kvm một cách tường minh, để QEMU dừng lại với một lỗi thay vì âm thầm emulating.

Một guest biến mất giữa chừng khi đang chạy. Hãy kiểm tra dmesg để tìm Out of memory: Killed process ... qemu-system-x86_64. Một guest L2 thực chất là một process trên L1, và OOM killer xử lý nó như bất kỳ process nào khác. RAM của L2 lấy từ allocation cố định của L1 — không có chuyện mượn thêm từ host.

Vận hành: backup, nâng cấp, giới hạn

Backup. Copy file qcow2 của một guest đang chạy sẽ cho bạn một image bị lỗi. Hoặc là dùng virsh shutdown guest1 rồi copy, hoặc lấy một external snapshot (virsh snapshot-create-as guest1 snap1 --disk-only --atomic) để các thao tác write được chuyển hướng vào một overlay trong khi bạn copy base đang đứng yên, sau đó gộp nó lại bằng virsh blockcommit. Hãy chuyển các bản copy ra khỏi VPS — một snapshot nằm trên cùng một disk thì không bảo vệ được gì cả.

Nâng cấp. apt full-upgrade sẽ cài đặt các module kvm_intel/kvm_amd mới, nhưng kernel đang chạy vẫn giữ các module cũ cho đến khi bạn reboot. Hãy giữ kernel cũ đã cài sẵn và chạy lại kvm-ok sau mỗi lần thay đổi kernel: một host quay lại mà không có vmx thì chỉ cách việc hoạt động bình thường đúng một lần boot nữa thôi.

Giới hạn mở rộng. Một IP public có nghĩa là mọi dịch vụ L2 đều tiếp cận thế giới thông qua một proxy hoặc một rule DNAT trên L1. Live migration không có trong menu. Dưới áp lực CPU, đường dẫn nested exit là thứ đầu tiên bị ảnh hưởng. Và một hypervisor với nhiều guest là một máy mà bạn đã dùng hết RAM — các VM lồng nhau không thể overcommit để thoát khỏi một allocation cố định. Khi một lab vượt quá giới hạn đó, câu trả lời không phải là một stack lồng nhau cao hơn; mà là một máy dedicated nơi bạn là L0 và không có điều gì trong số này áp dụng cả.

FAQ

Tôi có cần nested virtualization để chạy Docker trên VPS không?

Không. Các container dùng chung kernel của VPS và không bao giờ mở /dev/kvm, vì vậy một instance bình thường không có flag vmx hay svm vẫn chạy Docker và Docker Compose bình thường. Nesting chỉ quan trọng khi bạn muốn một kernel thứ hai: một lab Proxmox, một guest Windows, Firecracker microVMs, trình giả lập Android, hoặc các CI runners boot các image VM.

Làm thế nào để kiểm tra xem VPS của tôi có hỗ trợ nested virtualization không?

Chạy grep -o -E 'vmx|svm' /proc/cpuinfo | sort -u, sau đó chạy kvm-ok từ package cpu-checker. Một instance khả dụng sẽ in ra vmx (Intel) hoặc svm (AMD), kvm-ok báo cáo KVM acceleration can be used, và /dev/kvm tồn tại với group kvm và mode 660. Hãy bỏ qua /sys/module/kvm_intel/parameters/nested cho câu hỏi này — file đó mô tả module KVM của chính bạn, không phải những gì hypervisor của nhà cung cấp đã expose cho bạn.

Tại sao hầu hết các nhà cung cấp VPS đều tắt nested virtualization?

Expose vmx đồng nghĩa với việc cấp cho guest một CPU model có mang flag, và một guest phụ thuộc vào các tính năng CPU đó sẽ không thể được live-migrate sang một máy có CPU thiếu chúng — một nhà cung cấp thực hiện drain node bằng cách di chuyển khách hàng sẽ phải từ bỏ tính năng này. Các đường dẫn code VMX/SVM lồng nhau cũng có một lịch sử CVE dài. Một số host vẫn bật nó theo từng VM khi có yêu cầu, và một số khác liệt kê nesting như một tính năng của gói dịch vụ.

VM lồng của tôi không có mạng trên public bridge. Vấn đề là gì?

Switch của nhà cung cấp sẽ drop các frame từ một địa chỉ MAC mà họ chưa bao giờ cấp cho bạn, vì vậy một guest L2 được bridge lên NIC public sẽ gửi ARP và không nghe thấy gì phản hồi. Đừng debug br0 nữa — hãy dùng mạng NAT default của libvirt (virbr0, 192.168.122.0/24), cấp cho guest một static lease, và publish bất kỳ thứ gì public thông qua một reverse proxy hoặc rule DNAT ngay trên chính VPS.

Một VM lồng chậm hơn bao nhiêu?

Chi phí nằm ở các VM exits, không phải ở memory access. Với EPT/NPT đang hoạt động, các thao tác đọc và ghi thông thường bên trong L2 chạy ở tốc độ phần cứng, trong khi I/O, timer interrupts, MMIO và IPIs được xử lý bởi L0 và có thể bị đẩy ngược lại qua L1. Các tác vụ nặng về CPU trên dữ liệu đã có sẵn trong RAM sẽ trông gần như native; các workload nặng về syscall, packet và disk sẽ cảm nhận rõ từng lớp. Hãy dùng virtio devices ở mọi nơi và cache=none trên guest disk, sau đó tự đo workload của bạn.

#nested-virtualization#kvm#proxmox#vps#qemu#libvirt