- Authors

- Name
- Youngju Kim
- @fjvbn20031
- Introduction
- Basic Idea
- Core Code: pkg/network/multus/annotation.go
- Why Interface Name Calculation Matters
- What Goes into the Annotation
- What Happens After the Pod Receives the Secondary Network
- Why InfoSource Matters
- Secondary Network Changes Can Trigger Migration
- The Relationship Between Multus and Binding Plugins
- Common Issues in Practice
- Common Misconceptions
- Conclusion
Introduction
The primary Pod network alone is often insufficient. VMs may need multiple NICs for data plane, storage plane, management networks, or NFV purposes. KubeVirt does not solve this with its own multi-network system but instead reuses the Multus and NetworkAttachmentDefinition ecosystem.
This post traces the path from secondary networks in the VMI spec through Pod annotations, Pod interfaces, and VMI status.
Basic Idea
The primary network is usually provided by the default Pod CNI. Secondary networks are additionally attached by Multus. KubeVirt reads the VMI spec and generates the necessary Multus annotations to place on the launcher Pod.
The flow is as follows:
- User specifies secondary networks in the VMI spec.
- KubeVirt generates Pod annotations.
- Multus reads the annotations and attaches additional interfaces according to the NAD.
- KubeVirt reads the Pod network status and updates the VMI status.
Thanks to this structure, KubeVirt does not recreate multi-network functionality in its core.
Core Code: pkg/network/multus/annotation.go
The key functions in this file are GenerateCNIAnnotation and GenerateCNIAnnotationFromNameScheme. The role is very clear:
- Find secondary Multus networks
- Calculate Pod interface names
- Build a list of
NetworkSelectionElement - Serialize them into a JSON annotation string
The controller does not stop at just "there is a NAD name" -- it also calculates what interface name it should be attached to inside the Pod.
Why Interface Name Calculation Matters
KubeVirt does not use logical network names and Pod interface names identically. It creates hashed names through the namescheme layer. The purpose of this approach is:
- Handling interface name length limits
- Predictable naming
- Minimizing conflicts even with many secondary networks
network-binding-plugin.md also explains naming conventions like pod-hash or tap-hash for the secondary network side.
In other words, naming conventions are not just aesthetics -- they are the contract that ensures the launcher Pod, CNI plugin, and libvirt domain all point to the same interface.
What Goes into the Annotation
The Multus NetworkSelectionElement typically contains:
- Namespace
- NAD name
- Interface request
- MAC request if needed
When a binding plugin is attached, CNIArgs may also be included. annotation.go inserts the logical network name as a CNI arg for plugin bindings.
This means the plugin binding and secondary network model are not simply parallel -- they can be coupled at the annotation stage.
What Happens After the Pod Receives the Secondary Network
KubeVirt does not stop at just writing Pod annotations. After the Pod actually receives the secondary network, the result must be reflected back into the VMI status.
The code handling this role is pkg/network/controllers/vmi.go.
Here:
- Pod Multus network status annotations are read
- Primary interface status is calculated
- Secondary interface status is calculated
- Results are reflected in the VMI status
Interfaces
In other words, the VMI status contains not only "how the guest should see the network" but also "what secondary interfaces the Pod actually received."
Why InfoSource Matters
Looking at vmi.go, there is an InfoSource concept in the interface status. This is a mechanism to distinguish where information came from.
- Did it come from Pod Multus network status?
- Did it come from the libvirt domain?
- Did it come from the guest agent?
This distinction is very important. For example, if an interface exists on the Pod side but is not yet reflected in the domain, a network hotplug may be in progress or incomplete.
In other words, InfoSource is not just metadata -- it is material for reconciliation decisions.
Secondary Network Changes Can Trigger Migration
pkg/network/migration/evaluator.go reveals an interesting fact. Secondary interface hotplug or unplug, and NAD reference changes, can in some cases put a VMI into a migration-required state.
Why is this important?
When network configuration changes, there are cases where it is difficult to safely apply them on the current launcher Pod. In such cases, KubeVirt may decide:
- Immediate migration required
- Pending for a moment then migration required
and attempt to apply the network configuration cleanly on a new target Pod.
In other words, secondary networks are not just a CNI attach issue -- they are a dynamic state that is also connected to VM re-placement strategy.
The Relationship Between Multus and Binding Plugins
Many people think of Multus and binding plugins as separate things, but in practice they often appear together.
- Multus is the secondary network attach mechanism
- Binding plugin is the guest wiring method
One is responsible for bringing network endpoints into the Pod, and the other determines how those endpoints are bound to guest NICs.
When both come together, "how the secondary network appears as a device in the guest" is completed.
Common Issues in Practice
1. NAD is correct but interface status is empty
The Pod annotation was created but the Multus attach result may not have been populated as expected.
2. Interface exists on Pod but is not visible in the guest
The Pod stage and domain stage are out of sync. Check InfoSource.
3. Migration required appears after hotplug
This may mean that a dynamic network update cannot be safely finalized on the current Pod and re-placement is needed.
Common Misconceptions
Misconception 1: Once attached to Pod, secondary networks are automatic in the guest
No. Pod attach and guest wiring are different stages.
Misconception 2: Multus handles everything up to guest networking
No. Multus attaches the network to the Pod, and guest wiring is the responsibility of KubeVirt binding and domain configuration.
Misconception 3: Interface status is just display output
No. It is important data used for reconcile decisions by combining status from multiple sources.
Conclusion
In KubeVirt, secondary networks enter the Pod through Multus and NAD, and KubeVirt completes them by connecting annotations, naming schemes, interface status, and guest wiring. Multus handles endpoint provisioning, KubeVirt handles guest integration -- a division of labor structure. Understanding this structure enables much more systematic debugging of VMs with multiple NICs.
In the next post, we will move from networking to migration and examine the control plane process that the target Pod goes through after a migration CR is created.