This is a quick concept and workflow mapping for thinking about KubeVirt from an OpenStack Nova perspective.
| OpenStack / Nova | KubeVirt / OpenShift Virtualization | Notes |
|---|---|---|
| Nova server / instance | VirtualMachine + VirtualMachineInstance |
VirtualMachine is desired state; VirtualMachineInstance is the running guest. |
| Running libvirt domain | VirtualMachineInstance |
The live domain generated by KubeVirt. |
| Flavor | VirtualMachineInstancetype |
Defines vCPU, memory, CPU model, IOThreads policy, GPUs, host devices, etc. |
| Image | boot source: DataSource, PVC, DataVolume, containerDisk, registry import |
Source for the root disk. |
Glance image metadata / hw_* properties |
VirtualMachinePreference plus VM spec |
Captures guest hardware preferences: machine type, firmware, buses, topology, RNG, features. |
| Nova image + flavor selection | boot source + instancetype + preference | KubeVirt intentionally separates image/source, sizing, and guest hardware preferences. |
| Server create request | VirtualMachine manifest |
May reference an instancetype, preference, and boot source. |
| Compute host | Kubernetes node | Selected by Kubernetes scheduler plus KubeVirt constraints. |
| Nova scheduler | Kubernetes scheduler + KubeVirt admission/controllers | Placement is Kubernetes-native, with KubeVirt-specific validation. |
| Placement resource providers | Kubernetes nodes/resources/extended resources | GPUs, KVM, tun, vhost-net, etc. appear as pod resources/device plugin resources. |
| Neutron port/network | VMI network/interface definitions, Multus NADs, pod network | Depends on cluster networking setup. |
| Cinder volume | PVC / DataVolume | VM disks are Kubernetes storage resources. |
| Config drive / metadata service | cloud-init NoCloud/ConfigDrive, access credentials | Commonly specified as VM volumes. |
| Keypair injection | accessCredentials / cloud-init SSH keys |
Can source from Kubernetes Secret. |
| Console | virtctl console, virtctl vnc, serial console log |
Depends on guest/VM config. |
| libvirt XML | Generated in virt-launcher pod |
Usually inspected via virt-launcher logs or virsh dumpxml if RBAC permits exec. |
| nova live-migration | virtctl migrate |
Live migration of a running VMI. |
| nova resize | Stop VM, update instancetype/preference refs, start VM | No direct Nova-style confirm/revert transaction. |
| nova evacuate | KubeVirt node drain/eviction/live migration | Controlled by eviction strategy and migration policy. |
| Shelve/unshelve | Stop/start VM, possibly preserve PVCs | Not a perfect 1:1 mapping. |
| Delete server | Delete VirtualMachine; cleanup depends on DataVolume/PVC ownership |
PVC retention depends on how disks were created/owned. |
The persistent desired-state object. Similar to Nova's instance record plus desired power state.
apiVersion: kubevirt.io/v1
kind: VirtualMachine
spec:
runStrategy: Always
instancetype:
kind: VirtualMachineInstancetype
name: devstack-8c8g
preference:
kind: VirtualMachinePreference
name: devstack
template:
spec:
domain: {}
volumes: []
networks: []The live running instance. Similar to the active libvirt domain.
oc get vmi -n <namespace>
oc describe vmi <name> -n <namespace>A stopped VM has no VMI.
Closest to a Nova flavor.
Example:
apiVersion: instancetype.kubevirt.io/v1beta1
kind: VirtualMachineInstancetype
metadata:
name: devstack-8c8g
spec:
cpu:
guest: 8
model: host-passthrough
memory:
guest: 8Gi
ioThreadsPolicy: autoClosest to image hardware metadata / guest hardware policy.
Example:
apiVersion: instancetype.kubevirt.io/v1beta1
kind: VirtualMachinePreference
metadata:
name: devstack
spec:
cpu:
preferredCPUTopology: cores
devices:
preferredDiskBus: virtio
preferredInterfaceModel: virtio
preferredRng: {}
features:
preferredKvm: {}
firmware:
preferredEfi:
secureBoot: false
machine:
preferredMachineType: q35Closest to a Glance image reference, but implemented through CDI/PVCs.
A boot source can advertise default instancetype and preference labels:
metadata:
labels:
instancetype.kubevirt.io/default-instancetype: devstack-8c8g
instancetype.kubevirt.io/default-preference: devstackapiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: my-vm
spec:
runStrategy: Always
instancetype:
kind: VirtualMachineInstancetype
name: devstack-8c8g
preference:
kind: VirtualMachinePreference
name: devstack
dataVolumeTemplates:
- metadata:
name: my-vm-rootdisk
spec:
sourceRef:
kind: DataSource
name: debian-13
namespace: my-namespace
storage:
resources:
requests:
storage: 80Gi
storageClassName: rh-internal-nfs
template:
spec:
domain:
devices:
interfaces:
- name: default
masquerade: {}
networks:
- name: default
pod: {}
volumes:
- name: rootdisk
dataVolume:
name: my-vm-rootdiskApply:
oc apply -f vm.yaml -n <namespace>
oc get vm,vmi,dv,pvc -n <namespace>virtctl start <vm> -n <namespace>
virtctl stop <vm> -n <namespace>
virtctl restart <vm> -n <namespace>Equivalent mental model:
start: create a VMI from the VM desired state.stop: remove the VMI while keeping the VM object and disks.restart: recreate the VMI.
oc get vm <vm> -n <namespace> -o yaml
oc get vmi <vm> -n <namespace> -o yaml
oc describe vm <vm> -n <namespace>
oc describe vmi <vm> -n <namespace>Useful compact inspection:
oc get vmi <vm> -n <namespace> -o jsonpath='cpu={.spec.domain.cpu}{"\n"}memory={.spec.domain.memory}{"\n"}ioThreads={.spec.domain.ioThreadsPolicy}{"\n"}firmware={.spec.domain.firmware}{"\n"}features={.spec.domain.features}{"\n"}machine={.spec.domain.machine}{"\n"}'virtctl expand shows the VM after instancetype/preference expansion.
virtctl expand --vm <vm> -n <namespace>
virtctl expand --vm <vm> -n <namespace> -o jsonThis is inspect-only; it does not modify the VM.
KubeVirt does not provide a Nova-style resize transaction with confirm/revert. The closest cold resize workflow is:
- Stop the VM.
- Patch
spec.instancetypeand/orspec.preference. - Remove old
revisionNamepins. - Start the VM.
- Validate the new VMI.
Example:
NS=<namespace>
VM=<vm>
virtctl stop "$VM" -n "$NS"
# Wait for VMI deletion
oc get vmi "$VM" -n "$NS"
oc patch vm "$VM" -n "$NS" --type=merge -p '{
"spec": {
"instancetype": {
"kind": "VirtualMachineInstancetype",
"name": "devstack-8c8g"
},
"preference": {
"kind": "VirtualMachinePreference",
"name": "devstack"
}
}
}'
virtctl start "$VM" -n "$NS"Validate:
oc get vm,vmi -n "$NS" | grep "$VM"
oc get vmi "$VM" -n "$NS" -o jsonpath='{.spec.domain.cpu}{"\n"}{.spec.domain.memory}{"\n"}'KubeVirt captures instancetype/preference revisions on VM creation/start:
spec:
instancetype:
name: devstack-8c8g
revisionName: ...
preference:
name: devstack
revisionName: ...This is similar to Nova preserving flavor/image metadata on an instance. Editing the global instancetype or preference does not automatically mutate existing VMs. To consume a new definition, update the VM reference and clear/recreate the revision reference by replacing the field without revisionName.
virtctl migrate <vm> -n <namespace>Watch:
oc get vmi <vm> -n <namespace> -w
oc get virtualmachineinstancemigrations -n <namespace>This maps to Nova live migration, not resize.
virtctl console <vm> -n <namespace>
virtctl vnc <vm> -n <namespace>
virtctl ssh <user>@<vm> -n <namespace>Guest agent helpers, if installed/running:
virtctl guestosinfo <vm> -n <namespace>
virtctl fslist <vm> -n <namespace>
virtctl userlist <vm> -n <namespace>If RBAC permits exec into virt-launcher:
POD=$(oc get pod -n <namespace> -l vm.kubevirt.io/name=<vm> -o jsonpath='{.items[0].metadata.name}')
oc exec -n <namespace> "$POD" -c compute -- virsh dumpxml 1If exec is blocked, inspect virt-launcher logs for the QEMU command line:
oc logs -n <namespace> "$POD" -c compute | grep -i qemu-kvmExample check for Free Page Reporting:
oc logs -n <namespace> "$POD" -c compute | grep -i free-page-reportingA QEMU arg like this indicates FPR is enabled:
-device ...,"virtio-balloon...","free-page-reporting":true,...
| Nova/Cinder concept | KubeVirt concept |
|---|---|
| Root disk from image | DataVolume cloning/importing from DataSource/PVC |
| Cinder volume | PVC |
| Boot from volume | VM volume backed by PVC/DataVolume |
| Volume attach | Add VM volume / hotplug volume if supported |
| Ephemeral disk | containerDisk or ephemeral volume patterns |
Common commands:
oc get dv,pvc -n <namespace>
oc describe dv <name> -n <namespace>
oc describe pvc <name> -n <namespace>
virtctl addvolume <vm> --volume-name <name> -n <namespace>
virtctl removevolume <vm> --volume-name <name> -n <namespace>| Nova/Neutron concept | KubeVirt concept |
|---|---|
| Port | VMI interface/network attachment |
| Tenant network | Pod network or Multus network |
| Security groups | Kubernetes/OVN/network policy depending on platform |
| Floating IP | Service/route/load balancer or external networking integration |
Simple pod-network masquerade example:
networks:
- name: default
pod: {}
domain:
devices:
interfaces:
- name: default
masquerade: {}OpenShift/Kubernetes quotas apply to KubeVirt through the resources consumed by VMs:
- pods
- CPU/memory requests and limits
- PVC count
- storage requests
- services/load balancers if exposed
- extended resources such as KVM/tun/vhost-net/GPU devices
Useful checks:
oc get resourcequota -n <namespace>
oc describe quota -n <namespace>
oc get appliedclusterresourcequota -n <namespace>
oc describe appliedclusterresourcequota -n <namespace>
oc describe limitrange -n <namespace>VirtualMachineInstancetype.spec.cpu.guestdefines guest vCPU count.VirtualMachineInstancetype.spec.memory.guestdefines guest-visible RAM.memory.overcommitPercentcan reduce the virt-launcher memory request, but increases risk.- CPU overcommit is generally controlled by Kubernetes requests/limits and whether dedicated CPU placement is used.
dedicatedCPUPlacementis closer to pinned CPUs / dedicated pCPUs.- CPU topology is influenced by
VirtualMachinePreference.spec.cpu.preferredCPUTopology.
Example topology preference:
spec:
cpu:
preferredCPUTopology: coresCommon preference settings for Linux/q35/UEFI without secure boot:
spec:
firmware:
preferredEfi:
secureBoot: false
machine:
preferredMachineType: q35Nova flavor -> VirtualMachineInstancetype
Nova image -> DataSource / PVC / DataVolume / boot source
Nova image hw metadata -> VirtualMachinePreference
Nova server -> VirtualMachine
Running libvirt domain -> VirtualMachineInstance
Nova resize -> stop, patch instancetype/preference, clear revisions, start
Nova live migration -> virtctl migrate
Cinder volume -> PVC
Config drive/cloud-init -> cloudInitNoCloud/cloudInitConfigDrive volume