Dejar VMware tras Broadcom: guía de migración comprobada

Dejar VMware tras Broadcom: guía de migración comprobada

Dejar VMware tras Broadcom: guía de migración comprobada

Respuesta corta (comprobado el 2026-11-03): desde que compró VMware, Broadcom ha dejado de vender licencias perpetuas, ha reducido el catálogo a dos paquetes de suscripción, ha cerrado en Europa su antiguo programa de socios cloud y, este otoño, ha retirado la descarga pública de VDDK, la biblioteca de discos que usan la mayoría de las herramientas de migración para leer discos de VMware. Hoy The Register informa de un sustituto de código abierto y de solo lectura para esa biblioteca. Pero no todas las salidas necesitan VDDK: una exportación OVA más una conversión de disco no usa ni una línea de código de VMware. A continuación: los cambios con sus fechas, destinos realistas para un equipo de la UE, la migración paso a paso y un conversor que ejecutamos sobre una exportación real en formato VMware.

Fuente. "Architect creates open-source replacement for VM migration tool VMware has hidden" (Simon Sharwood, The Register, 2026-11-03). El resto de los datos se enlazan donde aparecen. Su contrato puede diferir de las condiciones públicas, así que confirme los detalles de la licencia con su revendedor.

Qué cambió Broadcom, con fechas

Fecha Cambio Fuente
2023-12-11 Fin de la venta de licencias perpetuas y de las renovaciones de soporte; la oferta se reduce a las suscripciones VMware Cloud Foundation (VCF) y vSphere Foundation (VVF) Noticias de Broadcom, Krish Prasad
2025-03-28 El distribuidor Arrow comunica a sus socios que el pedido mínimo sube de 16 a 72 núcleos por línea de producto a partir del 2025-04-10 The Register
2026-01-26 Los contratos de proveedores cloud (VCSP) en el EEE no se renuevan; las operaciones abiertas deben cerrarse antes del 2026-03-31; después, programa solo por invitación The Register, 2026-01-31
Aug-Sep 2026 VDDK se retira de la descarga pública: "The VDDK is not a customer entitlement" (VDDK no es un derecho del cliente), acceso a través de socios TAP seleccionados TechTarget, 2026-09-09
2026-11-03 OpenVDDK de Andrija Panić: sustituto directo, de solo lectura y con licencia Apache, de libvixDiskLib.so.8.0.3 que "contains no VMware code" (no contiene código de VMware) The Register, 2026-11-03

Dos advertencias. El mínimo de 72 núcleos lo comunicó un distribuidor, no aparece en ninguna página de Broadcom que hayamos encontrado: el artículo de Broadcom sobre el recuento de núcleos (KB 313548, comprobado el 2026-11-03) dice "You must license a minimum of 16 physical cores for each CPU" (hay que licenciar un mínimo de 16 núcleos físicos por CPU), y algunos revendedores afirman que el pedido mínimo de 72 núcleos se ha vuelto a eliminar. Pida por escrito el número de núcleos de su presupuesto. Además, el frente europeo sigue abierto: la asociación de proveedores cloud CISPE pidió en julio de 2025 al Tribunal General de la UE que anulara la aprobación de la fusión por parte de la Comisión (asunto T-503/25); todavía no hemos encontrado ninguna sentencia.

Por qué importa VDDK y qué vías lo evitan

La biblioteca de VDDK, libvixDiskLib, permite a una herramienta leer los discos de las VM que siguen en vSphere. The Register menciona virt-v2v, nbdkit, los importadores Forklift / MTV, Apache CloudStack y scripts internos entre las herramientas que la cargan. La extensión VM Conversion de Microsoft para Windows Admin Center (de vCenter a Hyper-V, con sincronización en caliente mediante Change Block Tracking) sigue marcada como versión preliminar en su documentación (actualizada el 2026-02-20), y la cobertura de su lanzamiento incluye VDDK entre sus requisitos previos. OpenVDDK es la nueva opción para todas ellas, con la advertencia de su propio autor de que los informes de los probadores son "not independently audited customer endorsements" (no son recomendaciones de clientes auditadas de forma independiente).

Vías sin VDDK, según la documentación de entrada VMware de virt-v2v (comprobada el 2026-11-03): una exportación OVA (-i ova), los archivos de la VM por NFS o por SSH (-i vmx, -it ssh), NFC y la vía HTTPS simple de vCenter, que la documentación llama "the slowest method" (el método más lento). El asistente de importación de ESXi de Proxmox VE, anunciado el 2024-03-27, lee los discos a través de la API de ESXi con su propio sistema de archivos en espacio de usuario escrito en Rust y se probó con ESXi 6.5 a 8.0 (foro de Proxmox).

Adónde migrar: cinco destinos realistas

Destino Encaja cuando Cuidado con
Proxmox VE (KVM) en su propio hardware 3 o más hosts, un equipo que quiere interfaz gráfica y clúster Usted se encarga de las actualizaciones, el almacenamiento (ZFS, Ceph) y el soporte
OpenStack Muchos inquilinos, todo a través de una API Pesado de operar; solo compensa a gran escala
Hyper-V (Windows Server) Entorno con mucho Windows, licencias Datacenter ya pagadas La herramienta de Microsoft necesita antes los controladores de Hyper-V en los invitados Linux
Servidores cloud (KVM) De unas pocas a unas decenas de VM, sin ganas de operar un hipervisor Una importación por VM, nuevas direcciones IP
Servidores dedicados + su propio hipervisor Carga estable, quiere la máquina entera Usted opera y parchea el hipervisor

Migrar una VM en cinco pasos

  1. Inventario y limpieza. Anote el firmware (BIOS o EFI), la controladora de disco, el tipo de NIC, las IP estáticas y cualquier licencia ligada a una dirección MAC. Elimine o consolide las instantáneas para exportar un único disco actual.
  2. Prepare el invitado mientras sigue en VMware. Windows: instale ya los controladores virtio (virtio-win); un invitado Windows trasladado a un disco virtio sin ellos no arranca. Linux: los controladores virtio están en el kernel, pero un initramfs de tipo host-only puede no incluirlos; compruébelo con lsinitramfs o lsinitrd y regenérelo si hace falta.
  3. Exporte o conecte. Apague la VM y exporte un OVF / OVA (en vSphere Client, "Export OVF Template", o con ovftool), o deje que virt-v2v o el asistente de Proxmox la extraigan.
  4. Convierta. Solo el disco con qemu-img, el invitado completo con virt-v2v (que también ajusta los controladores), o directamente en Proxmox desde el OVF.
  5. Arranque en la consola y después limpie. Compruebe el nombre de la NIC y la IP, elimine VMware Tools u open-vm-tools e instale qemu-guest-agent.
qemu-img convert -p -f vmdk -O qcow2 disk1.vmdk disk1.qcow2
virt-v2v -i ova VM.ova -o local -os /var/tmp -of qcow2
qm importovf 120 VM.ovf local-lvm

Estas son las formas documentadas en el manual de cada herramienta; aquí no ejecutamos estas tres. La conversión que sí ejecutamos está a continuación.

Probado: qué hace realmente una conversión (ova2raw.js)

Para mostrar las piezas, escribimos la conversión en unas 100 líneas de Bun sin dependencias. Abre una OVA (un tar normal), comprueba el manifiesto SHA-256, muestra el hardware que pide el OVF, descomprime el VMDK streamOptimized grano a grano en una imagen raw dispersa y comprueba la GPT. Le dimos la OVA oficial de Ubuntu 24.04, una exportación real en formato VMware: noble-server-cloudimg-amd64.ova, compilación del 2026-10-17, cuyo SHA-256 coincidía con el SHA256SUMS de Ubuntu. Guárdelo como ova2raw.js:

// ova2raw.js - check a VMware OVA export and turn its disk into a raw image for KVM
// usage: bun ova2raw.js <export.ova> <out.raw>
import { openSync, readSync, writeSync, ftruncateSync, closeSync, fstatSync } from 'node:fs'
import { inflateSync } from 'node:zlib'
import { createHash } from 'node:crypto'

const [ova, out] = process.argv.slice(2)
const fd = openSync(ova, 'r')
const read = (pos, len) => {
  const b = Buffer.alloc(len)
  readSync(fd, b, 0, len, pos)
  return b
}

// 1. an OVA is a plain tar: list its members
const files = {}
for (let o = 0; o + 512 <= fstatSync(fd).size; ) {
  const h = read(o, 512)
  if (h.every(x => x === 0)) break
  const name = h.toString('utf8', 0, 100).replace(/\0.*$/s, '')
  const size = parseInt(h.toString('ascii', 124, 136).replace(/\0.*$/s, '').trim(), 8)
  files[name] = { pos: o + 512, size }
  o += 512 + Math.ceil(size / 512) * 512
}
const find = ext => Object.keys(files).find(n => n.endsWith(ext))
const text = n => read(files[n].pos, files[n].size).toString('utf8')
console.log('OVA members:', Object.entries(files).map(([n, f]) => `${n} (${f.size} B)`).join(', '))

// 2. the .mf manifest: every member's SHA-256 must match
const mf = find('.mf')
for (const line of mf ? text(mf).split('\n') : []) {
  const m = line.match(/^SHA(1|256)\((.+)\)\s*=\s*([0-9a-f]+)/i)
  if (!m || !files[m[2]]) continue
  const h = createHash('sha' + m[1])
  const f = files[m[2]]
  for (let p = 0; p < f.size; p += 1 << 24) h.update(read(f.pos + p, Math.min(1 << 24, f.size - p)))
  console.log(`  manifest ${m[2]}: ${h.digest('hex') === m[3].toLowerCase() ? 'OK' : 'MISMATCH'}`)
}

// 3. the .ovf descriptor: what the VM expects from its hardware
const ovf = text(find('.ovf'))
const items = [...ovf.matchAll(/<(?:ovf:)?Item\b[\s\S]*?<\/(?:ovf:)?Item>/g)].map(x => x[0])
const tag = (s, t) => s.match(new RegExp(`<(?:rasd:)?${t}>([^<]*)<`))?.[1]
const kind = { 3: 'CPU', 4: 'RAM', 5: 'IDE controller', 6: 'SCSI controller', 10: 'NIC', 17: 'disk', 20: 'SATA controller' }
console.log('OVF:', ovf.match(/vmw:osType="([^"]+)"/)?.[1] ?? '?', '| firmware',
  ovf.match(/key="firmware" ovf:value="([^"]+)"/)?.[1] ?? 'bios (default)')
for (const it of items) {
  const k = kind[tag(it, 'ResourceType')]
  if (k) console.log(`  ${k.padEnd(16)} ${tag(it, 'ElementName') ?? ''} ${tag(it, 'ResourceSubType') ?? ''} ${tag(it, 'VirtualQuantity') ?? ''}`.trimEnd())
}

// 4. the streamOptimized VMDK: a header, then compressed grains and markers
const vmdk = files[find('.vmdk')]
const hd = read(vmdk.pos, 512)
if (hd.readUInt32LE(0) !== 0x564d444b) throw new Error('not a sparse VMDK (no KDMV magic)')
const capacity = Number(hd.readBigUInt64LE(12)) * 512
const desc = read(vmdk.pos + Number(hd.readBigUInt64LE(28)) * 512, Number(hd.readBigUInt64LE(36)) * 512)
console.log(`VMDK ${desc.toString().match(/createType="([^"]+)"/)?.[1]}, virtual size ${capacity} B, grain ${Number(hd.readBigUInt64LE(20)) * 512} B`)

const ofd = openSync(out, 'w')
ftruncateSync(ofd, capacity) // sparse: unwritten grains stay holes = zeros
let pos = Number(hd.readBigUInt64LE(64)) * 512
let grains = 0
let written = 0
while (pos < vmdk.size) {
  const m = read(vmdk.pos + pos, 512)
  const val = Number(m.readBigUInt64LE(0))
  const size = m.readUInt32LE(8)
  if (size) { // compressed grain: lba, size, zlib data
    const raw = inflateSync(read(vmdk.pos + pos + 12, size))
    writeSync(ofd, raw, 0, raw.length, val * 512)
    grains++
    written += raw.length
    pos += Math.ceil((12 + size) / 512) * 512
  } else if (m.readUInt32LE(12) === 0) break // end-of-stream marker
  else pos += 512 + val * 512 // grain table / directory / footer: metadata only
}
closeSync(ofd)
console.log(`Wrote ${out}: ${grains} grains, ${written} B of data in ${capacity} B`)

// 5. check the result: a valid GPT, and the file systems where the partitions say they are
const rfd = openSync(out, 'r')
const at = (p, l) => { const b = Buffer.alloc(l); readSync(rfd, b, 0, l, p); return b }
const gpt = at(512, 92)
const crc = Buffer.from(gpt)
crc.writeUInt32LE(0, 16)
console.log(`GPT "${gpt.toString('ascii', 0, 8)}", header CRC ${(Bun.hash.crc32(crc) >>> 0) === gpt.readUInt32LE(16) ? 'OK' : 'BAD'}`)
const n = gpt.readUInt32LE(80)
const es = gpt.readUInt32LE(84)
const ents = at(Number(gpt.readBigUInt64LE(72)) * 512, n * es)
console.log(`  partition array CRC ${(Bun.hash.crc32(ents) >>> 0) === gpt.readUInt32LE(88) ? 'OK' : 'BAD'}`)
for (let i = 0; i < n; i++) {
  const e = ents.subarray(i * es, (i + 1) * es)
  if (e.subarray(0, 16).every(x => x === 0)) continue
  const first = Number(e.readBigUInt64LE(32))
  const last = Number(e.readBigUInt64LE(40))
  const sb = at(first * 512 + 1024, 136)
  const fs = sb.readUInt16LE(56) === 0xef53 ? `ext4 label "${sb.toString('ascii', 120, 136).replace(/\0.*$/s, '')}"`
    : at(first * 512, 512).toString('ascii', 82, 87) === 'FAT32' ? 'FAT32 (EFI system partition)'
    : e.toString('ascii', 0, 16) === 'Hah!IdontNeedEFI' ? 'BIOS boot (GRUB for legacy BIOS)' : 'unknown'
  console.log(`  p${i + 1} ${String((last - first + 1) * 512 / 2 ** 20 | 0).padStart(5)} MiB  ${fs}`)
}
bun ova2raw.js noble-server-cloudimg-amd64.ova noble.raw

Salida, ejecutado en un servidor DCXV Cloud con Bun 1.4.4 el 2026-11-03:

OVA members: ubuntu-noble-24.04-cloudimg.ovf (11186 B), ubuntu-noble-24.04-cloudimg.mf (213 B), ubuntu-noble-24.04-cloudimg.vmdk (590749696 B)
  manifest ubuntu-noble-24.04-cloudimg.vmdk: OK
  manifest ubuntu-noble-24.04-cloudimg.ovf: OK
OVF: ubuntu64Guest | firmware bios (default)
  CPU              2 virtual CPU(s)  2
  RAM              1024MB of memory  1024
  SCSI controller  SCSI Controller 0 VirtualSCSI
  IDE controller   VirtualIDEController 1
  IDE controller   VirtualIDEController 0
  disk             Hard Disk 1
  NIC              Ethernet 1 VmxNet3
VMDK streamOptimized, virtual size 10737418240 B, grain 65536 B
Wrote noble.raw: 28663 grains, 1878458368 B of data in 10737418240 B
GPT "EFI PART", header CRC OK
  partition array CRC OK
  p1  2558 MiB  ext4 label "cloudimg-rootfs"
  p14     4 MiB  BIOS boot (GRUB for legacy BIOS)
  p15   106 MiB  FAT32 (EFI system partition)
  p16   913 MiB  ext4 label "BOOT"

Tres ejecuciones tardaron de 14.6 a 16.2 s de tiempo real en ese servidor. El archivo raw tiene un tamaño de 10 GiB y ocupa 1.8 GB en disco.

Qué le dice la salida antes del cambio definitivo

  1. VmxNet3 y VirtualSCSI son dispositivos de VMware. En KVM pasan a ser virtio-net y virtio-blk o virtio-scsi. El invitado necesita controladores para ambos antes del primer arranque, y la interfaz de red suele recibir un nombre nuevo, así que una IP estática ligada al nombre antiguo no se levantará. Use la consola para el primer arranque.
  2. El firmware debe coincidir. Este OVF no define nada, así que es BIOS; el disco lleva tanto una partición de arranque BIOS como una partición de sistema EFI, por lo que arranca de las dos formas. Una VM exportada con firmware=efi necesita UEFI (OVMF) en el destino; si no, no encuentra el cargador de arranque.
  3. Lo fino solo sigue siendo fino si lo mantiene así. 10 GiB virtuales, 1.8 GB de datos. Copie con herramientas que respeten los archivos dispersos (cp --sparse=always, rsync -S) o use qcow2; si no, moverá y almacenará ceros.
  4. El manifiesto es su control de transferencia. Verifique el SHA-256 después de cada copia entre sedes: una subida cortada se convierte sin quejas en un disco que falla más tarde.

Planifique el tiempo de inactividad

Una migración en frío cuesta exportación + transferencia + conversión + primer arranque. Mida cada paso con una VM de prueba y luego multiplique. Cálculo de transferencia (nuestro, sin contar la sobrecarga del protocolo): 1.8 GB a 1 Gbit/s son unos 15 s, 1 TB unas 2.2 horas. Las herramientas en caliente copian mientras la VM funciona y al final solo envían los bloques modificados; los probadores de The Register informan de ejecuciones en frío y en caliente con Forklift y MTV. Para bases de datos y aplicaciones con mucha actividad, la replicación más un cambio de DNS supera a cualquier copia de disco: baje antes el TTL (consulte propagación DNS y TTL) y siga las listas de comprobación de cómo migrar a un servidor cloud.

Cuándo encajan los servidores cloud o dedicados de DCXV

  • Unas pocas VM, sin equipo de hipervisores: nuestros servidores cloud funcionan sobre KVM con discos virtio. En el panel, Reinstalar -> "Imagen propia (URL)" acepta un archivo qcow2, raw o vmdk por https; una imagen mayor que el disco del plan amplía el disco y se factura como ampliación de disco, y la configuración de red solo se aplica si la imagen tiene cloud-init. Los planes empiezan en EUR 15.00/mes (2 vCPU, 4 GB RAM, 40 GB; comprobado el 2026-11-03, IVA no incluido).
  • Decenas de VM o su propio clúster Proxmox: servidores dedicados desde EUR 210/mes, con el hipervisor que elija.
  • Invitados Windows: revendemos licencias de Windows Server; consúltenos antes de la migración para que la licencia esté lista el primer día.

Ambos funcionan en nuestros centros de datos Tier III de Praga y Covilha.

Planifique la migración con nosotros

Ejecute ova2raw.js sobre una VM exportada y envíe las líneas de hardware de su salida a sales@dcxv.com, o ponga en marcha un servidor cloud y pruebe la importación usted mismo.

Dejar VMware tras Broadcom: guía de migración comprobada
clouddedicatedinfrastructure

Dejar VMware tras Broadcom: guía de migración comprobada

Broadcom eliminó las licencias perpetuas, recortó socios y ocultó VDDK. Cómo mover VM a KVM, Proxmox o Hyper-V, con fechas y un conversor OVA probado.

Propagación DNS: 3 segundos de Cloudflare frente a su TTL
networkingcloudinfrastructure

Propagación DNS: 3 segundos de Cloudflare frente a su TTL

Cloudflare bajó su retardo de build DNS a 3,3 s. Un cambio de servidor aún espera al TTL, la caché negativa y 2 días de delegación .com. Medido en dos zonas.

10.000 comentarios en concejos de EE. UU. y lo que implican
clouddedicatedinfrastructure

10.000 comentarios en concejos de EE. UU. y lo que implican

Un conjunto de datos codifica 10.202 intervenciones sobre centros de datos en EE. UU.: 90,5% en contra, el agua primero. Lo recontamos y vemos qué implica.

Soporte y facturación de AWS: guía verificada para la UE
cloudpricingcompare

Soporte y facturación de AWS: guía verificada para la UE

Planes y precios de soporte de AWS, retrasos de facturación, egress desde Frankfurt, un script de costes y cuándo conviene un proveedor UE de precio fijo.

Latencia de memoria en servidor cloud: medida, no supuesta
clouddedicatedinfrastructure

Latencia de memoria en servidor cloud: medida, no supuesta

Un post viral dice que una CPU ocupada a menudo solo espera a la RAM. Medimos la latencia de L1 a DRAM en nuestro servidor cloud y explicamos qué implica.