runtime: skip BIRD render on first cutover
Build flock Image / build (push) Has been cancelled

Calico's calico-node still runs on every node (Tigera-Operator-managed
via ArgoCD with selfHeal). Two birds with the same ASN can't peer to
crt001 from the same source. Use a manual static route on crt001 for
the flock /64 for the first cutover; switch to live BGP after Calico is
fenced off flock-labeled nodes.

The bird sidecar stays running with the bootstrap config (kernel +
device only, no BGP), so flipping live BGP on later is a single-line
change in runtime_linux.go.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Donavan Fritz
2026-04-24 22:41:40 -05:00
parent 0e1833dc7a
commit 06110884d4
+19 -21
View File
@@ -59,30 +59,28 @@ func (s *Server) configureRuntime(ctx context.Context) error {
BirdcSocket: "/run/flock/bird.ctl", BirdcSocket: "/run/flock/bird.ctl",
Logger: s.Logger, Logger: s.Logger,
} }
// Install kernel blackhole routes for the node summary CIDRs. These
// stay regardless of BGP — they keep the kernel from sending unknown
// destinations within our /64 to a default route loop.
if err := bird.SummaryRoutes(nc); err != nil { if err := bird.SummaryRoutes(nc); err != nil {
s.Logger.Warn("install summary routes", "err", err) s.Logger.Warn("install summary routes", "err", err)
} }
if err := bird.Render(nc, nil, nil, routerIDFromNodeIP(s.restCfg)); err != nil { // BGP is intentionally NOT rendered on the first cutover.
s.Logger.Warn("initial bird render", "err", err) //
} // Calico's calico-node DaemonSet still runs on this node (it's
// Re-render whenever NodeConfig changes (cheap). // Tigera-Operator-managed via ArgoCD with selfHeal=true) and Calico's
go func() { // bird is bound to BGP port 179 with the same ASN we'd advertise from.
t := time.NewTicker(15 * time.Second) // A clean coexistence requires either an Installation-CR change or a
defer t.Stop() // post-cutover Calico stop. Both are out of scope for the first M2
for { // cutover. crt001 carries a static route for the flock /64 instead.
select { //
case <-ctx.Done(): // To switch to live BGP later: replace this block with bird.Render(nc,
return // ...) + 15s tick re-render, after disabling calico-node on flock-
case <-t.C: // labeled nodes. The bird sidecar is already running with a bootstrap
cur := s.NodeConfig.Load() // config (just protocol kernel + device — no BGP), so flipping this on
if cur == nil { // is a one-line change here.
continue s.Logger.Info("BIRD BGP disabled for first cutover; static route on crt001 carries flock /64",
} "node_cidr6", nc.Spec.CIDR6, "node_cidr4", nc.Spec.CIDR4)
_ = bird.SummaryRoutes(cur)
_ = bird.Render(cur, nil, nil, routerIDFromNodeIP(s.restCfg))
}
}
}()
handler := &PodHandler{ handler := &PodHandler{
Node: s.Node, Node: s.Node,