Migración a Proxmox VE desde VMware, Hyper-V y VirtualBox

Por: Artiko
proxmoxproxmox-vemigracionvmwareesxihyper-vvirtualboxqemu-imgvirtualizacionkvm

Migración a Proxmox VE desde VMware, Hyper-V y VirtualBox

Tienes un clúster de Proxmox VE 9.2 funcionando: storage decidido, red definida, backups programados y un runbook de operación como el del capítulo 15. Lo que todavía no tienes es la carga de trabajo. Sigue corriendo en otro hipervisor, en ESXi, en Hyper-V o en un puñado de VirtualBox repartidos por escritorios, y alguien tiene que moverla sin romper nada.

Ese traslado es donde se pierden fines de semana. No porque copiar un disco sea difícil, sino porque una VM es mucho más que su disco: es un firmware, un controlador de almacenamiento, un initramfs que solo carga los módulos que necesitaba en el hipervisor de origen, una MAC que estaba en una reserva DHCP y un agente de invitado que ya no existe. Migrar mal produce un INACCESSIBLE_BOOT_DEVICE en Windows o un dracut: no root device found en Linux, y a esas alturas la VM de origen ya está apagada y la ventana de mantenimiento corriendo.

Este capítulo cubre los cuatro caminos reales para traer VMs a Proxmox VE, con los comandos exactos: el importador nativo desde ESXi, la exportación OVF/OVA, la importación de discos sueltos y el método de mínimo downtime. Y cubre lo que va antes y después de la copia, que es donde de verdad se decide si el huésped arranca.

El contexto: qué cambió con Broadcom y qué se mueve de verdad

La ola de migraciones de 2024-2026 tiene una causa concreta. Estos son los hechos que la sostienen, marcados explícitamente como fuentes secundarias: Broadcom no publica una lista de precios pública, así que cualquier cifra hay que presentarla como orden de magnitud reportado, no como precio oficial.

  • Broadcom cerró la adquisición de VMware y eliminó las licencias perpetuas. Todo pasó a suscripción.
  • Se pasó de precio por socket a precio por core, con un mínimo de 16 cores por CPU física: una CPU de 8 cores se factura como 16.
  • Desde el 10 de abril de 2025, el pedido mínimo subió de 16 a 72 cores por suscripción (The Register, 2025-03-28). Ese cambio golpea sobre todo a PyMEs, edge y entornos pequeños, que son precisamente los que no llegaban ni de lejos a 72 cores.

Lo que se está moviendo, según los reportes de canal, es SMB, mid-market, edge y cargas nuevas. La gran empresa sigue mayoritariamente en VMware. Conviene decirlo en voz alta antes de vender una migración: no todo el mundo tiene que migrar, y el que migra no ahorra lo que dice la calculadora de licencias.

Lo que la licencia no paga

El coste de licencia no es el coste total de migrar. Estas son las partidas que aparecen después y que casi nunca están en la hoja de cálculo inicial:

PartidaQué implica en la práctica
Reingeniería de storageVMFS y vSAN no existen en Proxmox VE. Hay que rediseñar sobre ZFS, Ceph o LVM, con otro modelo de snapshots y otro comportamiento de thin provisioning
Reescritura de automatizaciónTodo lo escrito en PowerCLI se tira. Se rehace sobre la API REST, Ansible o Terraform/OpenTofu
Formación del equipoProxmox VE es Debian. El equipo necesita soltura en Linux, systemd, apt y ZFS
Revalidación de backup y DRLos jobs, las retenciones y las pruebas de restauración se rehacen desde cero
Certificaciones ISVSoftware de terceros con soporte certificado solo sobre vSphere deja de estar certificado

Los dos primeros puntos son capítulos completos de este curso: el modelo de storage está en el capítulo 7 y la automatización en el capítulo 14. Si vas a presentar un caso de negocio, cuéntalos como trabajo, no como algo que “ya está resuelto”.

Inventario previo: qué documentar antes de tocar nada

Antes de la primera copia hay una tabla que tienes que llenar, VM por VM. No es burocracia: cada columna corresponde a una decisión que vas a tener que tomar en Proxmox VE, y si no la tomas antes, la vas a improvisar con la VM apagada.

Dato a documentarPor qué te va a hacer falta
Firmware del origen: BIOS legacy o UEFIDetermina bios=seabios con machine pc o bios=ovmf con machine q35 y efidisk0
Controlador de disco actualSi venía en LSI o PVSCSI, el huésped Windows no tiene el driver vioscsi cargado
Tamaño real usado frente a tamaño provisionadoqemu-img convert expande discos dinámicos al tamaño real; necesitas espacio de destino
IPs estáticas, gateway, DNS, VLANLa configuración de red del huésped no viaja sola y las interfaces se renombran
Direcciones MACLas MAC cambian. Toda reserva DHCP y todo filtro por MAC hay que actualizarlo
Presencia de vTPM y BitLockerEl vTPM no se migra. Con BitLocker activo y sin la clave de recuperación, pierdes la VM
Snapshots existentes en el origenLas VMs con snapshots se importan mucho más lento; conviene consolidarlos antes
Agente instalado: VMware Tools, Integration Services, Guest AdditionsHay que desinstalarlo antes de migrar
Datastore donde viven los discosSi están en vSAN, el importador nativo no los ve

Gotcha: el punto de las MAC es el que más incidencias genera y el más barato de evitar. Un servidor con IP por reserva DHCP arranca perfectamente en Proxmox VE, con red operativa, y sin embargo aparece con otra dirección. Nadie lo relaciona con la migración hasta media hora después.

El árbol de decisión: qué método usar

Hay cuatro caminos y no compiten entre sí: cada uno responde a una restricción distinta del origen.

flowchart TD
    A["VM en VMware que quieres mover"] --> B{"Host ESXi entre 6.5 y 8.0 alcanzable por API"}
    B -->|No| X["Exportar OVF u OVA con ovftool"]
    B -->|Si| C{"Discos en vSAN o cifrados por Storage Policy"}
    C -->|Si| Y["Mover los discos a otro datastore y quitar el cifrado"]
    Y --> B
    C -->|No| D{"Cuanto downtime puedes asumir"}
    D -->|"Ventana de mantenimiento completa"| E["Importador nativo sin live import"]
    D -->|"Solo unos minutos"| F["Importador nativo con live import"]
    D -->|"Casi cero y hay un share visible desde ambos"| G["Attach disk and move"]
    X --> H["qm importovf sobre un storage con content type import"]
    E --> Z["Post-migracion: CPU / SCSI / red / agente"]
    F --> Z
    G --> Z
    H --> Z

Fuera del mundo VMware el árbol es más corto: desde Hyper-V y VirtualBox no hay importador nativo, y el flujo es siempre convertir la imagen con qemu-img y adjuntarla con qm disk import.

El importador nativo: dar de alta un storage de tipo esxi

El importador existe desde Proxmox VE 8.2 y está implementado como plugin de storage. Ese detalle de diseño explica todo lo demás: al ser un storage, aparece en el árbol de recursos, se consulta con pvesm, se expone en la API y tiene integración nativa con la interfaz web sin ninguna herramienta externa. La referencia oficial es la wiki https://pve.proxmox.com/wiki/Migrate_to_Proxmox_VE.

Lo que hace el plugin es conectarse al host ESXi, listar sus VMs y exponerlas como contenido de tipo import. Los discos se ven a través de un montaje FUSE que el nodo levanta contra el datastore remoto.

Por interfaz web: Datacenter → Storage → Add → ESXi. Se introduce el dominio o la IP del host ESXi y las credenciales de una cuenta con permisos de administrador. Si el ESXi usa certificado autofirmado, o añades su CA al almacén de confianza del nodo, o marcas la casilla Skip Certificate Verification.

El equivalente por CLI:

# Dar de alta el host ESXi como storage de importacion
pvesm add esxi esxi-origen --server 192.168.1.50 --username root --password

# Si el ESXi tiene certificado autofirmado
pvesm set esxi-origen --skip-cert-verification 1

# Listar lo que el plugin ve
pvesm list esxi-origen

Advertencia: el nombre exacto del parámetro de omisión de certificado en pvesm puede variar entre versiones del plugin. En la interfaz la casilla existe con ese texto; para confirmar el nombre en tu instalación concreta usa la ayuda del propio comando en lugar de copiar la opción a ciegas:

pvesm help add --type esxi
pvesh usage /storage --verbose

El plugin necesita el paquete pve-esxi-import-tools instalado en el nodo. La herramienta interna que hace el listado es /usr/libexec/pve-esxi-import-tools/listvms.py; si el storage aparece vacío o en error, ejecutarla a mano es la forma más rápida de ver el mensaje real de la conexión.

Requisitos, versiones compatibles y limitaciones conocidas

Requisitos mínimos:

  • Proxmox VE 8 o superior, con las actualizaciones al día.
  • Una cuenta con permisos de administrador en el host ESXi.
  • Compatibilidad probada: ESXi 6.5 hasta 8.0.

Y ahora las limitaciones documentadas, que son las que deciden si este método sirve para tu caso:

LimitaciónConsecuencia y workaround
Discos en almacenamiento vSANEl importador no funciona. Hay que mover los discos a otro datastore antes de importar
Caracteres especiales en el nombre del datastoreUn datastore con + en el nombre puede hacer fallar la importación. Renombrar o usar otra ruta
VMs con snapshotsSe importan mucho más lento. Consolida los snapshots en el origen antes de empezar
Imágenes cifradas por Storage PolicyHay que quitar el cifrado antes de importar
vTPM cifradoNo se puede migrar. Hay que crear uno nuevo en el destino

El último punto es el que hay que revisar primero en entornos Windows: un vTPM cifrado en VMware combinado con BitLocker dentro del huésped es la receta exacta para un arranque que pide clave de recuperación en un servidor cuya clave nadie guardó.

Live import: cómo funciona y qué downtime deja

El live import es la opción que reduce el downtime a la ventana mínima, y conviene entender el mecanismo antes de usarlo porque tiene una contrapartida de rendimiento.

Proxmox VE trae primero los datos de disco críticos y el resto de forma asíncrona y bajo demanda. La VM arranca en el nodo cuando todavía falta la mayor parte de la imagen por copiar; cuando el huésped lee un bloque que aún no está en el destino, la lectura se resuelve contra el datastore remoto.

sequenceDiagram
    actor Admin
    participant PVE as Nodo Proxmox VE
    participant ESXi as Host ESXi
    Admin->>PVE: pvesm list esxi-origen
    PVE->>ESXi: listvms.py sobre la API
    ESXi-->>PVE: inventario de VMs y discos
    Admin->>ESXi: apagar la VM de origen
    Admin->>PVE: qm import con live-import 1
    PVE->>ESXi: leer los bloques criticos del disco
    PVE->>PVE: crear la config de la VM destino
    PVE->>PVE: arrancar la VM inmediatamente
    Note over PVE,ESXi: el huesped ya da servicio degradado
    PVE->>ESXi: copia asincrona del resto de bloques
    ESXi-->>PVE: bloques restantes bajo demanda
    Note over PVE: VM 100% en el storage local

Dos cosas que hay que tener claras:

Uno. La VM de origen debe apagarse en el lado ESXi. Proxmox VE arranca la imagen inmediatamente después. No es una migración en caliente al estilo vMotion: el downtime existe, es el tiempo entre el apagado en ESXi y el arranque en Proxmox VE.

Dos. El rendimiento se degrada durante la importación, y cuánto depende de la velocidad del storage de origen, del ancho de banda de red y de la carga del propio huésped. Una base de datos que lee de forma aleatoria por todo el disco es el peor candidato posible para un live import; un servidor web con un working set pequeño es el mejor.

Gotcha: nunca arranques la misma VM en Proxmox VE y en VMware a la vez. El aviso está literal en la documentación: “Never power on the same VM in both Proxmox VE or VMware simultaneously to avoid disk corruption.” Es especialmente fácil equivocarse cuando el live import está en curso y alguien “solo quiere comprobar algo” en el origen.

qm import desde el storage esxi con mapeo de hardware

El equivalente CLI del asistente es qm import. Su firma:

qm import <vmid> <source> --storage <string> [OPTIONS]

El source es una ruta dentro del storage de importación, con el formato <storage>:<inventario>/<datastore>/<carpeta>/<fichero>.vmx:

# Ver que hay disponible y con que ruta exacta
pvesm list esxi-origen

# Importar sin live import, convirtiendo a qcow2
qm import 300 esxi-origen:ha-datacenter/datastore1/WinSrv/WinSrv.vmx \
  --storage local-lvm \
  --format qcow2 \
  --live-import 0

Lo interesante de qm import es que acepta además opciones de configuración de la VM destino —CPU, memoria, red, cloud-init—, de modo que puedes mapear el hardware durante la propia importación en lugar de corregirlo después. Eso convierte la migración en una sola operación reproducible, que es justo lo que necesitas si vas a mover cincuenta VMs y no tres.

Un ejemplo con el mapeo hecho en el mismo comando:

qm import 300 esxi-origen:ha-datacenter/datastore1/WinSrv/WinSrv.vmx \
  --storage local-lvm \
  --format raw \
  --cores 4 --sockets 1 \
  --cpu x86-64-v2-AES \
  --memory 8192 \
  --scsihw virtio-scsi-single \
  --net0 virtio,bridge=vmbr0 \
  --agent enabled=1 \
  --live-import 0

Los nombres de bridge y el modelo de red dependen de cómo hayas montado la red del host; si todavía no la tienes definida, el capítulo 9 cubre bridges, VLAN y bonding antes de que empieces a importar.

Método manual A: exportar OVF/OVA e importar con qm importovf

Cuando el host ESXi no es alcanzable por API, cuando la versión queda fuera del rango probado o cuando lo que te entregan es directamente un fichero, el camino es OVF/OVA.

La exportación se hace desde una máquina con ovftool de VMware:

./ovftool vi://[email protected]/MiVM /export/path/

Y la importación en el nodo Proxmox VE:

qm importovf <vmid> <manifest> <storage> [--dryrun] [--format qcow2|raw|vmdk]
# Ver que interpretaria el importador sin crear nada
qm importovf 301 /export/path/MiVM/MiVM.ovf local-lvm --dryrun 1

# Importar de verdad
qm importovf 301 /export/path/MiVM/MiVM.ovf local-lvm --format qcow2

Ejecuta siempre el --dryrun primero. Te muestra cómo va a quedar la configuración interpretada del OVF sin escribir nada, y es la forma más barata de descubrir que el manifiesto declara una CPU o un tamaño de disco que no esperabas.

Dos detalles operativos importantes. Los OVA y OVF requieren un storage basado en ficheros con content type import habilitado; sin ese content type, el fichero no aparece como importable. Y los OVA se pueden subir directamente por la interfaz web al storage correspondiente, sin pasar por scp.

Lo que qm importovf no hace: añadir la tarjeta de red, ajustar el tipo de CPU y fijar el controlador SCSI adecuado. Todo eso queda para la fase de post-migración, y en Windows hay que cambiar temporalmente el bus del disco a IDE o SATA antes del primer arranque.

Método manual B: qm disk import de un VMDK suelto

Cuando lo único que tienes es la imagen de disco, el flujo es crear la VM vacía a mano y engancharle el disco.

qm disk import <vmid> <source> <storage> [--format qcow2|raw|vmdk] [--target-disk <bus>]
# El VMDK debe estar accesible desde el nodo: montaje NFS/CIFS, scp, disco USB...
qm create 302 --name migrada --memory 4096 --cores 2 \
  --net0 virtio,bridge=vmbr0 --scsihw virtio-scsi-single

qm disk import 302 /mnt/vmware/MiVM/MiVM.vmdk local-lvm --format qcow2

# El disco queda como unusedX: hay que engancharlo explicitamente
qm set 302 --scsi0 local-lvm:vm-302-disk-0,discard=on,ssd=1
qm set 302 --boot order=scsi0

La conversión de formato ocurre al vuelo, así que no hace falta pasar por qemu-img si el origen es un formato que QEMU entiende. El alias histórico qm importdisk sigue funcionando y hace lo mismo.

Gotcha del descriptor VMDK: un fichero .vmdk de VMware suele ser un descriptor de texto que apunta a un fichero de datos -flat.vmdk al lado. Si copias solo el .vmdk porque pesa dos kilobytes, la importación fallará o traerá una imagen vacía. Hay que copiar ambos ficheros. Compruébalo antes con head sobre el fichero: si ves texto plano con líneas RW ... FLAT ..., es un descriptor.

Nota sobre --target-disk: sin esa opción, el disco importado queda como unusedX y no está adjunto a ningún bus. Con ella, qm disk import lo engancha directamente al bus que le indiques. Para Windows migrado desde otro hipervisor conviene no usarla todavía y adjuntar primero en SATA, por la razón que se explica más abajo.

Método C: attach disk and move, el de mínimo downtime

Este es el método para cuando la ventana de mantenimiento es de minutos y no de horas. La idea es evitar la copia previa: la VM arranca en Proxmox VE leyendo el disco que sigue estando físicamente en el share de VMware, y la copia real se hace después, con la VM ya dando servicio.

Los pasos, en orden:

  1. Crear en Proxmox VE un storage de tipo Directory apuntando a un recurso de red accesible desde ambos hipervisores, con el content type Disk Image habilitado.
  2. Crear la VM destino en Proxmox VE con el disco de sistema en ese share, en formato VMDK.
  3. Copiar el VMDK de origen encima del que Proxmox VE generó.
  4. Editar el descriptor VMDK copiado para que apunte al fichero flat de origen con ruta relativa, del estilo ../../Server/Server-flat.vmdk.
  5. Apagar la VM de origen en VMware.
  6. Arrancar la VM en Proxmox VE.
  7. Con la VM corriendo, mover el disco al storage definitivo con Disk Action → Move Storage.

El downtime real es el del paso 5 al 6: apagar allí y arrancar aquí. Todo lo demás pasa con servicio activo.

Advertencia literal de la documentación: “Never power on the same VM in both Proxmox VE or VMware simultaneously to avoid disk corruption.” En este método el riesgo es máximo, porque el fichero flat es exactamente el mismo en ambos lados. Antes del paso 6, verifica en VMware que la VM está apagada de verdad, no suspendida.

El paso 7 usa el mismo mecanismo de move disk que cubrimos con el resto de operaciones de disco en el capítulo 3: copia en caliente y conmutación transparente al finalizar.

Preparación del huésped antes de migrar

Aquí es donde se gana o se pierde la migración. Casi todos los fallos de arranque post-migración se podían haber evitado con cinco minutos de trabajo dentro del huésped mientras aún estaba encendido en el hipervisor de origen.

flowchart TD
    A["VM encendida en el hipervisor de origen"] --> B["Desinstalar VMware Tools o Integration Services o Guest Additions"]
    B --> C["Documentar IPs estaticas gateway DNS y VLAN"]
    C --> D["Actualizar reservas DHCP porque las MAC cambian"]
    D --> E{"Sistema operativo del huesped"}
    E -->|Linux| F["Anadir modulos virtio al initramfs y regenerarlo"]
    E -->|Windows| G["Descargar virtio-win y tener el ISO listo en el nodo"]
    G --> H{"Hay vTPM o BitLocker"}
    F --> I["Apagar el huesped"]
    H -->|Si| J["Desactivar el cifrado de vTPM y suspender BitLocker"]
    H -->|No| I
    J --> I
    I --> K["Migrar con el metodo elegido"]
    K --> L["Post-migracion: CPU / SCSI / discos / red / guest agent"]

La lista imprescindible, sin excepciones:

  • Desinstalar VMware Tools en el huésped antes de migrar. En Hyper-V, los Integration Services; en VirtualBox, las Guest Additions.
  • Documentar la configuración de red, sobre todo las IPs estáticas.
  • Actualizar las reservas DHCP: las MAC cambian.
  • Desactivar el cifrado de vTPM si lo hay.
  • Apagar la VM de origen antes de empezar, salvo en el método de attach & move, donde el apagado es el paso 5.
  • Windows: preparar el driver VirtIO antes, o el sistema no arrancará.
  • Linux: asegurar que los módulos virtio están en el initramfs.

Linux: los módulos virtio en el initramfs

Un huésped Linux que venía de ESXi tiene un initramfs construido para hablar con un controlador PVSCSI o LSI. Al arrancar sobre VirtIO SCSI, el kernel arranca, no encuentra el disco raíz y cae al shell de emergencia. La solución es incluir los módulos antes de migrar.

En Debian y Ubuntu, dentro del huésped y antes de apagarlo:

echo -e "virtio\nvirtio_pci\nvirtio_blk\nvirtio_scsi\nvirtio_net" >> /etc/initramfs-tools/modules
update-initramfs -u -k all

En RHEL, Rocky y AlmaLinux:

dracut --force --add-drivers "virtio virtio_pci virtio_blk virtio_scsi virtio_net"

Si te olvidaste y la VM ya no arranca en Proxmox VE, no hay que rehacer la migración: arranca en modo rescate, o cambia temporalmente el bus del disco a IDE o SATA, reconstruye el initramfs con esos módulos desde dentro, apaga y vuelve a VirtIO SCSI.

Windows: el ISO virtio-win en el nodo

En Windows el driver no se puede añadir al arranque desde fuera, así que la preparación consiste en tener el ISO de drivers disponible en el nodo antes de empezar:

cd /var/lib/vz/template/iso
wget https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso

La build stable se corresponde aproximadamente con lo que se envió en la release más reciente de Red Hat Enterprise Linux. Existe también una build latest en .../latest-virtio/virtio-win.iso, pero puede ser de calidad pre-release, así que para una migración de producción usa la stable.

Gotcha de versiones: la wiki oficial documenta que virtio-win 0.1.285 provoca errores de lectura y problemas de rendimiento con discos VirtIO SCSI o VirtIO Block en VMs de Windows Server 2025 bajo cargas de IO intensivas, reportado con Microsoft SQL Server. El workaround documentado es usar 0.1.271, que no está afectada. Si vas a migrar un Windows Server 2025 con base de datos, comprueba la versión del ISO antes de instalar nada.

Post-migración: CPU, controlador SCSI, discos, red y guest agent

Una VM recién importada arranca con una configuración conservadora, que es lo correcto para que arranque, pero no es la configuración con la que quieres dejarla. Esta es la tabla de ajustes recomendados:

AjusteValor recomendado
Tipo de CPUx86-64-v2-AES, o host si no vas a migrar en vivo entre CPUs distintas
Controlador SCSIVirtIO SCSI single
Discodiscard=on, iothread=1, y ssd=1 si el backing es SSD
Redvirtio
BIOSSeaBIOS si el origen era legacy, OVMF (UEFI) si era UEFI
Machineq35 para UEFI
Guest agentInstalar qemu-guest-agent y activar --agent enabled=1

Traducido a comandos:

qm set 300 --cpu x86-64-v2-AES
qm set 300 --scsihw virtio-scsi-single
qm set 300 --scsi0 local-lvm:vm-300-disk-0,discard=on,iothread=1,ssd=1
qm set 300 --net0 virtio,bridge=vmbr0
qm set 300 --agent enabled=1

Tres precisiones sobre esa tabla que evitan sorpresas:

Uno. iothread=1 solo se puede usar en discos VirtIO Block, o en discos SCSI cuando el scsihw es virtio-scsi-single. Si intentas activarlo con lsi o con virtio-scsi-pci, no funcionará. Por eso el orden importa: primero el scsihw, después el disco.

Dos. El cambio de agent no surte efecto con un reinicio caliente desde dentro del huésped. La documentación es explícita: “A fresh start of the VM is necessary for the changes to take effect.” Hace falta un stop + start, o un qm reboot, que sí aplica los cambios pendientes. Puedes ver qué queda pendiente con qm pending 300.

Tres. ssd no está soportado en VirtIO Block: solo en IDE, SATA y SCSI. Y discard en VirtIO Block requiere kernel Linux 5.0 o superior en el huésped.

Dentro del huésped, instalar el agente:

# Debian / Ubuntu
apt-get install qemu-guest-agent
systemctl enable --now qemu-guest-agent

# RHEL / Rocky / AlmaLinux
dnf install qemu-guest-agent
systemctl enable --now qemu-guest-agent

En Windows, el agente y el resto de drivers salen del mismo ISO: virtio-win-guest-tools.exe en la raíz, o guest-agent\qemu-ga-x86_64.msi si solo quieres el agente. El detalle completo del stack de drivers de Windows está en el capítulo 4.

Windows: INACCESSIBLE_BOOT_DEVICE y el truco del disco temporal

Este es el error más famoso de las migraciones a KVM, y su causa es sencilla: Windows solo carga en el arranque temprano los drivers de almacenamiento que ya conoce. Si mueves el disco de sistema a un bus VirtIO SCSI del que Windows nunca ha oído hablar, el kernel no encuentra el volumen de arranque y muestra la pantalla azul con INACCESSIBLE_BOOT_DEVICE.

El truco consiste en hacer que Windows instale el driver mientras todavía arranca desde un bus que sí entiende. Se le presenta un segundo disco, vacío y pequeño, colgado del controlador VirtIO SCSI: Windows lo detecta, pide el driver, y una vez instalado ya puede arrancar desde ese controlador.

flowchart LR
    A["Disco de arranque en SATA o IDE"] --> B["Anadir disco temporal en scsi1 y el ISO virtio-win"]
    B --> C["Arrancar Windows desde el bus antiguo"]
    C --> D["Windows detecta scsi1 y pide driver"]
    D --> E["Instalar Red Hat VirtIO SCSI controller desde el ISO"]
    E --> F["Instalar virtio-win-guest-tools.exe"]
    F --> G["Apagar la VM"]
    G --> H["Borrar el disco temporal y el bus antiguo"]
    H --> I["Adjuntar el disco de arranque como scsi0"]
    I --> J["scsihw virtio-scsi-single y boot order=scsi0"]

El procedimiento completo por CLI, sobre una VM 303 recién migrada que arrancaba en ide0:

# 1. Descargar el ISO de drivers VirtIO en el nodo
cd /var/lib/vz/template/iso
wget https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso

# 2. Adjuntar el ISO y ANADIR un disco pequeno temporal en scsi1
qm set 303 --ide3 local:iso/virtio-win.iso,media=cdrom
qm set 303 --scsi1 local-lvm:1

# 3. Arrancar Windows, que sigue booteando desde IDE/SATA.
#    Windows detecta el disco scsi1 y pide el driver:
#    instalar "Red Hat VirtIO SCSI controller" desde el ISO.
#    Instalar tambien el guest agent con virtio-win-guest-tools.exe

# 4. Apagar y mover el disco de arranque a scsi0
qm set 303 --delete scsi1
qm set 303 --delete ide0
qm set 303 --scsi0 local-lvm:vm-303-disk-0,discard=on
qm set 303 --boot order=scsi0
qm set 303 --scsihw virtio-scsi-single

Gotcha del “Load driver”: cuando Windows abre el diálogo para buscar el driver en el ISO, hay que dejar marcada la casilla “Include subfolders”. Sin ella, el instalador no encuentra el .inf y parece que el ISO no sirve. El driver que buscas está en vioscsi\<version-windows>\amd64, donde la subcarpeta es w11 para Windows 11, w10 para Windows 10, 2k22 para Server 2022 y 2k25 para Server 2025.

Un apunte útil si tu origen era ESXi y quieres una fase intermedia todavía más suave: scsihw admite el valor pvscsi, que emula el controlador VMware Paravirtual. Sirve exactamente para VMs importadas de ESXi cuyo huésped ya tiene ese driver instalado, y te permite arrancar sin tocar nada antes de hacer la transición a virtio-scsi-single.

Migrar desde Hyper-V: VHDX, generación 1 frente a 2, avhdx y vTPM

Desde Hyper-V no hay importador nativo. El flujo es siempre: convertir la imagen con qemu-img, crear la VM y adjuntar el disco.

Lo primero es la equivalencia de firmware, que determina toda la configuración de la VM destino:

Hyper-VProxmox VE
Generation 1BIOS legacy: --bios seabios, machine pc
Generation 2UEFI: --bios ovmf, machine q35, efidisk0 obligatorio

El procedimiento completo, con la VM origen ya preparada (Integration Services desinstalados, arranque seguro revisado):

# 1. Copiar el VHDX al nodo PVE: scp, SMB, USB...

# 2. Convertir a qcow2 o a raw
qemu-img convert -p -f vhdx -O qcow2 /mnt/origen/servidor.vhdx /var/lib/vz/images/servidor.qcow2
# o directo a raw, mejor rendimiento sobre LVM y ZFS
qemu-img convert -p -f vhdx -O raw /mnt/origen/servidor.vhdx /var/lib/vz/images/servidor.raw

# 3. Crear la VM. Este ejemplo asume Generation 2 = UEFI
qm create 310 --name hyperv-migrada --memory 8192 --cores 4 \
  --net0 virtio,bridge=vmbr0 --scsihw virtio-scsi-single --ostype win11 \
  --bios ovmf --machine q35
qm set 310 --efidisk0 local-lvm:0,efitype=4m,pre-enrolled-keys=1

# 4. Importar el disco
qm disk import 310 /var/lib/vz/images/servidor.qcow2 local-lvm --format qcow2

# 5. Adjuntar primero en SATA para que Windows no de INACCESSIBLE_BOOT_DEVICE
qm set 310 --sata0 local-lvm:vm-310-disk-0
qm set 310 --boot order=sata0
qm set 310 --ide3 local:iso/virtio-win.iso,media=cdrom

# 6. Arrancar, instalar los drivers VirtIO y despues pasar a scsi0

Cuatro particularidades de Hyper-V que hay que conocer:

Uno. Si el VHDX es dinámico, qemu-img convert lo expande al tamaño real usado. Es normal que el fichero resultante sea bastante más grande que el original; calcula el espacio de destino sobre el tamaño usado, no sobre el tamaño del fichero.

Dos. Los discos diferenciales .avhdx son una cadena de snapshots. Hay que hacer merge de la cadena en Hyper-V antes de exportar; si no, qemu-img convert fallará o producirá datos incompletos. Este es probablemente el error más silencioso de toda la migración desde Hyper-V, porque la conversión puede terminar sin error aparente.

Tres. El vTPM de Hyper-V no se migra. Hay que crear uno nuevo en la VM destino:

qm set 310 --tpmstate0 local-lvm:1,version=v2.0

Cuatro. Si había BitLocker, hay que suspenderlo antes de migrar o tener la clave de recuperación a mano. Desde dentro del huésped, en PowerShell:

manage-bde -protectors -disable C:

Hay que hacerlo por cada unidad cifrada. Un vTPM nuevo tiene medidas de plataforma distintas, y BitLocker lo interpreta exactamente como lo que es: un cambio de hardware.

Migrar desde VirtualBox: VDI y Guest Additions

VirtualBox es el caso más simple, porque qemu-img entiende el formato VDI de forma nativa. Lo único obligatorio antes de empezar es desinstalar las Guest Additions dentro del huésped.

Hay dos opciones para la conversión. Con VBoxManage, en el equipo de origen:

VBoxManage clonemedium disk servidor.vdi servidor.vmdk --format VMDK
# o directamente a raw
VBoxManage clonemedium disk servidor.vdi servidor.img --format RAW

O directamente con qemu-img, que es lo que harás si ya copiaste el VDI al nodo:

qemu-img convert -p -f vdi -O qcow2 servidor.vdi servidor.qcow2

Y la importación:

qm create 311 --name vbox-migrada --memory 4096 --cores 2 \
  --net0 virtio,bridge=vmbr0 --scsihw virtio-scsi-single --ostype l26
qm disk import 311 servidor.qcow2 local-lvm --format qcow2
qm set 311 --scsi0 local-lvm:vm-311-disk-0,discard=on
qm set 311 --boot order=scsi0

Dos notas:

  • Si el huésped era UEFI en VirtualBox, hay que usar --bios ovmf --machine q35 y añadir el efidisk0, igual que con Hyper-V Generation 2.
  • La red en VirtualBox suele estar en modo NAT, así que las IPs del huésped van a cambiar sí o sí. Documenta lo que hubiera antes de apagar.

Tabla de formatos y flags de qemu-img convert

qemu-img es la herramienta común a todos los métodos manuales. Lo primero es acertar con el -f de origen, porque una detección automática errónea produce imágenes ilegibles:

Origen-fDestino recomendado-O
VMwarevmdkqcow2 o rawqcow2 / raw
Hyper-V VHDvpcqcow2 o rawqcow2 / raw
Hyper-V VHDXvhdxqcow2 o rawqcow2 / raw
VirtualBoxvdiqcow2 o rawqcow2 / raw
Xenvhd (vpc)qcow2qcow2
Imagen crudarawqcow2qcow2

Los flags que de verdad usas:

qemu-img convert -p            # barra de progreso
                 -O qcow2      # formato destino
                 -o preallocation=metadata   # rendimiento inicial en qcow2
                 -c            # comprimido: mas lento y mas pequeno
                 -m 8          # 8 corrutinas en paralelo
                 -W            # escrituras fuera de orden, mas rapido, requiere -m
                 origen.vmdk destino.qcow2

-m 8 -W juntos son la combinación que acorta de verdad las conversiones grandes: el número de corrutinas concurrentes sube y se permite escribir fuera de orden. -W requiere -m, no funciona solo.

Y la parte que la gente se salta: inspeccionar antes y verificar después.

# Que formato es realmente, que tamano virtual tiene, si hay cadena de backing
qemu-img info servidor.vhdx

# Verificar la consistencia de la imagen convertida
qemu-img check servidor.qcow2

qemu-img info sobre un .avhdx te muestra la cadena de backing: si aparece, ya sabes que tienes que hacer merge en Hyper-V antes de seguir. Es una comprobación de dos segundos que ahorra una migración entera.

Sobre la elección de formato: raw rinde hasta un 10% más que qcow2, pero no tiene snapshots propios ni thin provisioning por sí mismo. Y hay una regla dura del modelo de storage de Proxmox VE que decide por ti en muchos casos: los storages que presentan dispositivos de bloque —LVM, ZFS, Ceph— exigen raw. Solo los storages basados en ficheros —ext4, XFS, NFS, CIFS— te dejan elegir. El detalle completo está en el capítulo 7.

Volcar directo a un zvol, LV o RBD sin pasos intermedios

Si tu destino es LVM-thin, un zvol de ZFS o un RBD de Ceph, importar un qcow2 es trabajo doble: Proxmox VE tendrá que reconvertirlo a raw al colocarlo en el volumen. El atajo es crear primero el volumen vacío y volcar la conversión directamente sobre el dispositivo de bloque.

# 1. Crear el volumen vacio del tamano necesario. Esto crea el LV o el zvol
qm set 310 --scsi0 local-lvm:64

# 2. Volcar la conversion directamente sobre el dispositivo
qemu-img convert -p -f vhdx -O raw origen.vhdx /dev/pve/vm-310-disk-0

El 64 es el tamaño en GiB; tiene que ser al menos el tamaño virtual del disco de origen, el que te reporta qemu-img info. La ruta del dispositivo depende del backend: en LVM es /dev/<vg>/vm-<vmid>-disk-<n>, en ZFS es /dev/zvol/<pool>/vm-<vmid>-disk-<n>. Comprueba la ruta real en tu sistema antes de escribir sobre ella:

lsblk
ls -l /dev/pve/
zfs list -t volume

Advertencia: este método escribe directamente sobre un dispositivo de bloque. Un VMID equivocado en el comando sobrescribe el disco de otra VM sin preguntar y sin posibilidad de deshacer. Verifica la ruta con qm config <vmid> antes de ejecutar el convert, y hazlo con la VM destino apagada.

Para ZFS y sus particularidades de volblocksize y compresión, que afectan al espacio ocupado tras el volcado, el capítulo 8 tiene el detalle.

Validación posterior: la lista que se firma

Una VM migrada no está migrada hasta que pasa esta lista. Recórrela con el huésped encendido y anota el resultado.

  • qm config <vmid> muestra scsihw: virtio-scsi-single, el disco en scsi0 con discard=on e iothread=1, y net0 con modelo virtio.
  • El panel Summary de la VM muestra uso de RAM e IPs. Si no las muestra, el guest agent no está corriendo: qm agent <vmid> ping.
  • Dentro del huésped, la interfaz de red tiene la IP correcta y el gateway responde. En Linux, comprueba que no quedó una interfaz vieja definida por nombre.
  • En Windows, el Administrador de dispositivos no tiene ningún “Unknown device”.
  • El servicio de la aplicación arranca solo tras un reinicio completo, no solo tras el arranque manual.
  • La VM aparece en un job de backup y se ha ejecutado una restauración de prueba. Una migración sin backup validado no está terminada; el capítulo 13 cubre cómo montarlo.
  • La reserva DHCP o el registro DNS apuntan a la nueva MAC o a la nueva IP.
  • La VM de origen está apagada y marcada como no arrancable en el hipervisor viejo, no simplemente apagada.

Ese último punto merece una nota. Mientras la VM de origen exista y sea arrancable, alguien puede encenderla. Si el disco todavía se comparte —caso attach & move— eso corrompe datos. Si no se comparte, produce dos servidores con la misma identidad en la red, que es una forma distinta de arruinar la tarde.

Para diagnosticar lo que sea que quede raro, la herramienta número uno es ver la línea de comandos real que recibe QEMU:

qm showcmd <vmid> --pretty 1

Ahí ves exactamente el machine, los flags de CPU, el cache, el aio y el iothread que se están aplicando, sin interpretación de por medio.

Errores comunes y diagnóstico

SíntomaCausa probableDiagnóstico y solución
El storage esxi aparece vacío o en errorCertificado autofirmado, credenciales sin permisos de administrador o falta pve-esxi-import-toolspvesm list <storage>; probar /usr/libexec/pve-esxi-import-tools/listvms.py a mano; revisar Skip Certificate Verification
La VM no aparece en el listado del importadorSus discos están en vSANLimitación documentada. Mover los discos a otro datastore antes de importar
La importación falla con un datastore concretoCaracteres especiales como + en el nombre del datastoreLimitación documentada. Renombrar el datastore o usar OVF
La importación tarda muchísimoLa VM de origen tiene snapshotsConsolidar los snapshots en ESXi antes de importar
La imagen no se puede importar por estar cifradaCifrado por Storage Policy de VMwareQuitar el cifrado en el origen
El vTPM no llega al destinovTPM cifrado no migrableCrear uno nuevo: qm set <vmid> --tpmstate0 local-lvm:1,version=v2.0
Windows arranca en bucle pidiendo la clave de BitLockerEl vTPM es nuevo y cambian las medidas de plataformamanage-bde -protectors -disable C: antes de migrar, o usar la clave de recuperación
INACCESSIBLE_BOOT_DEVICE al primer arranque en WindowsEl disco de sistema está en VirtIO SCSI y falta el driver vioscsiAdjuntar en sata0, añadir disco temporal en scsi1 con el ISO virtio-win, instalar el driver y volver a scsi0
Windows no ve el driver dentro del ISOFalta marcar “Include subfolders” en el diálogo Load driverRepetir con la casilla marcada; buscar en vioscsi\<version>\amd64
Linux cae al shell de emergencia sin disco raízEl initramfs no trae los módulos virtioArrancar en rescate o pasar el bus a SATA, update-initramfs -u -k all o dracut --force --add-drivers "virtio virtio_pci virtio_blk virtio_scsi virtio_net"
El disco importado no aparece en la VMqm disk import sin --target-disk lo deja como unusedXqm config <vmid>; adjuntar con qm set <vmid> --scsi0 <storage>:vm-<vmid>-disk-0
La imagen importada está vacía o corrupta desde VMwareSe copió el descriptor .vmdk sin el fichero -flat.vmdkCopiar ambos; verificar con qemu-img info
qemu-img convert falla o produce datos incompletos desde Hyper-VCadena de discos diferenciales .avhdx sin consolidarqemu-img info muestra la cadena de backing; hacer merge en Hyper-V antes de exportar
El fichero convertido es mucho más grande que el originalVHDX dinámico expandido al tamaño real usadoComportamiento esperado. Dimensionar el destino por tamaño usado, no por tamaño de fichero
iothread no se puede activar en el disco SCSIEl scsihw no es virtio-scsi-singleqm set <vmid> --scsihw virtio-scsi-single y volver a fijar el disco
Las IPs no aparecen en el Summary tras migrarEl guest agent no está instalado o el cambio de agent sigue pendienteqm agent <vmid> ping; qm pending <vmid>; hace falta stop + start, no un reinicio caliente
qm shutdown se queda colgado hasta el timeoutagent: 1 en la config pero el agente no corre en el huéspedInstalar qemu-guest-agent; en Windows comprobar el servicio QEMU-GA
La VM no arranca: “Host doesn’t support requested features”Tipo de CPU demasiado alto para la CPU física del nodoBajar el cputype; contrastar con lscpu y los flags disponibles
El servidor no responde en su IP habitual tras migrarLa MAC cambió y la reserva DHCP apunta a la antiguaActualizar la reserva DHCP, o fijar la MAC anterior en net0
Corrupción de datos tras el arranque en Proxmox VELa VM se encendió a la vez en ambos hipervisores”Never power on the same VM in both Proxmox VE or VMware simultaneously”. Restaurar desde backup
El OVA subido no aparece como importableEl storage no tiene el content type import habilitadoHabilitar import en el storage de ficheros correspondiente

Comandos de diagnóstico transversales para esta fase:

qm showcmd <vmid> --pretty 1      # la linea de comandos QEMU real
qm config <vmid> --current 1      # config sin los cambios pendientes
qm pending <vmid>                 # que cambios esperan un arranque en frio
qm agent <vmid> ping              # el guest agent responde o no
pvesm status                      # estado de todos los storages, incluido el esxi
cat /var/log/pve/tasks/index      # historico de tareas del nodo
journalctl -u pvedaemon -u pveproxy -f

Cierre: el curso completo y qué viene después

Este capítulo cierra el recorrido. Si lo has seguido entero, lo que tienes montado es esto:

La base. Un nodo instalado y con los repositorios correctos desde el capítulo 1, y la anatomía del sistema, la interfaz web y las herramientas CLI del capítulo 2 para saber dónde mirar cuando algo falla.

Los huéspedes. Máquinas virtuales KVM con firmware, CPU y discos elegidos con criterio, Windows con su stack VirtIO completo, plantillas y cloud-init para no volver a instalar un sistema operativo a mano, y contenedores LXC donde una VM entera sería desperdicio.

La infraestructura. El modelo de plugins de storage y sus backends, ZFS con replicación, la red del host con bridges, VLAN, bonding y SDN, y el firewall con usuarios y permisos por encima.

La escala. Clúster con quorum, alta disponibilidad y migración, y Ceph hiperconvergido cuando el storage compartido tiene que dejar de ser un punto único de fallo.

La operación. Backups con vzdump y Proxmox Backup Server bajo una estrategia 3-2-1, automatización con API REST, Terraform/OpenTofu, Ansible y Packer, y monitoreo, notificaciones, actualizaciones y runbook para el día a día.

Y la carga de trabajo real, que es lo que has traído en este capítulo.

Lo que viene después no está en ningún índice, y es lo único que separa un laboratorio de una plataforma de producción: probar las restauraciones. Una restauración completa, en un nodo distinto, con cronómetro, al menos una vez por trimestre. El resto de este curso te enseña a construir; esa prueba es la que te dice si lo construido aguanta.

Si vuelves sobre algún tema, los dos que más rinden al releer son el capítulo 11, porque el comportamiento del quorum solo se entiende del todo cuando ya has perdido un nodo, y el capítulo 14, porque todo lo que hiciste a mano durante la migración se puede convertir en código y no volver a hacerse nunca más a mano.