OpenShift VirtualizationSeries · Part 3 of 15

Understanding KubeVirt, VM and VMI

7 min read

VMware to OpenShift Virtualization — Article 3 of 15

Technical baseline: OpenShift Virtualization 4.20 and MTV 2.11 documentation. Reviewed 31 October 2026. Examples are instructional and have not been executed against a production cluster; check your installed release, support matrix, and environment before use.

KubeVirt adds virtual-machine resources and controllers to Kubernetes. Its most useful operational distinction is between a VirtualMachine, which expresses persistent management intent, and a VirtualMachineInstance, which represents a particular execution of that guest.

VM, VMI, pod, and disk are different objects

Relationship between VirtualMachine, VirtualMachineInstance, virt-launcher pod, node, DataVolume, PVC and PV
Figure 1. The VM is persistent intent; each VMI and launcher pod is one execution lifetime; disks have their own lifecycle through DataVolume, PVC and PV. Select the diagram to view it at full size.
Object Meaning What to inspect
VirtualMachine / VM Managed guest definition and lifecycle policy Run strategy, template, disks, interfaces
VirtualMachineInstance / VMI Current guest execution Phase, conditions, node, migration state
virt-launcher pod Kubernetes execution context for that instance Scheduling, volume attachment, container state
PVC Claim for persistent storage Binding, capacity, access mode, storage class
DataVolume CDI-managed data population abstraction Import/clone progress and conditions

These relationships are described in the KubeVirt architecture and VMI reference. A VM can exist while powered off with no active VMI. A new execution may have the same human-readable name while using a different Kubernetes UID.

Why the distinction matters

Suppose app01 exists but users cannot connect. Looking only at oc get vm does not establish whether a guest is running. Inspect the VMI, launcher pod, disks, and guest console. Conversely, deleting a launcher pod is not a clean declaration that the managed VM should remain powered off; its lifecycle policy may request another execution.

Persistent data needs its own protection. Whether deleting a VM also removes related storage depends on ownership references and the deletion workflow. Before deleting any VM, inspect PVC ownership and reclaim behavior, and verify that backups cover the disks you intend to preserve.

Run strategies

The spec.runStrategy field controls lifecycle behavior. Do not combine it with the older spec.running field in one manifest.

Matrix of KubeVirt run strategies Always, RerunOnFailure, Manual, Once and Halted showing behaviour after guest shutdown and after failure
Figure 2. spec.runStrategy decides what the VM controller does after a guest shutdown or an execution failure. Select the diagram to view it at full size.
Strategy Intended behavior
Always Keep a guest execution present, including after guest shutdown
RerunOnFailure Restart after qualifying infrastructure/execution failures; allow a normal guest shutdown to remain stopped
Manual Let explicit lifecycle actions control execution
Once Run one execution without automatic repeat
Halted Keep the VM stopped

The run-strategy reference provides the detailed semantics. RerunOnFailure does not guarantee recovery from every failure inside a guest, such as an application crash or a guest blue screen that leaves the virtual machine process alive.

A minimal, deliberately halted VM definition

This instructional example assumes namespace apps already exists and app01-root is an existing bootable PVC containing a compatible operating system. It does not create an OS image, user account, SSH key, or network service. The PVC’s storage configuration must suit your availability design.

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: app01
  namespace: apps
spec:
  runStrategy: Halted
  template:
    metadata:
      labels:
        app: app01
    spec:
      domain:
        cpu:
          cores: 2
        resources:
          requests:
            memory: 4Gi
        devices:
          disks:
            - name: rootdisk
              disk:
                bus: virtio
          interfaces:
            - name: default
              masquerade: {}
      networks:
        - name: default
          pod: {}
      volumes:
        - name: rootdisk
          persistentVolumeClaim:
            claimName: app01-root

Validate against the actual API before creating it:

oc apply --dry-run=server -f app01.yaml
oc apply -f app01.yaml
virtctl start app01 -n apps
oc get vm,vmi -n apps
oc describe vmi app01 -n apps

The second and third commands change the cluster. Server-side dry run checks admission and schema; it does not prove the guest will boot or the application will work. Use a lab namespace and a release-compatible virtctl binary.

Observe the right state

Read VM status to understand the requested and reported lifecycle. Read VMI conditions for execution and mobility. Read pod events for scheduling and setup. Read the guest console and application probes for operating-system and service health. Each view answers a different question.

Four views and the question each answers: VM status, VMI conditions, pod events and guest console or application probe
Figure 3. Each view answers a different question. Use all four before concluding where a problem lies. Select the diagram to view it at full size.

A useful inventory report includes namespace, VM name, desired run strategy, VMI presence, VMI phase, node, and application owner. Treat a missing VMI as a possible normal state for a stopped VM rather than automatically classifying it as an outage.

Observe a complete lifecycle in a lab

Start with the deliberately halted VM above. Confirm that the VM exists and that no running VMI is expected. Submit one start request, then observe the creation of the instance and its launcher pod. Record their UIDs and node placement.

Lifecycle timeline: halted VM, start request creates VMI and launcher pod, VMI running, stop removes the execution, a new start creates a new VMI UID while the PVC persists
Figure 4. Each start creates a new execution lifetime with a new UID. The VM definition and persistent disks continue across executions. Select the diagram to view it at full size.
oc get vm app01 -n apps
oc get vmi app01 -n apps
virtctl start app01 -n apps
oc get vmi app01 -n apps -w

The final watch runs until interrupted. Once the VMI exists, a bounded readiness wait is useful:

oc wait vmi/app01 -n apps --for=condition=Ready --timeout=180s

This checks a resource condition, not application readiness. Follow it with guest login, disk/mount verification, and an application transaction. If the timeout expires, inspect conditions and events rather than repeatedly starting the same VM.

Next, use the supported stop action in the lab and observe the remaining VM/PVC resources. A new start creates another execution lifetime; persistent disks should retain the intended data. The purpose of the exercise is to see the separation between definition, execution, and storage, not to rely on names as proof of continuity.

Interpreting conditions and phases

Treat conditions as structured evidence. Read the type, status, reason, message, and transition time together. A boolean copied into a report without its reason can hide whether the problem is expected, transient, or actionable.

Observation Possible interpretation Next check
VM present, no VMI Intentionally stopped or startup has not produced an instance Run strategy, VM conditions, events
VMI pending Execution exists but preparation/scheduling is incomplete Launcher events and disk readiness
VMI running, no application Guest or application not ready Console, listener, dependency checks
Different VMI UID after restart New execution lifetime Expected lifecycle and persistent data
VM configuration changed, runtime unchanged Change may need supported restart/update handling Feature behavior for the installed release

A status printer column is convenient for humans but should not be the only automation contract. Use the API fields appropriate to the task and handle absence explicitly.

Why deleting runtime objects is a poor power-control interface

The VM controller’s job is to reconcile desired lifecycle state. Removing a lower-level execution resource can therefore trigger recovery or another execution rather than a durable stop. It can also bypass the graceful shutdown path the application expects.

Use documented lifecycle operations and understand the selected run strategy. If an application requires orderly shutdown, define the guest shutdown behavior, timeout, and escalation in the operating procedure. A forced termination should be a deliberate recovery decision with data implications, not the default equivalent of a power button.

For investigation, gather oc describe output and relevant events before changing runtime objects. This preserves evidence about why the original instance was unhealthy.

Storage ownership and deletion review

Before deleting a VM, inspect its volumes and the corresponding DataVolumes/PVCs. Review owner references and the intended deletion workflow. Then inspect the bound PV’s reclaim policy and the backend’s retention behavior. The exact cascade depends on how the resources were created and how deletion is requested.

oc get vm app01 -n apps -o jsonpath='{.spec.template.spec.volumes}'
oc get dv app01-root -n apps -o yaml
oc get pvc app01-root -n apps -o yaml

These are inspection commands. They intentionally do not include deletion. A safe deletion checklist confirms the application owner, backup/restore evidence, data retention decision, and exact object identifiers before executing any destructive step.

Keep guest provisioning separate from VM lifecycle

The example manifest defines virtual hardware and attaches an existing disk. It does not create a guest account or configure the application. Cloud-init, Windows initialization mechanisms, image customization, and configuration management can fill those roles where supported.

Avoid embedding reusable passwords in VM definitions. Decide which system owns the hostname, IP configuration, packages, and application settings. Re-running a VM should not unexpectedly reset production configuration because an initialization source was treated as a general-purpose configuration manager.

Configuration changes and persistence

Change the managed VM definition for persistent configuration. Whether a change takes effect immediately or requires a restart depends on the specific feature and release. Do not assume that editing the VMI changes the source of truth for future executions. If GitOps manages the VM, update the repository and understand how its controller handles imperative lifecycle changes.

Use the CLI comparison for daily commands and storage guide before making disk or deletion decisions.


Explore the complete series

  1. VMware vs OpenShift Virtualization: Complete Technical Comparison
  2. OpenShift Virtualization Architecture Explained
  3. Understanding KubeVirt, VM and VMI
  4. VMware to OpenShift: Complete Migration Strategy
  5. MTV Architecture and Internal Working
  6. OpenShift Virtualization Networking Deep Dive
  7. OpenShift Virtualization Storage Deep Dive
  8. OpenShift VM Live Migration Explained
  9. OpenShift Cluster Sizing for Virtualization
  10. Migrating Windows VMs Using MTV
  11. Migrating Linux VMs Using MTV
  12. VMware PowerCLI vs OpenShift CLI
  13. Building OpenShift PowerShell Cmdlets
  14. OpenShift Virtualization Troubleshooting Guide
  15. Enterprise-Scale VMware to OpenShift Migration Architecture
Share this article LinkedIn X