Commit 960a0c2
feat: hub-side level-triggered companion GC (Component 6)
Add CompanionGCReconciler, a level-triggered backstop for referenced-data
companions stranded by interrupted finalization. When the
ReferencedDataController's WD finalizer is interrupted mid-flight (pod restart,
SIGKILL), a hub companion can be left with a referenced-by annotation pointing
at WDs that no longer exist on the hub. Without this controller, the companion
persists forever (leaking data including Secret bytes), its ResourceBinding keeps
a Work alive on the hub, and Karmada continuously re-creates the cell copy —
exactly the cm-pristine/secret-pristine lab scenario.
Design:
- Watches referenced-data-labeled ConfigMaps and Secrets on the hub. The
federationMgr cache for ConfigMaps and Secrets is restricted to objects
carrying the ReferencedDataLabel via cache.Options.ByObject (cmd/main.go).
This is the OOM guard: predicates filter events, not cache contents; without
the cache-level scope the informer would list-and-watch every ConfigMap/Secret
on the Karmada hub — the same unscoped-informer pattern that OOMKilled the
cell CompanionGCReconciler. The label predicate on the controller is kept as
belt-and-suspenders but is NOT the primary memory guard.
- On each reconcile, parses the referenced-by annotation and checks each
referenced WD by name in the companion's own hub namespace (ns-{project-uid})
via HubClient.Get — no MCManager needed because WDs are federated to the hub.
- If ALL referrers are absent: deletes the companion and its ResourceBinding via
the downstreamCompanionWriter path, driving the full Karmada cascade
(RB → Work → cell copy deleted permanently).
- Conservative safety: terminating WDs count as present; corrupt annotations
and malformed WD keys are handled by skip-not-delete.
- A companionGCPeriodicSweep backstop fires every 5 minutes to catch companions
stranded before the controller started.
- Wired in setupManagementControllers on the federationMgr alongside
OrphanRBReconciler and InstanceProjector.
Unit tests cover: orphaned CM/Secret deleted + RB torn down; live referrer
preserved; terminating referrer counts as present; all-absent multi-referrer
deleted; partial multi-referrer preserved; corrupt annotation preserved;
empty annotation preserved; unlabeled object unaffected; RB-already-gone
tolerated; periodic sweep drives reconciliation.
Federated e2e (test/e2e/referenced-data-delete-cascade/):
- HAPPY-PATH CASCADE: create WD + ConfigMap/Secret → assert companions on hub +
cell + RBs present → delete WD → assert hub companion, RBs, cell copies all
deleted and stay deleted (30 s anti-thrash poll).
- STRANDED COMPANION BACKSTOP: inject a labeled companion with a dead WD key →
assert CompanionGCReconciler reclaims it within the sweep interval.
The e2e test is correct and self-contained but requires the Kind+Karmada
harness (task e2e:up) which is not runnable headless.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
(cherry picked from commit e419b54)1 parent 0af1ecd commit 960a0c2
8 files changed
Lines changed: 1323 additions & 8 deletions
File tree
- cmd
- internal/controller
- test/e2e/referenced-data-delete-cascade
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
| 19 | + | |
19 | 20 | | |
20 | 21 | | |
21 | 22 | | |
22 | 23 | | |
23 | 24 | | |
24 | 25 | | |
25 | 26 | | |
| 27 | + | |
26 | 28 | | |
27 | 29 | | |
28 | 30 | | |
| |||
495 | 497 | | |
496 | 498 | | |
497 | 499 | | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
498 | 511 | | |
499 | | - | |
500 | | - | |
501 | | - | |
502 | | - | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
503 | 517 | | |
504 | 518 | | |
505 | 519 | | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
506 | 530 | | |
507 | 531 | | |
508 | 532 | | |
| |||
539 | 563 | | |
540 | 564 | | |
541 | 565 | | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
| 575 | + | |
542 | 576 | | |
543 | 577 | | |
544 | 578 | | |
| |||
0 commit comments