Problema

En entornos de laboratorio o homelab es frecuente crear una VM de Windows 11 Pro dentro de Proxmox y, a su vez, intentar ejecutar Docker (o contenedores Linux) dentro de esa VM. El síntoma típico es que la instalación de una distribución Linux (por ejemplo Ubuntu) falla, o Docker no arranca y muestra errores relacionados con la arquitectura, la falta de soporte de virtualización o la imposibilidad de crear cgroups. El problema no es exclusivo de una versión concreta; se manifiesta siempre que la capa de virtualización anidada no está preparada para exponer los recursos que Docker necesita.

Causa

  1. CPU flags no propagados – Proxmox necesita pasar los flags VT-x/AMD-V y, en el caso de Docker, también VT-d y EPT/NPT. Si la VM de Windows no recibe esos flags, el hipervisor interno (Hyper‑V o WSL2) no puede crear máquinas virtuales ligeras para los contenedores.

  2. Configuración de la VM – La opción “Nested virtualization” suele estar desactivada por defecto en la plantilla de Windows. Incluso cuando se marca, es necesario habilitar la característica de “Virtual Machine Platform” y, en algunos casos, “Windows Subsystem for Linux” (WSL) para que Docker Desktop funcione.

  3. Versión del kernel de Linux dentro de la VM – Cuando se intenta instalar Ubuntu como una sub‑VM (por ejemplo usando Hyper‑V o VirtualBox dentro de Windows), el kernel necesita los módulos kvm_intel/kvm_amd. Si el hipervisor anidado no los expone, la instalación se queda en bucle.

  4. Políticas de seguridad de Proxmox – El parámetro cpu: host o cpu: kvm64 influye en la exposición de extensiones. Un modelo genérico puede ocultar instrucciones críticas para la virtualización anidada.

  5. Configuración de red NAT vs. bridge – Docker crea interfaces docker0 y necesita acceso a la red del host. Si la VM está configurada solo con NAT sin reglas de reenvío, los contenedores no pueden comunicarse y la instalación parece “colgarse”.

Solución

1. Verificar y habilitar la virtualización anidada en Proxmox

En el nodo de Proxmox, abre una consola y ejecuta:

# Verifica que el procesador soporte VT‑x/AMD‑V
egrep -c '(vmx|svm)' /proc/cpuinfo
# Habilita la anidación a nivel de host (solo necesita hacerse una vez)
echo "options kvm-intel nested=Y" > /etc/modprobe.d/kvm-nested.conf
modprobe -r kvm_intel && modprobe kvm_intel
# Confirma que está activo
cat /sys/module/kvm_intel/parameters/nested

Si el resultado es Y, la capa de host está lista.

2. Configurar la VM de Windows 11

Edita la VM desde la GUI de Proxmox o con qm set:

qm set <VMID> --cpu host --flags +nesting
qm set <VMID> --machine q35

El flag host asegura que se pasen todos los flags de la CPU; nesting habilita la anidación explícita.

3. Activar características de Windows

Dentro de la VM de Windows 11:

  1. Abre Panel de control → Programas → Activar o desactivar características de Windows.
  2. Marca:
    • Virtual Machine Platform
    • Windows Subsystem for Linux
    • Hyper‑V (opcional, pero recomendado para Docker Desktop)
  3. Reinicia la máquina.

4. Instalar Docker Desktop o Docker Engine

  • Docker Desktop: descarga el instalador oficial, ejecuta y permite que habilite WSL 2 automáticamente. Si el instalador detecta que la virtualización está desactivada, mostrará un mensaje claro.
  • Docker Engine en Ubuntu (si prefieres una sub‑VM): crea una VM ligera con virt-manager o qemu-system-x86_64 dentro de Windows (Hyper‑V) y sigue la guía estándar de Docker para Ubuntu.

5. Ajustar la red

Si la VM usa NAT, añade una regla de reenvío en Proxmox:

iptables -t nat -A POSTROUTING -s 10.0.2.0/24 -o vmbr0 -j MASQUERADE

O cambia la interfaz a bridge en la configuración de la VM para que Docker obtenga una dirección IP directamente del segmento de red del host.

6. Comprobar módulos KVM dentro de la sub‑VM

Una vez que Ubuntu arranca, verifica:

lsmod | grep kvm

Si no aparecen kvm_intel o kvm_amd, revisa la configuración de la VM de Windows (Hyper‑V) y asegura que la opción “Enable nested virtualization” está activada en el gestor de Hyper‑V.

Cuándo aplicar esta solución

  • Síntomas: la instalación de Ubuntu dentro de Windows falla, Docker Desktop muestra “Virtualization is disabled”, o los contenedores no pueden iniciar por errores de cgroup.
  • Entorno: Proxmox como hipervisor principal, Windows 11 Pro como VM y Docker ejecutándose dentro de esa VM (ya sea vía Docker Desktop, WSL 2 o una sub‑VM Linux).
  • No aplica: si Docker se ejecuta directamente en el nodo Proxmox (sin Windows) o si la VM es de tipo Linux que ya tiene anidación habilitada por defecto.

Código

# Paso 1: habilitar anidación en el host
echo "options kvm-intel nested=Y" > /etc/modprobe.d/kvm-nested.conf
modprobe -r kvm_intel && modprobe kvm_intel

# Paso 2: configurar la VM en Proxmox
qm set 101 --cpu host --flags +nesting --machine q35

# Paso 3: regla NAT opcional
iptables -t nat -A POSTROUTING -s 10.0.2.0/24 -o vmbr0 -j MASQUERADE

Verificación

  1. En Proxmox, ejecuta cat /sys/module/kvm_intel/parameters/nested. Debe devolver Y.
  2. Dentro de Windows, abre PowerShell y corre systeminfo. Busca “Hyper-V Requirements: VM Monitor Mode Extensions: Yes”.
  3. Ejecuta docker version. La salida debe mostrar tanto el cliente como el servidor sin errores.
  4. Si usas Ubuntu como sub‑VM, docker run hello-world debe descargar la imagen y mostrar el mensaje de bienvenida.

Notas adicionales

  • Algunas CPUs Intel más antiguas no exponen EPT de forma estable bajo carga; en esos casos la única solución viable es evitar la anidación y ejecutar Docker directamente en el nodo Proxmox.
  • Cuando uses Hyper‑V, la opción “Enhanced Session Mode” puede interferir con la transmisión de dispositivos USB a la sub‑VM; desactívala si ves problemas de acceso a discos.
  • Mantén actualizado el firmware del servidor; versiones de BIOS antiguas pueden desactivar la extensión de virtualización sin notificarlo al sistema operativo host.