Overview
The KubeVirt add-on lets an mk8s cluster run VM workloads (spec.type: vm). It installs the KubeVirt and CDI (Containerized Data Importer) operators and configures them for Control Plane: VM components are scoped to a dedicated VM node pool, the feature gates the platform needs are enabled, and boot-disk imports are wired through CDI.
Once the add-on is enabled and at least one VM-capable node is present, the location reports vm in its capabilities and VM workloads can be scheduled there.
Supported providers
Any provider whose nodes can expose hardware virtualization (/dev/kvm) — that means bare-metal nodes or instances with nested virtualization enabled. On AWS, nested virtualization is available on 8th-generation Intel instance types (c8i, m8i, r8i and variants); bare-metal (.metal) instances also work. On generic / BYOK clusters, use bare-metal hosts or VMs that pass through KVM.
Requirements
Setting up a cluster for VMs has four parts:A node pool with hardware virtualization
VM nodes must be able to run KVM. On AWS, enable nested virtualization on a supported instance type via
cpuOptions.nestedVirtualization; elsewhere use bare-metal / KVM-capable hosts.Label (and ideally taint) the VM node pool
KubeVirt’s components and the VMs themselves are scoped to nodes labelled
cpln.io/nodeType: vm. Add that label to the node pool. A matching taint cpln.io/nodeType=vm:NoSchedule is recommended to keep ordinary pods off the VM nodes — KubeVirt’s VM placement tolerates it.Enable the kubevirt add-on
Add
kubevirt to addOns. This installs the KubeVirt + CDI operators and their custom resources.Provide storage for boot disks
VM boot disks are imported by CDI into a PVC (backed by a volume set), so the cluster needs a working CSI / default
StorageClass. If your default StorageClass is block-mode, set scratchSpaceStorageClass to a filesystem-mode class so CDI has scratch space for imports.The dedicated
cpln.io/nodeType: vm node pool is what makes a node VM-capable. Without a labelled node, the KubeVirt components have nowhere to run and no VM workload can schedule.How to enable
Cluster manifest (AWS example)
A dedicated VM node pool with nested virtualization, the required label and taint, plus the add-on:YAML
/dev/kvm; nested-virtualization flags are provider-specific.
Console
When creating or editing the cluster, open Add-ons, toggle on KubeVirt, and make sure you have a node pool labelledcpln.io/nodeType: vm on VM-capable instances.
Configuration
| Option | Description |
|---|---|
scratchSpaceStorageClass | Filesystem-mode StorageClass CDI uses for import scratch space. Required when the cluster default StorageClass is block-mode; otherwise optional. |
YAML
DataVolumes, BlockVolume, and Sidecar feature gates, and the VM node placement — so you don’t set these yourself.
DNS
VM guests reach in-cluster services through a platform DNS forwarder. ThenodeLocalDns add-on (a per-node CoreDNS cache) is recommended alongside KubeVirt for reliable VM DNS. It is not strictly required — VM cloud-init falls back to TCP DNS (options use-vc) — but enabling it avoids edge cases.
Verify
After the add-on reconciles and a VM node is ready:- The cluster’s location reports
vmunder its workload-type capabilities. - A VM workload targeting this location schedules, imports its boot disk (watch
Importing boot disk: NN%in the deployment status), and boots.
Next steps
VM Workloads
Configure and run a VM
Publishing VM Images
Build boot images
Volume Sets
Storage for boot and data disks
mk8s Overview
Managed Kubernetes basics