agent: add flock.fritzlab.net/addresses annotation (eth0 static IPs)
Build flock Image / build (push) Successful in 3m23s

Like anycast, addresses IPs are advertised via BGP (/128+/32) and get
host routes via the AnycastReconciler. The sole difference: they are
assigned to pod eth0 instead of lo, so workloads that inspect their
primary interface (e.g. Plex remote-access detection) see the public IP
directly.

- annotations.go: annAddresses const, Addresses []net.IP in ParsedAnnotations
- state.go: Addresses []string persisted in allocations.json
- anycast.go: resolveAnycastTargets processes Anycast+Addresses together
- netns_linux.go: configurePodSide assigns Addresses to eth0
- netns_stub.go: mirror Addresses field for non-Linux builds
- handlers.go: thread Addresses through ADD path

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Donavan Fritz
2026-04-28 17:50:49 -05:00
parent 362a1e01ce
commit 2daa2a21f3
6 changed files with 52 additions and 8 deletions
+22
View File
@@ -25,6 +25,11 @@ type SetupRequest struct {
// Host /128 and /32 routes are NOT installed here — that happens once
// the pod becomes Ready, see AnycastReconciler.
Anycast []net.IP
// Addresses are additional IPs to bind directly on pod eth0 (NOT lo).
// BGP advertisement is handled identically to Anycast by the
// AnycastReconciler. Use when the workload needs the IP on its primary
// interface (e.g. Plex remote-access detection).
Addresses []net.IP
}
// LinkLocalGW is the deterministic IPv6 LL gateway placed on every host
@@ -269,6 +274,23 @@ func configurePodSide(req SetupRequest) error {
}
}
// Addresses: assign directly to pod eth0. Host routing and BGP
// advertisement are handled identically to Anycast by the
// AnycastReconciler (host route via pod-eth0-ip, /128+/32 in BIRD).
for _, ip := range req.Addresses {
var mask net.IPMask
if ip.To4() != nil {
mask = net.CIDRMask(32, 32)
ip = ip.To4()
} else {
mask = net.CIDRMask(128, 128)
}
a := &netlink.Addr{IPNet: &net.IPNet{IP: ip, Mask: mask}, Scope: int(netlink.SCOPE_UNIVERSE)}
if err := netlink.AddrAdd(eth0, a); err != nil && !errors.Is(err, os.ErrExist) {
return fmt.Errorf("pod eth0 address %s: %w", ip, err)
}
}
return nil
})
}