M6: anycast — pod lo + Ready-gated /128/32 + BIRD export
Build flock Image / build (push) Has been cancelled
Build flock Image / build (push) Has been cancelled
CNI ADD now adds anycast IPs to the pod's lo interface (NOT eth0 — design
doc rationale: avoid NDP/ARP DAD conflicts when N replicas share an IP).
Allocation persists the anycast list.
AnycastReconciler:
desired = { ip → flock<8hex> } from
committed allocations × pod.Status.PodReady=True
diff against advertised, install/remove host /128 (v6) or /32 (v4)
re-render bird.conf with the active set
Triggers: 2s tick, AfterCommit (per ADD/DEL), Pod informer Ready
transitions (PodCache.OnReadyChange callback).
The bird template already supported Anycast6/Anycast4 via the export
filter — this turn finally drives those slices from runtime.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+16
-10
@@ -74,23 +74,31 @@ func (s *Server) configureRuntime(ctx context.Context) error {
|
||||
// Calico is fenced off this node (Tigera Installation CR adds a
|
||||
// nodeAffinity excluding flock.fritzlab.net/agent on
|
||||
// calicoNodeDaemonSet). flock now owns BGP from this host.
|
||||
if err := bird.Render(nc, nil, nil, routerIDFromNodeIP(s.restCfg)); err != nil {
|
||||
routerID := routerIDFromNodeIP(s.restCfg)
|
||||
if err := bird.Render(nc, nil, nil, routerID); err != nil {
|
||||
s.Logger.Warn("initial bird render", "err", err)
|
||||
}
|
||||
|
||||
// AnycastReconciler is the single owner of bird re-renders going
|
||||
// forward. It runs every 2s + on Pod readiness changes + on each
|
||||
// successful CNI ADD/DEL.
|
||||
anycast := NewAnycastReconciler(s.Node, s.Store, pods, s.NodeConfig, bird, routerID, s.Logger)
|
||||
pods.OnReadyChange(anycast.Trigger)
|
||||
go anycast.Run(ctx)
|
||||
|
||||
// Background tick for SummaryRoutes (idempotent) in case the kernel
|
||||
// blackhole disappears for any reason.
|
||||
go func() {
|
||||
t := time.NewTicker(15 * time.Second)
|
||||
t := time.NewTicker(60 * time.Second)
|
||||
defer t.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-t.C:
|
||||
cur := s.NodeConfig.Load()
|
||||
if cur == nil {
|
||||
continue
|
||||
if cur := s.NodeConfig.Load(); cur != nil {
|
||||
_ = bird.SummaryRoutes(cur)
|
||||
}
|
||||
_ = bird.SummaryRoutes(cur)
|
||||
_ = bird.Render(cur, nil, nil, routerIDFromNodeIP(s.restCfg))
|
||||
}
|
||||
}
|
||||
}()
|
||||
@@ -103,9 +111,7 @@ func (s *Server) configureRuntime(ctx context.Context) error {
|
||||
NodeConfig: s.NodeConfig,
|
||||
SetupFunc: Setup,
|
||||
TeardownFunc: Teardown,
|
||||
AfterCommit: func() {
|
||||
// Future: collect anycast IPs from store snapshot, re-render bird.
|
||||
},
|
||||
AfterCommit: anycast.Trigger,
|
||||
}
|
||||
s.RPC.SetHandlers(handler.Add, handler.Del, handler.Check)
|
||||
s.Logger.Info("runtime ready",
|
||||
|
||||
Reference in New Issue
Block a user