VPS fit run Proxmox with nested virtualization?
Most VPS providers hide the vmx flag. Run kvm-ok in one minute, then see whether your VPS fit host KVM or Proxmox guests and the exact errors to expect.
Di short answer
Nested virtualization na when hypervisor dey run inside virtual machine: your VPS don already be guest, and you want make e host im own guests. E go work only when your provider hypervisor deliberately expose CPU virtualization extensions to your instance. Check /proc/cpuinfo for vmx flag (Intel) or svm (AMD). If none of dem show, nothing wey you configure inside VPS go fix am.
Make we set one expectation first: Docker no need any of dis things. Containers dey share your VPS kernel and dem no ever touch /dev/kvm. If di real goal na "run several services inside containers for my server", you already get wetin you need. Nesting matter when you want second kernel, Proxmox lab, Windows guest, Firecracker microVMs, Android emulator, Kubernetes testbed of real VMs, or CI runners wey boot VM images.
Wetin actually dey nested
Three layers:
- L0, provider hypervisor, for the physical machine. You no get access to am.
- L1, your VPS. To L0, na just guest.
- L2, the VM wey you wan run inside your VPS.
Hardware virtualization na VT-x (the vmx flag) plus EPT for Intel, AMD-V / SVM (svm) plus RVI/NPT for AMD. Hypervisor dey use those instructions enter guest mode and allow CPU walk two page tables at the same time.
Dem no design either one to work re-entrantly, so nesting dey emulated: when L1 execute VMX instruction, e dey trap go L0. L0 then maintain the shadow structures for L2 on behalf of L1. KVM dey handle this well, but na L0 dey do extra work for every exit. Na why provider need opt in.
Two conditions must hold before accelerated L2 fit work:
- L0's KVM module must load with
nested=1. - L0 must give your VPS CPU model wey carry the flag:
<cpu mode='host-passthrough'/>for libvirt,cpu: hostfor Proxmox, and-cpu hostfor raw QEMU. Generic emulated model (qemu64,kvm64) dey hidevmxeven when nesting dey enabled globally.
Check your VPS for one minute
# 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/kvmA usable instance suppose e print vmx or svm, kvm-ok dey show KVM acceleration can be used, and /dev/kvm dey exist with root:kvm mode 660. If the flag dey but device node no dey, load the module by hand and read kernel log:
sudo modprobe kvm_intel # or kvm_amd
sudo dmesg | tail -n 20One file dey get quoted plenty times, and people dey often misread am:
cat /sys/module/kvm_intel/parameters/nested # Y or NInside your VPS, na setting for your KVM module be that. E control whether an L2 guest fit nest one third level. E no talk anything about whether L0 enable nesting for you. /proc/cpuinfo and kvm-ok answer that question. The nested parameter na the setting wey you fit change for machine wey belong to you completely:
echo 'options kvm_intel nested=1' | sudo tee /etc/modprobe.d/kvm-nested.conf
sudo modprobe -r kvm_intel && sudo modprobe kvm_intelSystem no go allow module removal while VM dey run, so shut down guests first.
Why most VPS hosts dey leave am off
- Live migration. To give you
vmxmean say dem expose CPU model wey carry the flag. Guest wey depend on those CPU features no fit migrate safely go machine wey CPU no get dem. Host wey dey drain nodes by migrating customers go lose that option once e enable nesting. - Attack surface. The nested VMX/SVM paths dey among the most complex code for kernel virtualization layer, and CVE history dey show the risk.
- L0 fit no be KVM. If
systemd-detect-virtprintsvmware,xenormicrosoft, na that stack own nesting rules, no be KVM own.
Your instance no get the flag? Ask support, because some providers dey enable am per-VM. You fit choose plan wey document nesting, or move go dedicated box. The remaining steps assume say you get root for machine wey dey show the flag.
libvirt dey run one 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'You no need graphical session. Serial install fit take some time, so start am inside persistent shell: the same tmux workflow wey dey keep Claude Code sessions alive for VPS dey keep one virt-install console attached even if SSH connection drop. If --os-variant debian13 reject, your osinfo-db old pass the release, run osinfo-query os and choose name wey dey exist. --cpu host-passthrough dey forward vmx go inside L2, and you only need am if L2 must virtualize another layer. Use virsh autostart guest1 make the guest fit boot safely.
The virtio bus for disk and NIC no be decoration: emulated IDE and e1000 devices dey trap into the hypervisor much more often than virtio queues, and with nesting, system dey pay for every trap twice.
Networking: di part wey tutorials dey skip
Your VPS get one public IP and e dey behind one network fabric wey dey filter unknown MAC addresses. Two things go follow.
Bridging L2 guests go public network usually no go work. Put br0 for the public NIC, give the guest im own MAC, and you go see ARP go out but nothing come back. Provider switch dey drop frames from MAC wey e never lease give you. If na this you dey see, stop debugging the bridge; na so the mechanism dey work.
Use the NAT network instead. libvirt ships default: virbr0, 192.168.122.0/24, dnsmasq leases, and outbound connectivity dey work immediately. For inbound traffic, terminate TLS for L1 and proxy am inside. The certificate paths below come from 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;
}
}Give the guest static lease first (virsh net-edit default), so the address inside that proxy_pass no go change.
Keep management interfaces off the internet: VNC for 5900 and the Proxmox web UI for 8006 suppose dey on loopback. Reach dem through SSH tunnel (ssh -N -L 8006:127.0.0.1:8006 you@your-vps) or through a self-hosted WireGuard VPN into the VPS, wey go put the whole 192.168.122.0/24 guest range one private hop away. Keep the firewall narrow, sudo ufw allow 22,80,443/tcp, nothing else. If guests lose outbound connectivity immediately after you enable ufw, the usual cause na DEFAULT_FORWARD_POLICY="DROP" inside /etc/default/ufw. Set am to ACCEPT and reload ufw.
Proxmox for VPS
Proxmox VE 9 na Debian 13 underneath, so e dey install for Debian VPS by adding pve-no-subscription repository and proxmox-ve package. Use the repository and keyring lines from Proxmox current documentation. URL wey you copy from old blog post fit make the installation fail. Before you spend evening on the networking wey dey below, decide whether Proxmox make sense at all for rented hardware. the cost and capability comparison between Proxmox box for house and rented VPS na the version of this question wey don already do the power and hardware calculation.
The packages no be the hard part. Proxmox expect vmbr0 to bridge to physical NIC, and this enter the MAC-filtering problem wey we mention above. The setup wey dey work for VPS na NAT'd or routed vmbr0 without physical port attached. Guests dey for private range, while DNAT rules or reverse proxy for the host handle anything wey public. If the public-facing services na containers instead of VMs, Traefik wey dey front multiple apps from one Docker Compose file handle the same routing work with automatic certificates. Take snapshot of /etc/network/interfaces first. Bad bridge definition fit lock you out of machine wey you fit no get console access to.
Performance, as e really be
Nested virtualization dey slower than single-level virtualization, and the reason clear: memory access no be where the cost dey; exits na where the cost dey. When EPT/NPT dey available, L0 dey maintain shadow page tables for L2, and hardware dey handle normal memory reads at full speed. The expensive part na every operation wey comot from guest mode: I/O, timer interrupts, MMIO, and inter-processor interrupts. L0 dey handle L2 exit, and e fit reflect am back through L1. CPU-bound work wey dey use data already dey RAM dey perform almost like native. But work wey depend mainly on syscalls, packets, and disk I/O go feel all the virtualization layers.
So, use virtio devices everywhere. Your qcow2 file dey on disk wey provider don already virtualize. That mean two thin-provisioning layers dey on top each other, and cache=none for guest disk stop the same blocks from dey inside two page caches at the same time. We no put benchmark numbers here. Measure your own workload for your own instance.
Wahala wey fit happen, and strings wey you go see
INFO: /dev/kvm does not exist / KVM acceleration can NOT be used from kvm-ok. Either module no load, or flag no dey exposed. Check /proc/cpuinfo first.
kvm: disabled by bios for dmesg. For bare metal, change VT-x/SVM toggle for firmware. Inside VPS, e mean say L0 no dey give you the extensions, and nothing wey you type for guest go change that.
modprobe: ERROR: could not insert 'kvm_intel': Operation not supported. CPU wey your kernel dey see no get vmx, and na L0 decision again.
Could not access KVM kernel module: Permission denied. Na permissions cause am, no be hardware. ls -l /dev/kvm suppose show group kvm, mode 660; add yourself to that group and start fresh login shell, because group membership no apply to session wey don already dey run.
kvm: Device or resource busy when QEMU start. Another hypervisor module dey hold CPU: run lsmod, look for vboxdrv or VMware modules together with kvm_intel, then unload the one wey you no want.
/var/run/libvirt/libvirt-sock: No such file or directory from virsh. Daemon don stop: sudo systemctl enable --now libvirtd.
Proxmox: KVM virtualisation configured, but not available. Guest get KVM acceleration enabled for host wey no fit provide am. Fix nesting, or disable am and accept emulation.
Android emulator: x86_64 emulation currently requires hardware acceleration! /dev/kvm again, usually na group issue.
No error at all, and everything is glacial. QEMU wey no get accelerator flag go fall back to TCG, wey be software emulator. E correct, but e slow; boot wey suppose take seconds fit take minutes. Pass -accel kvm explicitly, so QEMU go stop with error instead of quietly doing emulation.
A guest vanishes mid-run. Check dmesg for Out of memory: Killed process ... qemu-system-x86_64. L2 guest na process for L1, and OOM killer dey treat am like any other process. L2 RAM dey come from L1 fixed allocation; e no fit borrow from host.
Operating am: backups, upgrades, limits
Backups. If you copy qcow2 for guest wey still dey run, image go corrupt. Either virsh shutdown guest1 and copy am, or take external snapshot (virsh snapshot-create-as guest1 snap1 --disk-only --atomic) so writes go divert enter overlay while you copy the base wey no dey change, then join am back with virsh blockcommit. Move the copies comot from VPS; snapshot wey dey the same disk no protect against anything.
Upgrades. apt full-upgrade dey install new kvm_intel/kvm_amd modules, but kernel wey dey run go still use the old ones until you reboot. Keep the previous kernel installed, then run kvm-ok again after every kernel change. If host come back without vmx, you fit restore am from one boot entry.
Where this stops scaling. One public IP mean say every L2 service dey reach the world through proxy or DNAT rule for L1. Live migration no dey available. When CPU contention happen, nested exit path na the first thing wey go feel am. Hypervisor wey get several guests na machine wey you don already use up the RAM for. Nested VMs no fit overcommit to escape fixed allocation. When lab pass this limit, answer no be to add another layer to the nested stack. Use dedicated box instead, where you be L0 and none of these limitations apply.
FAQ
Nesting virtualization dey necessary to run Docker for VPS?
No. Containers dey share your VPS kernel and dem no ever open /dev/kvm, so ordinary instance wey no get vmx or svm flag fit run Docker and Docker Compose well. Nesting only matter when you want another kernel: Proxmox lab, Windows guest, Firecracker microVMs, Android emulator, or CI runners wey dey boot VM images.
How I fit check whether my VPS support nested virtualization?
Run grep -o -E 'vmx|svm' /proc/cpuinfo | sort -u, then kvm-ok from cpu-checker package. Instance wey work go print vmx (Intel) or svm (AMD), kvm-ok go report KVM acceleration can be used, and /dev/kvm go dey with group kvm and mode 660. Ignore /sys/module/kvm_intel/parameters/nested for this question. That file describe your own KVM module, e no describe wetin provider hypervisor expose to you.
Why most VPS providers dey disable nested virtualization?
To expose vmx mean say guest go receive CPU model wey carry the flag. Guest wey depend on those CPU features no fit do live migration go machine wey CPU no get dem. Provider wey dey drain nodes by moving customers around go lose that ability. The nested VMX/SVM code paths too get long CVE history. Some hosts still enable am per-VM when you request am, while others document nesting as plan feature.
My nested VM no get network for public bridge. Wetin wrong?
Provider switch dey drop frames from MAC address wey e never lease to you. So L2 guest wey bridge onto public NIC dey send ARP but e no dey hear anything back. Stop debugging br0. Use libvirt NAT default network (virbr0, 192.168.122.0/24), give the guest static lease, then publish anything public through reverse proxy or DNAT rule for the VPS itself.
Nested VM slow reach how much?
The cost dey happen for VM exits, no be memory access. When EPT/NPT dey active, ordinary reads and writes inside L2 dey run at hardware speed. But L0 dey handle I/O, timer interrupts, MMIO and IPIs, and e fit bounce dem back through L1. CPU-bound work wey data already dey for RAM go near native speed. Workload wey heavy for syscalls, packets, or disk go feel every layer. Use virtio devices everywhere and cache=none for guest disks, then measure your own workload.