Virtualización anidada en VPS: ¿puedes usar Proxmox?
Comprueba en un minuto si tu VPS expone vmx o svm con kvm-ok. Si no aparece, verás errores de KVM y no podrás ejecutar invitados KVM o Proxmox.
La respuesta breve
La virtualización anidada consiste en ejecutar un hipervisor dentro de una máquina virtual: su VPS ya es un invitado y quiere que aloje sus propios invitados. Sólo funciona cuando el hipervisor del proveedor expone deliberadamente las extensiones de virtualización de la CPU a su instancia. Compruebe /proc/cpuinfo para buscar la marca vmx (Intel) o svm (AMD). Si no aparece ninguna, ninguna configuración dentro del VPS solucionará el problema.
Primero, una aclaración importante: Docker no necesita nada de esto. Los contenedores comparten el kernel de su VPS y nunca acceden a /dev/kvm. Si el objetivo real es «ejecutar varios servicios en contenedores en mi servidor», ya dispone de lo necesario. La virtualización anidada es relevante cuando necesita un segundo kernel, un laboratorio de Proxmox, un invitado Windows, microVM de Firecracker, un emulador de Android, un entorno de pruebas de Kubernetes con máquinas virtuales reales o ejecutores de CI que arrancan imágenes de máquinas virtuales.
Qué se está anidando realmente
Hay tres capas:
- L0, el hipervisor del proveedor, en el servidor físico. No tiene acceso a él.
- L1, su VPS. Para L0, sólo es un guest.
- L2, la VM que quiere ejecutar dentro de su VPS.
La virtualización asistida por hardware usa VT-x (el indicador vmx) y EPT en Intel, y AMD-V / SVM (svm) junto con RVI/NPT en AMD. Un hipervisor usa esas instrucciones para entrar en modo guest y permitir que la CPU recorra dos tablas de páginas a la vez.
Ninguna de las dos tecnologías se diseñó para ejecutarse de forma reentrante, por lo que la anidación se emula: cuando L1 ejecuta una instrucción VMX como VMLAUNCH o VMRESUME, la ejecución pasa a L0, que mantiene en nombre de L1 las estructuras auxiliares de L2. En las CPU con VMCS shadowing, las operaciones VMREAD y VMWRITE de L1 pueden atenderse sin una salida, lo que elimina gran parte de ese tráfico, pero no todo. KVM lo hace bien, pero es L0 quien realiza trabajo adicional en cada salida. Por eso el proveedor debe habilitar esta función.
Cuando L0 es KVM, deben cumplirse ambas condiciones para que una L2 use aceleración:
- El módulo KVM de L0 debe estar cargado con
nested=1. - L0 debe proporcionar a su VPS un modelo de CPU que incluya el indicador:
<cpu mode='host-passthrough'/>en libvirt,cpu: hosten Proxmox y-cpu hosten QEMU sin procesar. Un modelo emulado genérico (qemu64,kvm64) ocultavmxaunque la anidación esté habilitada globalmente.
Los demás hipervisores tienen su propio mecanismo. Hyper-V, por ejemplo, emula las extensiones de virtualización para un hipervisor anidado dentro de sus VM, pero sólo en las VM donde la anidación se haya habilitado de forma individual.
Compruebe su VPS en un minuto
# 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/kvmUna instancia operativa muestra vmx o svm, kvm-ok indica KVM acceleration can be used y /dev/kvm existe con el modo root:kvm 660. Si el indicador está presente pero el nodo de dispositivo no existe, cargue el módulo manualmente y consulte el registro del kernel:
sudo modprobe kvm_intel # or kvm_amd
sudo dmesg | tail -n 20Hay un archivo que se cita constantemente y que se interpreta mal con frecuencia:
cat /sys/module/kvm_intel/parameters/nested # Y or NDentro de su VPS, ese archivo contiene la configuración de su módulo KVM y determina si un invitado L2 puede anidar un tercer nivel. No indica si L0 habilitó el anidamiento para usted; /proc/cpuinfo y kvm-ok responden a esa pregunta. El parámetro nested es el ajuste que configura en una máquina que posee directamente:
echo 'options kvm_intel nested=1' | sudo tee /etc/modprobe.d/kvm-nested.conf
sudo modprobe -r kvm_intel && sudo modprobe kvm_intelLa eliminación del módulo se rechaza mientras haya una VM en ejecución, así que apague primero las máquinas virtuales. Si esa máquina es un host de Proxmox, activar la virtualización anidada en Proxmox VE 9 cubre el mismo cambio en modprobe.d y también el ajuste cpu: host por VM que hace visible el indicador dentro de una máquina virtual.
Por qué la mayoría de los proveedores de VPS lo mantienen desactivado
- Migración en vivo. Proporcionarle
vmximplica exponer un modelo de CPU que incluye esa marca, y un guest que depende de esas funciones de CPU no se puede migrar de forma segura a una máquina cuya CPU no las admite. Un proveedor que evacúa nodos mediante la migración de clientes pierde esa capacidad en cuanto habilita la virtualización anidada. - Superficie de ataque. Las rutas VMX/SVM anidadas se encuentran entre las partes más complejas del código de la capa de virtualización del kernel, y su historial de CVE lo refleja.
- L0 puede no ser KVM. Si
systemd-detect-virtmuestravmware,xenomicrosoft, las reglas de virtualización anidada corresponden a esa pila, no a KVM.
¿La instancia no muestra la marca? Consulte al soporte; algunos proveedores la habilitan por VM. También puede elegir un plan que documente la compatibilidad con virtualización anidada o pasar a un servidor dedicado. El resto de esta guía presupone que tiene root en una máquina que muestra la marca.
Ejecución de un invitado L2 con 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'No se necesita una sesión gráfica. La instalación serie tarda un tiempo, así que iníciela dentro de un shell persistente: el mismo flujo de trabajo de tmux que mantiene activas las sesiones de Claude Code en un VPS mantiene una consola virt-install conectada aunque se interrumpa la conexión SSH. Si se rechaza --os-variant debian13, su osinfo-db es anterior a la versión que lo introdujo; ejecute osinfo-query os y elija un nombre existente. --cpu host-passthrough reenvía vmx a L2, y sólo es necesario si L2 también debe ejecutar virtualización. Prepare el invitado para arrancar de forma segura con virsh autostart guest1.
El bus virtio del disco y la NIC no es un detalle meramente estético: los dispositivos IDE y e1000 emulados provocan muchas más salidas al hipervisor que las colas virtio y, con la virtualización anidada, una salida que L0 no puede completar por sí solo se refleja en L1. Allí, su gestión puede provocar más salidas adicionales.
Redes: la parte que los tutoriales omiten
Tu VPS tiene una IP pública y se encuentra detrás de una infraestructura que filtra las direcciones MAC desconocidas. De aquí se derivan dos consecuencias.
El bridging de invitados L2 en la red pública normalmente no funcionará. Coloca br0 en la NIC pública, asigna al invitado su propia MAC y verás que salen solicitudes ARP, pero no vuelve ninguna respuesta: el switch del proveedor descarta las tramas de una MAC que nunca te asignó. Si ese es el síntoma, deja de depurar el bridge; este es el mecanismo.
Usa la red NAT. libvirt incluye default: virbr0, 192.168.122.0/24, concesiones de dnsmasq y conectividad saliente inmediata. Para las conexiones entrantes, termina TLS en L1 y usa un proxy hacia dentro. Las rutas de certificados siguientes proceden de emitir un certificado de Let's Encrypt con Certbot en 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;
}
}Asigna primero una concesión estática al invitado (virsh net-edit default) para que la dirección de proxy_pass no cambie.
Las interfaces de administración deben permanecer fuera de Internet: VNC en 5900 y la interfaz web de Proxmox en 8006 deben estar vinculados a loopback y se deben alcanzar mediante un túnel SSH (ssh -N -L 8006:127.0.0.1:8006 you@your-vps) o a través de una VPN WireGuard autohospedada hacia el VPS, que coloca todo el rango de invitados 192.168.122.0/24 a un salto privado de distancia. Mantén el firewall restringido, sudo ufw allow 22,80,443/tcp, y no permitas nada más. Si los invitados pierden la conectividad saliente justo después de habilitar ufw, la causa habitual es DEFAULT_FORWARD_POLICY="DROP" en /etc/default/ufw. Establécelo en ACCEPT y recarga ufw.
Proxmox en un VPS
Proxmox VE 9 se basa en Debian 13, por lo que se instala en un VPS con Debian mediante la adición del repositorio pve-no-subscription y el paquete proxmox-ve. Tome las líneas del repositorio y del keyring de la documentación actual del propio Proxmox. Una URL copiada de una publicación antigua de blog puede interrumpir la instalación. Conviene decidir antes si Proxmox tiene sentido en hardware alquilado. Así evitará dedicar una tarde a configurar la red y después descubrir que la opción no es adecuada. La comparación de costes y capacidades entre un equipo Proxmox en casa y un VPS alquilado responde a esa cuestión con los cálculos de consumo eléctrico y hardware ya realizados.
Los paquetes no son la parte difícil. Proxmox espera que vmbr0 esté asociado mediante un bridge a una NIC física, lo que lleva directamente al bloqueo causado por el filtrado de MAC descrito arriba. La configuración que funciona en un VPS usa un vmbr0 con NAT o enrutado, sin ningún puerto físico asociado, los invitados en un rango privado y reglas DNAT o un reverse proxy en el host para los servicios públicos. Cuando los servicios públicos se ejecutan en contenedores en lugar de máquinas virtuales, Traefik delante de varias aplicaciones desde un solo archivo Docker Compose cubre la misma función de enrutamiento con certificados automáticos. Cree primero una snapshot de /etc/network/interfaces: una definición incorrecta del bridge puede bloquear el acceso a una máquina cuya consola quizá no esté disponible.
Rendimiento, expresado con precisión
El anidamiento es más lento que el uso de un solo nivel, y el mecanismo es específico, no difuso: el coste recae en las salidas y en la traducción de direcciones, no en las instrucciones ordinarias. Con EPT/NPT disponible, L0 combina las tablas de páginas de L1 para L2 y las suyas propias en una sola tabla shadow, por lo que un acierto en la TLB se ejecuta a la velocidad del hardware. Un fallo en la TLB cuesta más: el hardware recorre conjuntamente la tabla de páginas del guest y la tabla shadow, y cada cambio que L1 hace en sus propias tablas provoca una salida para que L0 pueda resincronizar la tabla shadow. Lo que resulta caro es cada operación que abandona el modo guest: E/S, interrupciones del temporizador, MMIO e interrupciones entre procesadores, porque una salida de L2 la gestiona L0 y puede reflejarse de vuelta a través de L1. El trabajo limitado por CPU sobre un conjunto de trabajo pequeño ofrece un rendimiento cercano al nativo; los conjuntos de trabajo grandes en memoria pagan el coste de los fallos en la TLB, y cualquier carga dominada por llamadas al sistema, paquetes y E/S de disco refleja el efecto de las capas.
Por tanto: dispositivos virtio en todas partes. Además, el archivo qcow2 reside en un disco que el proveedor ya ha virtualizado: hay dos capas de aprovisionamiento ligero apiladas, y cache=none en el disco del guest evita que los mismos bloques permanezcan simultáneamente en dos cachés de páginas. Aquí no se incluyen cifras de referencia: mida su propia carga en su propia instancia.
Modos de fallo y cadenas que verá
INFO: /dev/kvm does not exist / KVM acceleration can NOT be used de kvm-ok. El módulo no está cargado o la opción no está expuesta. Compruebe primero /proc/cpuinfo.
kvm: disabled by bios en dmesg. En un servidor físico, active la opción VT-x/SVM en el firmware. Dentro de una VPS, significa que L0 no le proporciona las extensiones. Ningún comando ejecutado en el guest puede cambiarlo.
modprobe: ERROR: could not insert 'kvm_intel': Operation not supported. La CPU que detecta el kernel no tiene vmx. De nuevo, es una decisión de L0.
Could not access KVM kernel module: Permission denied. El problema son los permisos, no el hardware. ls -l /dev/kvm debería mostrar el grupo kvm y el modo 660. Añádase a ese grupo e inicie un shell de inicio de sesión nuevo, porque la pertenencia al grupo no se aplica a una sesión que ya está en ejecución.
kvm: Device or resource busy al iniciar QEMU. Otro módulo de hipervisor está usando la CPU: ejecute lsmod, busque vboxdrv o módulos de VMware junto a kvm_intel y descargue el que no quiera usar.
/var/run/libvirt/libvirt-sock: No such file or directory de virsh. El daemon está detenido: sudo systemctl enable --now libvirtd.
Proxmox: KVM virtualisation configured, but not available. Un guest tiene activada la aceleración KVM en un host que no puede proporcionarla. Corrija la virtualización anidada o desactive la opción y acepte la emulación.
Emulador de Android: x86_64 emulation currently requires hardware acceleration! De nuevo, /dev/kvm, normalmente por el caso del grupo.
No aparece ningún error y todo funciona muy lento. QEMU, si no recibe ninguna opción de aceleración, recurre a TCG, su emulador de software. Funciona correctamente, pero es lento: un arranque que se mide en segundos pasa a medirse en minutos. Pase -accel kvm explícitamente para que QEMU se detenga con un error en lugar de emular silenciosamente.
Un guest desaparece durante la ejecución. Busque Out of memory: Killed process ... qemu-system-x86_64 en dmesg. Un guest L2 es un proceso en L1, y el OOM killer lo trata como a cualquier otro proceso. La RAM de L2 sale de la asignación fija de L1; no puede tomarla prestada del host.
Operación: copias de seguridad, actualizaciones y límites
Copias de seguridad. Copiar el archivo qcow2 de un guest en ejecución puede producir una imagen incoherente, porque el guest sigue escribiendo mientras se lee el archivo. Ejecute virsh shutdown guest1, espere hasta que virsh domstate guest1 informe de shut off (el comando de apagado puede devolver el control mientras el guest todavía se está deteniendo) y después copie el archivo. Otra opción es crear una instantánea externa (virsh snapshot-create-as guest1 snap1 --disk-only --atomic), de modo que las escrituras se desvíen a una capa superpuesta mientras copia la base, que ya no cambia; después, integre los cambios con virsh blockcommit guest1 vda --active --pivot. Transfiera las copias fuera del VPS. Una instantánea en el mismo disco no protege frente a ningún fallo del disco.
Actualizaciones. apt full-upgrade instala módulos nuevos de kvm_intel/kvm_amd, pero el kernel en ejecución sigue usando los antiguos hasta que reinicie. Mantenga instalado el kernel anterior y vuelva a ejecutar kvm-ok después de cada cambio del kernel: si el host vuelve a arrancar sin vmx, podrá recuperar el funcionamiento seleccionando otra entrada de arranque.
Cuándo deja de escalar. Una sola IP pública implica que todos los servicios L2 llegan al exterior a través de un proxy o de una regla DNAT en L1. La migración en vivo no es una opción. Cuando hay contención de CPU, la ruta de salida anidada es la primera que lo acusa. Además, un hypervisor con varios guests es una máquina cuya RAM ya ha sido asignada; las VM anidadas no pueden resolver una asignación fija mediante overcommit. Cuando un laboratorio supera ese límite, la solución no es añadir otra capa anidada, sino usar un equipo dedicado en el que usted sea L0 y nada de esto se aplique.
FAQ
¿Necesito virtualización anidada para ejecutar Docker en un VPS?
No. Los contenedores comparten el kernel de su VPS y nunca abren /dev/kvm, por lo que una instancia normal sin el indicador vmx ni svm ejecuta Docker y Docker Compose sin problemas. La virtualización anidada sólo es necesaria cuando quiere un segundo kernel: un laboratorio de Proxmox, un invitado de Windows, microVM de Firecracker, un emulador de Android o ejecutores de CI que arrancan imágenes de VM.
¿Cómo compruebo si mi VPS admite virtualización anidada?
Ejecute grep -o -E 'vmx|svm' /proc/cpuinfo | sort -u y después kvm-ok del paquete cpu-checker. Una instancia utilizable muestra vmx (Intel) o svm (AMD), kvm-ok informa de KVM acceleration can be used y /dev/kvm existe con el grupo kvm y el modo 660. Ignore /sys/module/kvm_intel/parameters/nested en esta comprobación. Ese archivo describe su propio módulo KVM, no lo que el hipervisor del proveedor expuso.
¿Por qué la mayoría de los proveedores de VPS deshabilitan la virtualización anidada?
Exponer vmx implica proporcionar al invitado un modelo de CPU que incluye ese indicador. Un invitado que depende de esas funciones de CPU no se puede migrar en caliente a una máquina cuya CPU no las admita. Un proveedor que evacúa nodos moviendo clientes entre máquinas renuncia a esa flexibilidad. Las rutas de código VMX/SVM anidadas también tienen un historial extenso de CVE. Algunos hosts aún la habilitan por VM previa solicitud. Otros documentan la virtualización anidada como una función del plan.
Mi VM anidada no tiene red en el puente público. ¿Qué ocurre?
El switch del proveedor descarta las tramas de una dirección MAC que nunca le asignó. Por eso, un invitado L2 conectado en puente a la NIC pública envía ARP y no recibe ninguna respuesta. Deje de depurar br0. Use la red NAT de libvirt default (virbr0, 192.168.122.0/24), asigne al invitado una concesión estática y publique los servicios externos mediante un reverse proxy o una regla DNAT en el propio VPS.
¿Cuánto más lenta es una VM anidada?
El coste se concentra en las salidas de la VM y en la traducción de direcciones. Con EPT/NPT activo, las instrucciones y los aciertos de TLB dentro de L2 se ejecutan a velocidad de hardware. Sin embargo, un fallo de TLB recorre tablas de páginas adicionales, y L0 gestiona la E/S, las interrupciones del temporizador, MMIO y las IPI, que pueden tener que volver a pasar por L1. Las cargas limitadas por CPU y con un conjunto de trabajo pequeño ofrecen un rendimiento cercano al nativo. Los conjuntos de trabajo grandes en memoria y las cargas intensivas en llamadas al sistema, paquetes o disco reflejan el coste de cada capa. Use dispositivos virtio en todas partes y cache=none en los discos del invitado. Después, mida su propia carga de trabajo.