- Authors

- Name
- Youngju Kim
- @fjvbn20031
- Introduction
- Why Split Into Three Objects
- VirtualMachine Is "Persistent Intent"
- VirtualMachineInstance Is the Running Guest's Substance
- Why Is VMI Status So Extensive
- VirtualMachineInstanceMigration Is a "Work Request"
- Understanding Object Relationships in One Diagram
- Design Philosophy Visible in schema.go
- Why Weren't VM and VMI Merged
- What Operators Should Look at First in Status
- Common Misconceptions
- Conclusion
Introduction
When following KubeVirt's structure, the first types you encounter are VirtualMachine, VirtualMachineInstance, and VirtualMachineInstanceMigration. The similar names can be confusing at first, but if you cannot distinguish these three objects, the subsequent controller, migration, and state tracking logic all become blurry.
This article focuses on staging/src/kubevirt.io/api/core/v1/types.go and schema.go to organize what each object represents among intent, running instance, and one-time move request.
Why Split Into Three Objects
It becomes easy to understand by recalling Kubernetes' basic patterns.
- A Deployment represents "desired state."
- A Pod represents "currently running instance."
- A Job represents "a task to perform once."
KubeVirt adopts a similar separation.
VirtualMachine: long-term VM intent and operational policyVirtualMachineInstance: the currently alive guest instanceVirtualMachineInstanceMigration: a work object to move a specific VMI to another node
This separation is necessary so that start, stop, restart, migration, eviction, and status reflection don't get tangled with each other.
VirtualMachine Is "Persistent Intent"
VirtualMachine is a higher-level object representing "how I want to maintain this VM." Users typically declare templates, run strategies, and data volume connection policies here.
The key point is that VirtualMachine does not directly mean the guest process itself. The actual execution entity is the VirtualMachineInstance.
When Is VirtualMachine Useful
- When you want to maintain the same intent even after powering off and on
- When you want to separate operational policy from state
- When you want to manage start or stop requests declaratively
In other words, VirtualMachine handles "should this VM exist?" while VirtualMachineInstance handles "where and how is it currently running?"
VirtualMachineInstance Is the Running Guest's Substance
VirtualMachineInstance, abbreviated as VMI, is KubeVirt's core runtime object. In types.go, this object is described as a runtime definition with both spec and status.
In practice, the object most frequently observed by controllers and node agents is also the VMI. The reason is simple. VMI is the center of runtime state including Pod creation, node assignment, network status, migration state, and guest agent information.
Important Fields in VMI Spec
domain: guest hardware requirements like CPU, memory, disks, NICsnodeSelector,affinity,tolerations: which nodes it can go tovolumes: what storage to attach to the guestnetworks: what networks to connect to guest NICsterminationGracePeriodSeconds: grace time between shutdown signal and forced termination
In other words, the VMI spec represents "what does the runtime need to prepare to run this guest right now?"
Why Is VMI Status So Extensive
VirtualMachineInstanceStatus is richer than you might think. This is important because KubeVirt is not a single monolithic daemon but rather multiple controllers and node components cooperating in a choreography pattern. Each component looks at status to decide its next action.
Key important fields include:
NodeName: which node the VMI is currently running onPhase: high-level state like Pending, Scheduling, RunningConditions: detailed flags like paused, agent connected, migratableInterfaces: guest and Pod interface mapping statusMigrationState: migration progressMigrationMethod: whether it's live migration or block migrationMigrationTransport: which transport to useActivePods: which launcher Pods are alive for a given VMI
ActivePods is especially important during migration. Normally it appears as one Pod per VM, but during migration, source and target Pods can briefly coexist.
VirtualMachineInstanceMigration Is a "Work Request"
Many users think of migration as a button inside VMI status, but KubeVirt uses a separate CRD. When a VirtualMachineInstanceMigration object is created, the controller sees it and starts migration orchestration.
The advantages of this design are clear:
- Migration can be tracked as an independent, auditable object
- Policy application becomes easier
- State transitions can be modeled as a separate lifecycle
- Failure reasons can be recorded per work unit
Looking at the migrate handler in pkg/virt-api/rest/lifecycle.go, the migrate request is actually translated internally into a VirtualMachineInstanceMigration object creation. In other words, the user's "migrate" button click ultimately becomes "migration CR creation."
Understanding Object Relationships in One Diagram
VirtualMachine
-> Long-lived object with template/spec/policy
-> Induces VMI when execution is needed
VirtualMachineInstance
-> Currently running guest instance
-> Center of Pod, node, network, storage, migration state
VirtualMachineInstanceMigration
-> One-time work object to move a specific VMI
-> Controller initiates target Pod creation and handoff
This structure is intended to avoid mixing "desired state," "runtime instance," and "operation request."
Design Philosophy Visible in schema.go
Looking at schema.go, you can see that fields like network, volume, CPU, memory, firmware, launch security, and access credentials are very richly defined inside the VMI spec. This means KubeVirt is not simply a "QEMU execution wrapper" but rather a layer that makes guest hardware and operational environment declarable in Kubernetes API form.
Conversely, the status side is designed to be orchestration-friendly. For example, network interface status, guest OS info, and migration state contain both guest internal information and cluster orchestration state. This is a different texture from container Pod status.
Why Weren't VM and VMI Merged
This is an important question. If everything were put in a single object, implementation might look simpler. But in actual operations, the following problems arise:
1. Hard to Maintain the Same "Intent" After Power Cycling
When running instance state and user's persistent settings are mixed in one object, the lifecycle becomes complex.
2. Status Churn Becomes Too Large
Runtime state changes frequently, but intent does not. Separating them organizes watch costs and reconcile responsibilities.
3. Hard to Model Operations Like Migration
A separate work object is needed to cleanly handle policies, queuing, priorities, and failure reasons.
What Operators Should Look at First in Status
In practice, you look at all three objects, but priorities differ by situation.
When a VM Won't Start
VirtualMachine's run strategy- Whether VMI was created
- How far VMI phase has progressed
When Networking or Booting Is Abnormal
- VMI status
Interfaces ConditionsActivePods
When Migration Is Stuck
VirtualMachineInstanceMigrationstatus- VMI status
MigrationState - Source Pod and target Pod states
Common Misconceptions
Misconception 1: VM and VMI Just Have Different Names and Are Essentially the Same
No. One is intent, the other is the runtime substance. Understanding this difference is necessary to see start/stop, restart, migration, and drain logic.
Misconception 2: Migration Starts by Just Changing One VMI Field
No. A separate migration CR is created, and the controller consumes that object as a work unit.
Misconception 3: Status Is Just for UI Purposes
No. It is an important contract surface through which KubeVirt's internal components cooperate with each other.
Conclusion
KubeVirt's object model is not accidentally complex. VirtualMachine represents persistent intent, VirtualMachineInstance represents a running instance, and VirtualMachineInstanceMigration represents a one-time move request. Because of this separation, KubeVirt can maintain Kubernetes-style declarative APIs while reliably handling state-heavy operations like VM execution and migration.
In the next article, we will look at how these objects are handled at the actual API entry point, and what validation and subresource operations virt-api performs.