perf(controller): repair mirror drift from watch events instead of resync

Mirror update events were filtered out, so an in-place edit of a
mirrored copy was invisible to the controller. The periodic resync did
not catch it either: NeedsSync only compares the source content hash
with the recorded annotation, and tampered mirror data leaves both
unchanged.

Changes:
- The mirror watch now passes real update events (resourceVersion
  changed, object is a managed mirror) and maps them to the source.
  Informer resync replays keep an unchanged resourceVersion and stay
  filtered.
- reconcileMirror detects in-place drift by rebuilding the expected
  mirror in memory and comparing content hashes. Metadata differences
  never count as drift, so the controller's own writes converge in one
  no-op pass.
- The resync-period default moves from 10m to 1h. Watches now cover
  source changes, mirror deletion, mirror drift, and namespace changes,
  so the resync is only a safety net for missed watch events. The chart
  default moves with it.
- Add predicate and tamper-repair regression tests; drift repair is
  verified to make no direct apiserver reads.
This commit is contained in:
2026-08-29 13:44:57 +01:00
parent eaa1246fb7
commit 8988893160
6 changed files with 147 additions and 19 deletions
+1 -1
View File
@@ -53,7 +53,7 @@ Defaults are taken from [`values.yaml`](values.yaml).
| `controller.leaderElectionID` | `"kubemirror-controller-leader"` | Lease name (`--leader-election-id`). |
| `controller.resourceTypes` | `[]` | Resource types to mirror (`--resource-types`). Empty enables auto-discovery. |
| `controller.discoveryInterval` | `"5m"` | Auto-discovery interval (`--discovery-interval`). |
| `controller.resyncPeriod` | `"10m"` | Cache resync period (`--resync-period`). |
| `controller.resyncPeriod` | `"1h"` | Cache resync period, safety net only (`--resync-period`). |
| `controller.maxTargets` | `100` | Max target namespaces per resource (`--max-targets`). |
| `controller.workerThreads` | `5` | Concurrent reconcile workers (`--worker-threads`). |
| `controller.rateLimitQPS` | `50.0` | API QPS limit (`--rate-limit-qps`). |
+3 -2
View File
@@ -54,10 +54,11 @@ controller:
# How often to rediscover available resources in the cluster
discoveryInterval: "5m"
# Cache resync period - how often to refresh all cached resources
# Cache resync period - safety net for missed watch events; mirror drift
# is repaired event-driven, so this can stay long
# Higher values reduce memory churn and API load
# Default: 10m (was 30s in earlier versions)
resyncPeriod: "10m"
resyncPeriod: "1h"
# Resource limits
maxTargets: 100