Skip to content

fix(migration): VM MAC address not preserved during virtual-machine → vm-instance migration #2166

@sircthulhu

Description

@sircthulhu

Describe the bug

During the upgrade from v0.41 to v1.0, migration script 29 converts virtual-machine
HelmReleases to vm-disk + vm-instance. The migration attempts to preserve the VM's
MAC address by storing it in the pre-created ip.kubeovn.io IP resource (step 2k).
However, Kube-OVN does not honor the macAddress field stored in an IP resource when
assigning a MAC to a new pod — the migrated VM receives a new random MAC address.

As a result, if the VM's OS had netplan (or any network config) matching the interface
by the old MAC address, the primary network interface stays DOWN after migration,
causing loss of internet connectivity.

Environment

  • Cozystack version: v0.41.x → v1.0.x
  • Kube-OVN version: v1.15.3

Root cause

Migration step 2k stores the old MAC in spec.macAddress of the pre-created IP
resource, assuming Kube-OVN will honor it. However, per Kube-OVN source code
(pkg/controller/pod.go), the MAC address is read exclusively from the pod
annotation
ovn.kubernetes.io/mac_address:

annoMAC := pod.Annotations[fmt.Sprintf(util.MacAddressAnnotationTemplate, podNet.ProviderName)]
if annoMAC != "" {
    macPointer = &annoMAC
}
// if annotation is absent — macPointer stays nil → a fresh random MAC is generated

The spec.macAddress field in the ip.kubeovn.io resource is updated by Kube-OVN
post-assignment and is never read during allocation.

Migration step 2n creates the vm-instance values secret without setting
ovn.kubernetes.io/mac_address on the VirtualMachine template annotations. As a
result, the annotation is absent on the virt-launcher pod, and Kube-OVN generates a
fresh random MAC.

The timestamp of the ip.kubeovn.io resource matching the pod creation time exactly
confirms that Kube-OVN created it at pod startup, not from a pre-reserved value.

To Reproduce

  1. Have a running VM under the virtual-machine chart (v0.41.x) with network
    configured in the OS using match: macaddress: in netplan
  2. Upgrade Cozystack from v0.41 to v1.0
  3. Migration 29 runs, converting the VM to vm-disk + vm-instance
  4. After migration, the VM's network interface is DOWN (netplan MAC mismatch)

Expected behaviour

The VM retains the same MAC address after migration so that OS-level network
configuration (netplan, udev rules, etc.) continues to work without manual
intervention.

Actual behaviour

The VM receives a new random MAC address. The netplan match: macaddress: rule no
longer matches the interface, leaving it in state DOWN. The VM loses internet
connectivity (ping 1.1.1.1 returns "Network is unreachable").

Suggested fix

Migration step 2n should propagate OVN_MAC into the VirtualMachine template
annotations via the vm-instance values secret:

spec:
  template:
    metadata:
      annotations:
        ovn.kubernetes.io/ip_address: "${OVN_IP}"
        ovn.kubernetes.io/mac_address: "${OVN_MAC}"

Note: the MAC must not be set via KubeVirt's
spec.template.spec.domain.devices.interfaces.macAddress — per Kube-OVN
documentation, this only affects the MAC visible inside the VM guest and causes a
mismatch with the OVN logical port MAC, resulting in traffic being dropped by security
policies.

Workaround for affected users

Inside the VM (via SSH or VNC console):

  1. Remove the match: macaddress: constraint from netplan
  2. Run sudo netplan apply
  3. The interface will come up and receive IP + gateway via DHCP

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions