feat(vm): add IPAM for additional network interfaces#2612
Open
hardcoretime wants to merge 9 commits into
Open
Conversation
920d0e4 to
d5acfb3
Compare
Contributor
|
Workflow has started. The target step completed with status: failure. |
d5acfb3 to
bc615b4
Compare
prismagod
approved these changes
Jul 10, 2026
…network IPAM Add the `ipAddressName` field to `NetworksSpec` to enable static IP address assignment for additional network interfaces via user-provided `IPAddress` resources (SDN module). When empty, the controller uses automatic mode (DHCP). Add the `ipAddress` field to `NetworksStatus` to reflect the actual IP address allocated for each additional network interface by SDN. Update CRD manifests (EN and RU) with the new fields and descriptions. Signed-off-by: Roman Sysoev <roman.sysoev@flant.com>
…richment Add ipaddress.go with helpers for SDN IPAddress lifecycle management: EnsureSDNIPAddress (create Auto with ownerRef on VM, idempotent), FindSDNIPAddress (by VM label + networkRef), GetSDNIPAddressStatus (address, phase, Allocated/NoFreeAddress), SDNIPAddressExists, and IsIPAddressNameUsedByAnotherVM (conflict detection). Add HasIPAM to check if a network has an IPAM pool configured. Add EnrichWithIPAM: for each additional interface with a pool, resolve ipAddressNames (auto: find controller-created IPAddress; static: validate user IPAddress exists, is allocated, and not used by another VM), set ipAssignmentMode=DHCP, and skip problematic interfaces. Add WillProvisionInterface to determine if an interface will be included in networks-spec (mirrors skip logic for NetworkReady). Update CreateNetworkSpec to propagate IPAddressNames from vm.spec. Add unit tests for all new helpers. Signed-off-by: Roman Sysoev <roman.sysoev@flant.com>
Add IPAddressHandler: creates auto-IPAddress (Auto, ownerRef on VM, label virtual-machine-uid) for additional networks with an IPAM pool when ipAddressName is not set. Garbage-collects auto-IPAddress when a network is removed from spec. Classifies transient vs configuration errors (transient: return error; configuration: skip interface). Update NetworkInterfaceHandler: - collectIPAMErrors: aggregate IPAM errors (static without pool, static IPAddress missing/not allocated/conflicting, auto IPAddress not allocated) into NetworkReady with IPAddress phase and reason. - WillProvisionInterface: filter desired networks to skip problematic interfaces, avoiding misleading "waiting for SDN" messages. - extractIPAddressesFromPods: parse ipAddressConfigs from networks-status into status.networks[].ipAddress. Update SyncKvvmHandler: call EnrichWithIPAM in both MakeKVVMFromVMSpec (KVVM template) and patchPodNetworkAnnotation (pod patch). Update NetworkWatcher: watch SDN IPAddress by ownerRef (auto) and by name reference in vm.spec.networks[].ipAddressName (static) to enqueue VM when Allocated condition changes. Fix isOnlyNetworkIDAutofillChange to include IPAddressName comparison so changing ipAddressName is treated as a hotpluggable network change. Register IPAddressHandler in vm_controller.go after MACHandler. Add unit and integration tests for IPAM controller logic. Signed-off-by: Roman Sysoev <roman.sysoev@flant.com>
Add get/list/watch/create/update/patch/delete permissions for ipaddresses.network.deckhouse.io to the virtualization-controller ClusterRole. Required for IPAddressHandler to manage SDN IPAddress resources for VM additional networks. Signed-off-by: Roman Sysoev <roman.sysoev@flant.com>
Add ClusterIPAddressPool (e2e-ipam-pool, 192.168.200.0/24) and bind it to cn-4006-for-e2e-test via spec.ipam.ipAddressPoolRef in both nightly and release e2e pipelines. Update SDN precheck to verify that cn-4006 has an IPAM pool configured. If the pool is missing, the precheck fails with a command to create it. Signed-off-by: Roman Sysoev <roman.sysoev@flant.com>
Add helpers in util/sdn.go for SDN IPAddress CRUD via dynamic client: CreateSDNIPAddress, GetSDNIPAddress, GetSDNIPAddressAddress, DeleteSDNIPAddress, ListSDNIPAddresses, DeleteAllSDNIPAddresses. Add ipam_additional_networks.go with 7 test cases: - Auto (DHCP): IP allocated from pool, delivered via DHCP to guest OS, stable across VM restart - Static (ipAddressName): user-provided IPAddress, stable across restart - Skip problematic: VM with missing IPAddress on network without pool starts without the interface, error in NetworkReady - Skip to working via watcher: IPAddress created after VM start triggers reconciliation via watcher, interface attached without restart - Hotplug static to auto: switch modes without pod recreation - Hotplug auto to static: switch modes without pod recreation - Live migration: auto IP preserved across migration Each test verifies no AwaitingRestartToApplyConfiguration condition and pod UID stability for hotplug scenarios. Signed-off-by: Roman Sysoev <roman.sysoev@flant.com>
Update vmop/restore.go to use cn-4006 (with pool) with auto (DHCP) cloud-init instead of static IP. CheckAdditionalNetworkInterface now reads the IP from status.networks[].ipAddress and verifies it is present in the guest OS. Add CheckIPAMAfterRestore to verify the auto-IPAddress is recreated after VM restore. Switch additional_network_interfaces.go to use cn-4007 (no pool) for tests with manual IP configuration, since cn-4006 now has an IPAM pool. Remove redundant NoPrecheck label. Signed-off-by: Roman Sysoev <roman.sysoev@flant.com>
Add a new section "IPAM for additional network interfaces" to both USER_GUIDE.md (EN) and USER_GUIDE.ru.md (RU). Describe: - Two modes: automatic (DHCP, controller-managed IPAddress with ownerRef on VM) and static (user-provided IPAddress via ipAddressName) - How the mode is determined by the ipAddressName field - Examples of VM spec with auto and static configuration - Example of creating a static IPAddress resource - Updated status example showing ipAddress for additional interfaces - Warning about avoiding manual static IP config when IPAM is enabled - Warning about hotplugged interfaces requiring guest OS configuration (NetworkManager or udev rule) to automatically bring up new interfaces and request DHCP - Note about skipped interfaces when pool is exhausted or IPAddress is not yet allocated Signed-off-by: Roman Sysoev <roman.sysoev@flant.com>
Signed-off-by: Vladislav Panfilov <vladislav.panfilov@flant.com>
c5ed5e8 to
6fa53cb
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Add IPAM (IP Address Management) for virtual machine additional network interfaces, integrating with the SDN module's IPAM capabilities (address pools,
IPAddressresources, DHCP delivery).Two allocation modes are supported for additional networks that have an IPAM pool (
spec.ipam.ipAddressPoolRef):Automatic (DHCP): when
ipAddressNameis not set in.spec.networks[], the VM controller creates an SDNIPAddress(typeAuto) bound to the VM viaownerReferencesand passes it to SDN. SDN allocates an address from the pool and delivers it to the guest OS via DHCP. The address is stable across VM restarts and migrations (bound to the VM, not the ephemeral pod).Static: when
ipAddressNameis set, the controller uses a user-providedIPAddressresource (typeStatic). The address is determined by the user.If an additional network does not have an IPAM pool, the feature is not enabled — the interface operates in L2-only mode with manual IP configuration in the guest OS (as before).
The allocated IP address is reflected in
status.networks[].ipAddress.Why do we need it, and what problem does it solve?
Previously, additional network interfaces operated at L2 only — IP addresses had to be configured manually inside the guest OS (e.g., via Cloud-Init). This led to:
VirtualMachineIPAddress).Startingwhen network configuration was invalid — CNId8-sdnfails hard on missingIPAddress, blocking pod creation.This PR solves these by having the VM controller manage
IPAddressresources for additional networks (analogous toVirtualMachineIPAddressfor the Main network), with resilient startup (skip problematic interfaces) and reactive reconciliation (watchIPAddressto provision interfaces when addresses become available).What is the expected result?
ipAddressName).status.networks[].ipAddress.ipAddressNamereferences a non-existentIPAddress, or the network has no pool), the VM starts without that interface and reports the error in theNetworkReadycondition.ipAddressName(add/remove/switch auto↔static) is applied live without pod recreation or VM restart.IPAddressafter VM start triggers reconciliation via watcher — the interface is attached automatically (hotplug).Checklist
Changelog entries