Odejście od VMware po Broadcom: sprawdzony plan migracji

Odejście od VMware po Broadcom: sprawdzony plan migracji

Odejście od VMware po Broadcom: sprawdzony plan migracji

Krótka odpowiedź (sprawdzone 2026-11-03): Od przejęcia VMware Broadcom przestał sprzedawać licencje wieczyste, zebrał ofertę w dwa pakiety subskrypcyjne, zamknął dawny program partnerów chmurowych w Europie, a tej jesieni wycofał publiczne pobieranie VDDK - biblioteki dyskowej, której większość narzędzi migracyjnych używa do odczytu dysków VMware. Dziś The Register opisuje otwartoźródłowy zamiennik tej biblioteki działający tylko w trybie odczytu. Nie każda droga wyjścia wymaga jednak VDDK: eksport OVA plus konwersja dysku nie korzysta z żadnego kodu VMware. Poniżej: zmiany z datami, realistyczne cele dla zespołu z UE, przeprowadzka krok po kroku oraz konwerter, który uruchomiliśmy na prawdziwym eksporcie w formacie VMware.

Źródło. "Architect creates open-source replacement for VM migration tool VMware has hidden" (Simon Sharwood, The Register, 2026-11-03). Pozostałe fakty mają linki w miejscu, w którym się pojawiają. Twoja umowa może różnić się od publicznych warunków, więc szczegóły licencji potwierdź u swojego resellera.

Co zmienił Broadcom, z datami

Data Zmiana Źródło
2023-12-11 Koniec sprzedaży licencji wieczystych i odnowień wsparcia; oferta ograniczona do subskrypcji VMware Cloud Foundation (VCF) i vSphere Foundation (VVF) Komunikat Broadcom, Krish Prasad
2025-03-28 Dystrybutor Arrow informuje partnerów, że od 2025-04-10 minimalne zamówienie rośnie z 16 do 72 rdzeni na linię produktów The Register
2026-01-26 Umowy z dostawcami chmury (VCSP) w EOG nie są odnawiane; otwarte transakcje do zamknięcia do 2026-03-31; potem program tylko na zaproszenie The Register, 2026-01-31
Aug-Sep 2026 VDDK usunięty z publicznego pobierania: "The VDDK is not a customer entitlement" (VDDK nie jest uprawnieniem klienta), dostęp przez wybranych partnerów TAP TechTarget, 2026-09-09
2026-11-03 OpenVDDK (autor: Andrija Panić): zamiennik drop-in dla libvixDiskLib.so.8.0.3 na licencji Apache, tylko do odczytu, który "contains no VMware code" (nie zawiera kodu VMware) The Register, 2026-11-03

Dwa zastrzeżenia. Minimum 72 rdzeni podał dystrybutor, a nie strona Broadcom, którą udało nam się znaleźć: artykuł Broadcom o liczeniu rdzeni (KB 313548, sprawdzone 2026-11-03) mówi "You must license a minimum of 16 physical cores for each CPU" (minimum 16 fizycznych rdzeni na każdy CPU), a część resellerów twierdzi, że minimalne zamówienie 72 rdzeni znów zniesiono. Poproś o liczbę rdzeni w ofercie na piśmie. Strona unijna też pozostaje otwarta: branżowe stowarzyszenie chmurowe CISPE wniosło w lipcu 2025 do Sądu UE o stwierdzenie nieważności zgody Komisji na fuzję (sprawa T-503/25); orzeczenia jeszcze nie znaleźliśmy.

Dlaczego VDDK ma znaczenie i które ścieżki go omijają

Biblioteka VDDK, libvixDiskLib, pozwala narzędziu czytać dyski maszyn wirtualnych, które wciąż działają w vSphere. The Register wymienia virt-v2v, nbdkit, importery Forklift / MTV, Apache CloudStack i własne skrypty firm wśród narzędzi, które ją ładują. Rozszerzenie VM Conversion firmy Microsoft dla Windows Admin Center (z vCenter do Hyper-V, z synchronizacją na ciepło przez Change Block Tracking) nadal ma status preview w swojej dokumentacji (aktualizacja 2026-02-20), a relacje z premiery wymieniają VDDK wśród wymagań. OpenVDDK to nowa opcja dla wszystkich tych narzędzi, z ostrzeżeniem autora, że raporty testerów to "not independently audited customer endorsements" (nie są niezależnie zweryfikowanymi rekomendacjami klientów).

Ścieżki bez VDDK według dokumentacji wejścia VMware w virt-v2v (sprawdzone 2026-11-03): eksport OVA (-i ova), pliki VM na NFS lub przez SSH (-i vmx, -it ssh), NFC oraz zwykła ścieżka HTTPS przez vCenter, którą dokumentacja nazywa "the slowest method" (najwolniejszą metodą). Kreator importu z ESXi w Proxmox VE, ogłoszony 2024-03-27, czyta dyski przez API ESXi za pomocą własnego systemu plików w przestrzeni użytkownika napisanego w Rust i był testowany z ESXi od 6.5 do 8.0 (forum Proxmox).

Dokąd się przenieść: pięć realistycznych celów

Cel Pasuje, gdy Na co uważać
Proxmox VE (KVM) na własnym sprzęcie 3+ hosty, zespół, który chce GUI i klastrowania Aktualizacje, storage (ZFS, Ceph) i wsparcie są po twojej stronie
OpenStack Wielu najemców, wszystko przez API Ciężki w utrzymaniu; opłaca się dopiero w dużej skali
Hyper-V (Windows Server) Środowisko głównie Windows, licencje Datacenter już opłacone Narzędzie Microsoftu wymaga najpierw sterowników Hyper-V w gościach Linux
Serwery w chmurze (KVM) Od kilku do kilkudziesięciu VM, bez chęci utrzymywania hypervisora Jeden import na VM, nowe adresy IP
Serwery dedykowane + własny hypervisor Stałe obciążenie, chcesz całą maszynę Hypervisor utrzymujesz i łatasz sam

Przenieś VM w pięciu krokach

  1. Inwentaryzacja i porządki. Zapisz firmware (BIOS lub EFI), kontroler dysku, typ karty sieciowej, statyczne adresy IP i każdą licencję powiązaną z adresem MAC. Usuń lub scal snapshoty, aby wyeksportować jeden aktualny dysk.
  2. Przygotuj gościa, póki działa jeszcze na VMware. Windows: zainstaluj teraz sterowniki virtio (virtio-win); gość Windows przeniesiony na dysk virtio bez nich nie uruchomi się. Linux: sterowniki virtio są w jądrze, ale initramfs w trybie host-only może je pominąć; sprawdź to przez lsinitramfs lub lsinitrd i w razie potrzeby przebuduj go.
  3. Eksport lub połączenie. Wyłącz VM i wyeksportuj OVF / OVA (vSphere Client "Export OVF Template" lub ovftool) albo pozwól, by virt-v2v lub kreator Proxmox pobrał ją sam.
  4. Konwersja. Sam dysk przez qemu-img, cały gość przez virt-v2v (który dostosowuje też sterowniki) albo bezpośrednio do Proxmox z OVF.
  5. Uruchom przez konsolę, potem posprzątaj. Sprawdź nazwę karty sieciowej i IP, usuń VMware Tools lub open-vm-tools, zainstaluj 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

To udokumentowane formy wywołań z podręcznika każdego narzędzia; tych trzech nie uruchamialiśmy tutaj. Konwersja, którą faktycznie uruchomiliśmy, jest poniżej.

Przetestowane: co naprawdę robi konwersja (ova2raw.js)

Aby pokazać poszczególne elementy, napisaliśmy konwersję w około 100 liniach Bun bez zależności. Skrypt otwiera OVA (zwykły tar), sprawdza manifest SHA-256, wypisuje sprzęt, którego wymaga OVF, rozpakowuje VMDK typu streamOptimized grain po grainie do rzadkiego (sparse) obrazu raw i sprawdza GPT. Podaliśmy mu oficjalny OVA Ubuntu 24.04, prawdziwy eksport w formacie VMware: noble-server-cloudimg-amd64.ova, build z 2026-10-17, którego SHA-256 zgadzał się z SHA256SUMS Ubuntu. Zapisz jako 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

Wynik, uruchomione na serwerze DCXV Cloud z Bun 1.4.4 dnia 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"

Trzy uruchomienia trwały na tym serwerze od 14.6 do 16.2 s czasu rzeczywistego. Plik raw ma rozmiar 10 GiB i zajmuje 1.8 GB na dysku.

Co mówi wynik przed przełączeniem

  1. VmxNet3 i VirtualSCSI to urządzenia VMware. Na KVM stają się virtio-net oraz virtio-blk lub virtio-scsi. Gość potrzebuje sterowników do obu przed pierwszym uruchomieniem, a interfejs sieciowy zwykle dostaje nową nazwę, więc statyczny IP przypisany do starej nazwy się nie podniesie. Pierwsze uruchomienie wykonaj przez konsolę.
  2. Firmware musi się zgadzać. Ten OVF niczego nie ustawia, więc jest to BIOS; dysk zawiera zarówno partycję BIOS boot, jak i partycję systemową EFI, więc uruchomi się w obu trybach. VM wyeksportowana z firmware=efi wymaga UEFI (OVMF) na docelowym hoście, inaczej nie znajdzie bootloadera.
  3. Thin zostaje thin tylko wtedy, gdy o to zadbasz. 10 GiB wirtualnie, 1.8 GB danych. Kopiuj narzędziami obsługującymi pliki rzadkie (cp --sparse=always, rsync -S) albo używaj qcow2, inaczej przesyłasz i przechowujesz zera.
  4. Manifest to twoja kontrola transferu. Sprawdzaj SHA-256 po każdej kopii między lokalizacjami: przerwany upload bez żadnych skarg skonwertuje się do dysku, który zawiedzie później.

Zaplanuj przestój

Przeprowadzka na zimno to eksport + transfer + konwersja + pierwsze uruchomienie. Zmierz każdy etap na jednej testowej VM, a potem pomnóż. Rachunek transferu (nasz, bez narzutu protokołu): 1.8 GB przy 1 Gbit/s to około 15 s, 1 TB około 2.2 godziny. Narzędzia na ciepło kopiują podczas pracy VM i na końcu wysyłają tylko zmienione bloki; testerzy cytowani przez The Register opisują przebiegi na zimno i na ciepło z Forklift i MTV. Dla baz danych i obciążonych aplikacji replikacja plus przełączenie DNS wygrywa z każdą kopią dysku: najpierw obniż TTL (zob. propagacja DNS i TTL) i skorzystaj z list kontrolnych w artykule jak przenieść się na serwer w chmurze.

Kiedy pasują serwery w chmurze lub dedykowane DCXV

  • Kilka VM, brak zespołu od hypervisora: nasze serwery w chmurze działają na KVM z dyskami virtio. W panelu Reinstalacja -> "Własny obraz (URL)" przyjmuje plik qcow2, raw lub vmdk przez https; obraz większy niż dysk planu powiększa dysk i jest rozliczany jako rozszerzenie dysku, a ustawienia sieci są stosowane tylko wtedy, gdy obraz ma cloud-init. Plany od EUR 15.00/mies. (2 vCPU, 4 GB RAM, 40 GB; sprawdzone 2026-11-03, bez VAT).
  • Dziesiątki VM lub własny klaster Proxmox: serwery dedykowane od EUR 210/mies., z wybranym przez ciebie hypervisorem.
  • Goście Windows: odsprzedajemy licencje Windows Server; zapytaj przed przeprowadzką, aby licencja była gotowa od pierwszego dnia.

Oba rozwiązania działają w naszych centrach danych Tier III w Pradze i Covilha.

Zaplanuj przeprowadzkę z nami

Uruchom ova2raw.js na jednej wyeksportowanej VM i wyślij linie ze sprzętem z jej wyniku na sales@dcxv.com albo uruchom serwer w chmurze i przetestuj import samodzielnie.

Odejście od VMware po Broadcom: sprawdzony plan migracji
clouddedicatedinfrastructure

Odejście od VMware po Broadcom: sprawdzony plan migracji

Broadcom skończył z licencjami wieczystymi, ograniczył partnerów i ukrył VDDK. Jak przenieść VM na KVM, Proxmox lub Hyper-V: daty i testowany konwerter OVA.

Propagacja DNS: 3 sekundy Cloudflare kontra Twój TTL
networkingcloudinfrastructure

Propagacja DNS: 3 sekundy Cloudflare kontra Twój TTL

Cloudflare skrócił opóźnienie budowania DNS do 3,3 s. Przełączenie serwera czeka na TTL, cache negatywny i 2 dni delegacji .com. Zmierzone na dwóch strefach.

10 000 głosów w radach miast USA: co znaczą dla klientów DC
clouddedicatedinfrastructure

10 000 głosów w radach miast USA: co znaczą dla klientów DC

Nowy zbiór danych koduje 10 202 wystąpienia o centrach danych w USA: 90,5% przeciw, woda na czele. Przeliczyliśmy go i wyjaśniamy, co to znaczy dla klientów.

Wsparcie i rachunki AWS: sprawdzony poradnik dla firm z UE
cloudpricingcompare

Wsparcie i rachunki AWS: sprawdzony poradnik dla firm z UE

Plany wsparcia AWS i ich ceny, opóźnione dane rozliczeniowe, koszt transferu, skrypt do kontroli rachunku i kiedy lepszy jest dostawca z UE ze stałą ceną.

Opóźnienie pamięci w chmurze: zmierzone, nie zgadnięte
clouddedicatedinfrastructure

Opóźnienie pamięci w chmurze: zmierzone, nie zgadnięte

Popularny wpis twierdzi, że zajęty CPU często po prostu czeka na RAM. Zmierzyliśmy opóźnienie od L1 do DRAM na naszym serwerze w chmurze i wyjaśniamy wnioski.