Repository navigation
fix: Stop the gateway rewriting unchanged rules on every pod attach - #786
Conversation
Every gateway node reconciled on any BGPAdvertisement, BGPVRFInstance or BGPRouter event in its namespace, status writes and its own VIP advertisements included. Each pass re-applied every rule: a fresh quota reservation, a rebuilt Maglev table, and a Put of every vip_table and vip_addr_table entry. Pod churn anywhere in the cluster therefore rewrote every VIP on every gateway node. The engine now applies a rule only when it is new or differs from the active one, compared field by field including each backend's uSID. An unchanged rule still reports an applied status, so its advertisement and Programmed condition are untouched. Skipping unchanged rules removes the every-pass rewrite that used to repair a failed update or removal, so the engine now tracks those itself. A failed apply releases the key's quota and can leave its datapath entries half-written, and a failed removal leaves the rule active with its quota already released. Either marks the key dirty, and a dirty key is applied on the next pass even when its desired rule equals the active one. A new rule that fails to apply never becomes active, so it is retried as before. The NetworkGateway controller's watches now drop events that cannot change what a pass does: - BGPAdvertisements without both a VRFID and a Function, which the backend resolver ignores, except a delete or spec edit of the gateway's own VIP advertisements, so a removed one is still restored. - Status-only updates to all three kinds. Every field the resolver reads is in spec. Unchanged rules are no longer rewritten after an external wipe of the pinned maps. A process restart, which empties the engine's active set, still rebuilds them. Fixes #719 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
pr-conventions-reviewer: VERDICT: merge. No reach, collision, ownership or convention findings. The change is Go-only under internal/gateway and internal/controller and touches no manifest, so it ships only with a release. It rolls out through the normal merge-to-staging, release-to-prod path, and no open PR owns the same files. PR #738 touches only the gateway architecture doc and the webhook, so the two can both land. pr-adversary: VERDICT: merge. No correctness defect. rulesEqual covers every DesiredRule field including Backends[].USID, so a backend that moves nodes still triggers a rewrite. ReconcileOrphans spares any key in the live set, so skipped rules with older generations are not swept. The resolver reads only spec fields, so filtering status-only updates on BGPRouter, BGPVRFInstance and BGPAdvertisement is safe; deletes and spec edits of the gateway's own VIP advertisements still pass. A failed apply of an active rule, or a failed removal, is marked dirty and retried next pass. pr-conventions-reviewer ran: gh pr view 786; git diff --stat base...head; gh pr list --state open (files); grep of docs/agents/CONVENTIONS.md for commit rules; git diff of the controller and gateway files filtered for added comment lines. pr-adversary ran: gh pr view 786; gh issue view 719 --comments; gh pr checks 786; git diff --stat and full diff of the controller and gateway files; reads of types.go, kerneldatapath.go, usidresolver.go, edgemap/viptable.go and greps of ReconcileOrphans/Generation/ApplyRule call sites; go test ./internal/gateway/... ./internal/controller/... (both pass). No findings to apply. CI: All checks passed (Build, Lint, Unit Tests, Unit Tests (root), E2E Tests, all image publish jobs, kustomize bundle publish, CLA). Auto-merge enabled with --merge. The base branch ruleset requires code owner review and approval of the last push. Auto-merge will complete once the required approvals are in place. Generated with Claude Code |
Summary
Each gateway node rewrote every VIP's load-balancing entries whenever any route object in its namespace changed, so every pod start or stop anywhere in the cluster triggered a full rewrite on every gateway node.
The gateway now rewrites a rule only when its inputs change, and it ignores route events that cannot affect a backend.
A rule whose last update or removal failed is still retried on the next pass. The gateway still restores its own VIP advertisements if someone deletes or edits them.
Test plan
Fixes #719
🤖 Generated with Claude Code