Broadcom’s acquisition of VMware changed the economics of enterprise virtualization overnight. License costs doubled or tripled for many organizations, and the perpetual license model that teams relied on for budget predictability is gone. If you are reading this, you are probably feeling that pressure right now.
KubeVirt is emerging as the primary open-source alternative. It lets you run virtual machines on Kubernetes with no license fees, using commodity hardware and the same orchestration layer you already use for containers. The project is mature, backed by Red Hat and the CNCF (currently an Incubating project), and used in production by organizations across industries.
But migration is not as simple as “lift and shift.” VMware and Kubernetes have fundamentally different architectures, different networking models, different storage paradigms, and different operational workflows. Rushing into migration without a plan is the fastest path to a failed project and a frustrated team.
This guide walks you through the planning phase: assessing your VMware estate, mapping concepts between platforms, choosing a migration path, designing your target architecture, and building a phased runbook that reduces risk at every step. By the end, you will have a clear plan that you can take to your team and your leadership.
This is the planning guide. The hands-on conversion tutorial, where you will use virt-v2v to convert VMware VMs to KubeVirt, is covered in Part 2 of this series.
Step 1: Assess Your Current VMware Estate
Before migrating anything, you need a clear inventory. This sounds obvious, but most organizations underestimate how much institutional knowledge is locked inside their vCenter. VMs accumulate over years, and documentation drifts. Start by documenting every VM you plan to migrate.
For each VM, capture the following:
| Field | What to Capture | Why It Matters |
|---|---|---|
| OS Type | Windows/Linux, version | KubeVirt supports both, but Windows needs specific drivers (virtio-win) |
| Disk Format | VMDK thin/thick, size | Determines conversion method and storage requirements |
| CPU/Memory | vCPU count, RAM | Maps directly to KubeVirt resource requests |
| Network | vSwitch/NSX, VLANs, static IPs | Networking is the hardest part of the migration |
| Storage | Datastore type, IOPS needs | Drives StorageClass selection on the Kubernetes side |
| Dependencies | Other VMs, external services | Determines migration order |
| GPU | Passthrough devices | Requires IOMMU configuration on Kubernetes nodes |
Use vCenter’s export functionality or tools like RVTools to generate this inventory automatically. RVTools is particularly useful because it exports to spreadsheets, which makes it easy to sort, filter, and share with your team.
While you are building this inventory, identify VMs that are candidates for containerization instead of migration. If a workload is already stateless, runs a single application process, and has no dependency on the underlying OS, it probably should not be a VM at all. Those workloads should skip the VM step entirely and move straight to containers. Your migration project is a good opportunity to make that call.
Step 2: Map VMware Concepts to KubeVirt
This is the mental model shift that your team needs to internalize before touching any tooling. VMware and KubeVirt solve the same problem — running virtual machines — but they use completely different abstractions. If your team tries to operate KubeVirt like they operate vCenter, they will struggle.
Here is the mapping:
| VMware Concept | KubeVirt Equivalent | Notes |
|---|---|---|
| ESXi Host | Kubernetes Node | Nodes run KVM via the virt-handler DaemonSet |
| vCenter | Kubernetes API Server | All management through kubectl or the API |
| Virtual Machine | VirtualMachine CR | Persistent definition that survives restarts |
| VM Instance (running) | VirtualMachineInstance | Ephemeral runtime object, similar to a Pod |
| Datastore | StorageClass + PV | Ceph, Longhorn, local-path, or cloud volumes |
| VMDK | DataVolume (QCOW2) | CDI handles import and format conversion |
| vSwitch | CNI (Calico, Cilium) | Pod networking provides default connectivity |
| Port Group / NSX Segment | NetworkAttachmentDefinition | Multus required for Layer 2 or multiple NICs |
| vMotion | Live Migration | KubeVirt supports live migration with shared storage |
| Snapshot | VolumeSnapshot | CSI driver must support snapshots |
| Template | VM with DataVolumeTemplate | Clone from a golden image |
| Resource Pool | Namespace + ResourceQuota | Kubernetes-native resource management |
The most important shift is operational. In VMware, you manage infrastructure through a GUI (vCenter) with point-and-click workflows. In KubeVirt, everything is a YAML manifest applied through kubectl or virtctl. Your infrastructure becomes code, which is a significant advantage for automation and reproducibility, but it requires a different skill set.
Spend time with your team reviewing this mapping. Make sure everyone understands where their familiar VMware concepts land in the Kubernetes world before you start migrating workloads.
Step 3: Choose Your Migration Path
There are three approaches, and most organizations end up using a mix of all three.
Path A: Forklift (Migration Toolkit for Virtualization)
Forklift is an open-source tool (part of the Konveyor community project, and the upstream of Red Hat’s Migration Toolkit for Virtualization) that automates bulk VM migration from VMware to KubeVirt. It connects directly to your vCenter, discovers VMs, converts disk images, and imports them into your Kubernetes cluster.
This is the right choice for large estates with 50 or more VMs, where manual conversion would take too long. Forklift handles the repetitive work: disk conversion, network mapping, and VM creation. It also provides a web UI for tracking migration progress, which is useful for reporting to stakeholders.
The trade-off is that Forklift is another tool to install, configure, and manage. It requires vCenter API access, and you need to understand its mapping model (how it translates VMware networks and storage to Kubernetes resources). For small environments, the setup overhead may not be worth it.
Path B: Manual Conversion with virt-v2v
Use libguestfs virt-v2v to convert VMDK files to QCOW2 format, then import them into KubeVirt via the Containerized Data Importer (CDI). This gives you full control over every step of the process, with no additional tooling beyond virt-v2v and kubectl.
This path is best for smaller estates, air-gapped environments where you cannot install Forklift, or teams that want to understand every detail of the conversion process. It is also the right choice for VMs that need special handling — custom drivers, unusual disk layouts, or non-standard configurations.
The trade-off is more manual work per VM. Each conversion requires running virt-v2v, uploading the resulting image, creating the DataVolume, and writing the VirtualMachine manifest. Part 2 of this series walks through this process step by step.
Path C: Rebuild (Re-platform)
Instead of migrating the VM, containerize the application or rebuild it on Kubernetes-native services. If a workload is already stateless, runs a standard application stack (Node.js, Python, Java), and does not depend on specific OS-level configuration, it is a better candidate for containerization than VM migration.
This is the highest effort per workload, but it results in the best long-term architecture. Containers are lighter, faster to deploy, and easier to scale than VMs. If you are going through the effort of leaving VMware, consider whether some workloads should leapfrog VMs entirely.
Tip: Most organizations use a mix of all three paths. Containerize what you can (Path C), bulk-migrate standard VMs with Forklift (Path A), and manually convert the tricky ones with virt-v2v (Path B). Categorize each VM in your inventory by the path that makes the most sense.
flowchart TD
Start[VM from VMware inventory]
Q1{Stateless app
+ standard stack?}
Q2{50+ similar VMs
to migrate?}
Q3{Special drivers
or unusual config?}
Start --> Q1
Q1 -->|Yes| Rebuild["Path C: Rebuild as container
(highest long-term value)"]
Q1 -->|No| Q2
Q2 -->|Yes| Forklift["Path A: Forklift
(automated bulk migration)"]
Q2 -->|No| Q3
Q3 -->|Yes| V2V["Path B: virt-v2v manual
(full control per VM)"]
Q3 -->|No| V2V
Step 4: Design Your Target Architecture
With your inventory complete and migration paths assigned, you need to design the Kubernetes cluster that will host your VMs. Three areas require the most attention: compute, storage, and networking.
Compute Sizing
Each KubeVirt VM runs inside a virt-launcher pod. The pod requests the same CPU and memory as the VM, so your Kubernetes nodes need enough capacity to host the VMs you are migrating, plus overhead.
Plan for the same total capacity as your VMware estate, plus 15-20% overhead for Kubernetes system components (kubelet, kube-proxy, CoreDNS) and the KubeVirt stack itself (virt-controller, virt-handler, virt-api). If you are running a storage solution like Ceph on the same nodes, add another 10-15% for storage daemons.
For GPU workloads, nodes need IOMMU enabled in the BIOS and kernel. Add intel_iommu=on or amd_iommu=on to your GRUB configuration, depending on your processor vendor. GPU passthrough in KubeVirt works well, but it requires upfront configuration that you do not want to discover you need on migration day.
Storage Backend
This is the most critical decision in your target architecture. Your storage choice determines whether you can use live migration, how your backups work, and what performance your VMs will get.
Ceph (via Rook): Distributed storage that supports RWX access mode, which is required for live migration. Production-grade and battle-tested, but higher operational complexity. If you are migrating a large VMware estate and need live migration, Ceph is the standard choice.
Longhorn: Simpler distributed storage, well-suited for mid-size deployments. Longhorn’s KubeVirt support is growing, and it is easier to operate than Ceph for smaller teams.
Local storage (hostpath-provisioner): Best raw performance because there is no network overhead. However, VMs using local storage are pinned to the node where their data lives. No live migration support — node maintenance requires VM shutdown.
Cloud volumes (EBS, Persistent Disk): Works if you are running Kubernetes on a cloud provider. Be aware of single-AZ constraints for block volumes and the IOPS limits of standard volume types.
Warning: Live migration requires shared storage with RWX (ReadWriteMany) access mode. If you choose local storage, VMs cannot be migrated between nodes. Node maintenance, kernel upgrades, and hardware failures all require VM shutdown and restart. Make this trade-off consciously.
Networking
Default pod networking through Calico or Cilium works for most VMs. Each VM gets a pod IP address and can communicate with other pods, services, and external endpoints through standard Kubernetes networking.
The complications start when your VMs need Layer 2 network access. Many legacy applications expect to see broadcast traffic, use ARP for discovery, or require specific VLANs. Standard Kubernetes CNIs operate at Layer 3 (IP routing), which means these Layer 2 expectations break.
For VMs that need Layer 2 access, install Multus CNI and create NetworkAttachmentDefinitions with bridge or macvtap plugins. Multus allows you to attach multiple network interfaces to a single pod (or VM), so a VM can have one interface on the pod network and another on a bridged Layer 2 segment.
| Requirement | CNI Recommendation |
|---|---|
| Basic pod networking only | Calico or Cilium |
| Layer 2 access needed | Multus + bridge or macvtap |
| Multiple NICs per VM | Multus (mandatory) |
| Network policies | Calico or Cilium |
Step 5: Plan Your Network Migration
Networking deserves its own section because it is where most VMware-to-KubeVirt migrations fail. Storage is a close second, but networking failures are more subtle and harder to debug.
IP Address Management
VMs in KubeVirt get pod IPs by default, which are assigned by the CNI and change if the VM is rescheduled to a different node. If your VMs have hardcoded IP addresses, static DNS entries, or application configurations that reference specific IPs, you have two options:
- Use Multus with a bridge plugin and a DHCP server on the same Layer 2 segment, so VMs get predictable IPs from your existing DHCP infrastructure.
- Assign static IPs via cloud-init or the QEMU guest agent during VM creation.
Neither option is as smooth as VMware’s networking model, where a VM keeps its IP regardless of which host it runs on. Plan for this friction and allocate time for testing.
NSX to Kubernetes Mapping
If you are running NSX-T or NSX-V, each segment or port group needs a corresponding NetworkAttachmentDefinition in Kubernetes. Document every segment, which VMs use it, and what Layer 2 or Layer 3 properties it provides. This mapping exercise is tedious but essential — missing a network segment during migration means a VM comes up without connectivity to a critical dependency.
DNS Updates
Update DNS records to point to the new KubeVirt VM IP addresses. Plan for a dual-run period where both VMware and KubeVirt versions of a VM are running, and use DNS or load balancer changes to shift traffic. Do not cut over DNS and decommission the VMware VM in the same maintenance window.
Warning: Layer 2 and Layer 3 friction is the number one technical issue in KubeVirt networking. Standard Kubernetes CNIs operate at Layer 3 (IP routing), but many legacy VMs expect Layer 2 behavior (ARP, broadcast, DHCP). If your VMs need Layer 2, you must use Multus with a bridge or macvtap plugin. Test this configuration early in your migration, not during production cutover.
Step 6: Build Your Migration Runbook
A phased approach reduces risk. Do not try to migrate everything at once.
Phase 1: Dev/Test VMs (Week 1-2)
Start with non-critical development and test VMs. These are your learning environment. Migrate them, validate that networking works, check storage performance, and confirm that applications behave correctly. Use this phase to build team confidence with the tooling and to discover issues in a low-stakes environment.
Document every issue you encounter and how you resolved it. This documentation becomes your playbook for the production phases.
Phase 2: Stateless Production VMs (Week 3-4)
Migrate production VMs that are stateless or easily replaceable: web servers, API gateways, reverse proxies, and similar workloads. Run them in parallel with the VMware versions for one to two weeks, shifting traffic gradually through DNS changes or load balancer updates.
This phase validates that KubeVirt can handle production traffic and that your monitoring, alerting, and incident response workflows work with the new platform.
Phase 3: Stateful Production VMs (Week 5-8)
Databases, file servers, and VMs with persistent state are the hardest to migrate. They require careful data migration, validation of data integrity, and planned maintenance windows for the final cutover.
For databases, consider using replication to keep the VMware and KubeVirt instances in sync during the transition. Cut over by promoting the KubeVirt replica and updating connection strings. This minimizes downtime and gives you a fast rollback path.
Phase 4: Decommission VMware (Week 9+)
Once all workloads are validated on KubeVirt, decommission your ESXi hosts and vCenter. Reallocate the hardware to Kubernetes nodes if it meets your requirements, or retire it. Cancel or downgrade your VMware licenses.
Do not rush this phase. Keep VMware running until you are confident that every migrated workload is stable. The cost of running both platforms for an extra week or two is far less than the cost of a failed migration with no rollback.
Risk Mitigation
Four strategies will protect you during migration:
Rollback strategy. Keep VMware running during the entire migration period. For each VM, maintain the ability to revert to the VMware version until the KubeVirt version has been validated in production for at least one full business cycle (typically one to two weeks).
Performance baseline. Benchmark key VMs on VMware before migration. Capture CPU utilization, memory usage, disk IOPS, and network throughput. After migration, run the same benchmarks on KubeVirt and compare. If performance drops significantly, investigate before migrating the next batch.
Dual-run period. Budget for running both platforms simultaneously for two to four weeks. This costs more in infrastructure but eliminates the risk of a “big bang” migration where everything moves at once and there is no fallback.
Skills gap. Your team knows VMware. They know vCenter, ESXi, vMotion, and the VMware ecosystem. KubeVirt uses different tools: kubectl, virtctl, Kubernetes RBAC, and YAML manifests. Plan training time before the migration starts, not during it. The KubeVirt user guide and the other tutorials in this series are a good starting point.
Next Steps
With your plan in place, you are ready to start the hands-on work:
- Converting VMware VMs to KubeVirt: A Step-by-Step Guide with virt-v2v (coming soon) — Part 2 of this series covers the actual conversion process
- Troubleshooting KubeVirt: CNI Conflicts, CDI Errors, and Common Fixes — for the issues you will hit during migration
- Installing KubeVirt on a Kubernetes Cluster — set up your target environment before you start migrating
Summary
Migrating from VMware to KubeVirt is a significant infrastructure project, but it is entirely achievable with the right plan. Start by inventorying your VMware estate and documenting every VM’s configuration, dependencies, and network requirements. Map VMware concepts to their KubeVirt equivalents so your team understands the new platform. Choose migration paths — Forklift for bulk migration, virt-v2v for manual control, and containerization where it makes sense. Design your target architecture with particular attention to storage (shared storage is required for live migration) and networking (Layer 2 friction is the most common failure point). Execute in phases, starting with dev/test and working up to stateful production workloads. Keep VMware running as a rollback option until you are confident in the new platform.
The planning phase is the foundation. Get it right, and the execution becomes methodical. Skip it, and you will spend more time firefighting than migrating.
