Phase: Phase 15 — Performance and scale
Proposal: docs/proposals/next-phases.md §15
Priority: P2 · Size: XL
Problem
internal/assign/assign.go resolves which ConversionWebhookServer serves a config: an explicit reference, or the instance marked default: true. Scaling out today therefore means an operator manually creating instances and manually assigning configs to them — which is fine for tenant isolation (a deliberate choice) but is not a scaling story.
Every replica of a given server compiles and holds every config assigned to that server, so the per-replica cost grows with the number of targets, and the only lever is manual.
Goal
N targets spread across M servers without an operator hand-assigning each one.
Non-goals
- Cross-cluster anything.
- Removing explicit assignment. Deliberate pinning must keep working exactly as it does — automatic balancing is for the configs that do not express a preference.
Design
Add a balancing policy to ConversionWebhookServer, e.g. spec.sharding: {enabled, replicas|weight}, and a resolver that distributes unpinned configs across the servers that opt in — by consistent hashing on the target name, so the assignment is stable as configs come and go and does not reshuffle the world when one server is added.
The hard part is the move, not the assignment. Reassigning a target from server A to server B means the XRD's spec.conversion must point at B only once B is actually serving the plan — otherwise there is a window with no working webhook. The safe sequence is: B compiles and reports ready for the target → patch the XRD to B → A drops it. That needs per-target readiness from the server, which the project currently and deliberately does not have (docs/limitations.md, "Per-pod webhook-server state isn't surfaced back into status").
So this issue probably has a prerequisite: a minimal, bounded form of per-target readiness — enough to answer "is server B serving target X on every replica?" without making the reconcile loop depend on polling pods. Investigate whether an aggregated status.servedTargets written by the servers themselves (each replica updating a lease or a per-replica status) is acceptable, and write up the design before building.
Acceptance criteria
Notes
Largest item in the phase and the one most likely to need splitting. Start with the design note.
Generated by Claude Code
Phase: Phase 15 — Performance and scale
Proposal:
docs/proposals/next-phases.md§15Priority: P2 · Size: XL
Problem
internal/assign/assign.goresolves whichConversionWebhookServerserves a config: an explicit reference, or the instance markeddefault: true. Scaling out today therefore means an operator manually creating instances and manually assigning configs to them — which is fine for tenant isolation (a deliberate choice) but is not a scaling story.Every replica of a given server compiles and holds every config assigned to that server, so the per-replica cost grows with the number of targets, and the only lever is manual.
Goal
N targets spread across M servers without an operator hand-assigning each one.
Non-goals
Design
Add a balancing policy to
ConversionWebhookServer, e.g.spec.sharding: {enabled, replicas|weight}, and a resolver that distributes unpinned configs across the servers that opt in — by consistent hashing on the target name, so the assignment is stable as configs come and go and does not reshuffle the world when one server is added.The hard part is the move, not the assignment. Reassigning a target from server A to server B means the XRD's
spec.conversionmust point at B only once B is actually serving the plan — otherwise there is a window with no working webhook. The safe sequence is: B compiles and reports ready for the target → patch the XRD to B → A drops it. That needs per-target readiness from the server, which the project currently and deliberately does not have (docs/limitations.md, "Per-pod webhook-server state isn't surfaced back into status").So this issue probably has a prerequisite: a minimal, bounded form of per-target readiness — enough to answer "is server B serving target X on every replica?" without making the reconcile loop depend on polling pods. Investigate whether an aggregated
status.servedTargetswritten by the servers themselves (each replica updating a lease or a per-replica status) is acceptable, and write up the design before building.Acceptance criteria
spec.conversionWebhookServerRefalways winsinternal/enqueue's paced fan-outdocs/architecture.mdanddocs/configuration/conversionwebhookserver.mdupdatedNotes
Largest item in the phase and the one most likely to need splitting. Start with the design note.
Generated by Claude Code