The three macvlan NADs on the IoT VLAN (matter-server, otbr,
shelly-manager) used static IPAM with hand-picked addresses .226/.227/
.228, chosen because a ping sweep on 2026-05-13 found them idle. All
three sit inside the UniFi DHCP pool (10.2.30.100-.254), so the UDM
leased them out from under the pods.
The controller has been logging CLIENT_IP_CONFLICT continuously since
2026-05-13:
.226 vs Miele oven (00:1d:63:5a:95:4e) 16 alerts
.227 vs Miele fridge (00:1d:63:87:9d:b1) 8 alerts
.228 vs itself 4 alerts
Nobody noticed because these attachments exist only for mDNS/multicast
L2 presence, and multicast reception survives losing the ARP race, so no
pod ever logged an error. The .228 case involves no real device at all:
Multus randomizes the macvlan MAC per sandbox, so a rolling update had
the terminating and starting pods claiming the same static address under
different MACs.
A ping sweep shows which hosts answer at that instant. It says nothing
about what DHCP will lease later. Relocating the addresses to a quieter
part of the subnet would preserve the actual defect -- an address that no
allocator owns. So remove the addresses instead: let the UDM allocate,
as it does for every other device on this VLAN.
Nothing depends on the values. Verified across the repo, every live
cluster object including decoded Secrets, and Home Assistant's stored
config entries: no consumer references .226/.227/.228, and no UniFi
firewall rule, port-forward, or firewall group mentions them. All three
pods are reached via their ClusterIP Services; matter-server binds by
interface name (--primary-interface=net1) and otbr by
BACKBONE_INTERFACE=net1.
Adds cni-dhcp-daemon to infrastructure/multus, which the dhcp IPAM
plugin requires -- the plugin is only a client of a per-node daemon on
/run/cni/dhcp.sock. The dhcp binary is already on the nodes; the sibling
cni-plugins-installer extracts the whole v1.5.1 tarball. Flux's apps
Kustomization already dependsOn infrastructure, so the daemon lands
before the NADs reconcile, and running pods keep their addresses until
restarted.
No stable MAC is pinned: under DHCP the random per-sandbox MAC is what
lets a rolling update take two independent leases rather than collide on
one reservation.
Also corrects two stale comments: matter-server/deployment.yaml still
described the NAD as pinning .226, and bgp-service.yaml claimed the
home-assistant-iot Service at 10.2.30.80 was retained for hard-coded
clients -- it was retired 2026-05-20 and no LoadBalancer Service holds a
10.2.30.x address any more.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>