If our introduction to KubeVirt covered what it is and why it exists, this is the deeper layer: the actual components that turn a VirtualMachine manifest into a running virtual machine, and how they fit into the rest of Kubernetes.

The control-plane components

virt-api extends the Kubernetes API server with the KubeVirt custom resources — VirtualMachine, VirtualMachineInstance, and related objects — so they're validated and served exactly like built-in Kubernetes types. virt-controller watches those objects and reconciles them: when a VirtualMachine says "running: true," virt-controller is what creates the corresponding VirtualMachineInstance and the pod that will run it.

The node-level components

virt-handler runs as a DaemonSet, one instance per node, acting as the local agent that starts, monitors and reports on VMs scheduled to that node. virt-launcher runs inside a pod — one per VM — and is the process that actually wraps libvirtd and QEMU, the same virtualization stack underneath most KVM-based platforms. From the scheduler's perspective, a VM is a pod; from the hypervisor's perspective, it's a normal QEMU process — KubeVirt is the layer that keeps both views consistent.

The object model: VM vs. VMI

VirtualMachine is the durable, desired-state object — it persists whether the VM is running or stopped, the way a Deployment persists regardless of current replica count. VirtualMachineInstance is the actual running instance, created and destroyed as the VM starts and stops. This split is what makes start/stop, and patterns like VirtualMachineInstanceReplicaSets for scaling identical VMs, possible without redefining the VM itself each time.

Networking

By default, a VM's primary network interface attaches through the cluster's standard CNI plugin using a bridge or masquerade binding, so it behaves like any other pod on the cluster network. Workloads that need additional or specialized interfaces — a second NIC on a different network, for instance — attach them through Multus, layering extra network attachments onto the same pod.

Storage

A VM's disk can be a lightweight containerDisk — a read-only image baked into a container image, good for ephemeral or template use — or a PersistentVolumeClaim-backed disk for anything that needs to persist and follow the VM through migrations, going through the same CSI drivers and StorageClasses as any other Kubernetes storage.

Live migration

Migrating a running VM to another node is handled as its own object — a VirtualMachineInstanceMigration — that virt-controller and virt-handler coordinate to transfer the VM's memory and state with minimal downtime, the mechanism behind moving VMs off a node before it drains for maintenance.

Where a management platform fits

None of this architecture is visible to an operator clicking "migrate" in a console — and that's the point. AetherVirt operates on top of this exact object model, turning virt-controller reconciliation and VirtualMachineInstanceMigration objects into a one-click action with progress tracking, RBAC checks and an audit log entry.