Skip to content

docs(dha): PoC finding — CNPG scale subresource has no selector; reopen actuation mechanism - #53

Merged
Timofei Larkin (lllamnyp) merged 3 commits into
mainfrom
dha/poc-cnpg-scale-selector-blocker
Aug 18, 2026
Merged

docs(dha): PoC finding — CNPG scale subresource has no selector; reopen actuation mechanism#53
Timofei Larkin (lllamnyp) merged 3 commits into
mainfrom
dha/poc-cnpg-scale-selector-blocker

Conversation

@scooby87

@scooby87 scooby87 commented Aug 10, 2026

Copy link
Copy Markdown

What this PR does

Amends the merged Database Horizontal Autoscaler proposal with a blocking finding from a live PoC, and puts two resolution options on the record for a decision. This follows up the design merged in #44.

The finding

A live PoC (cozystack v45, CloudNativePG 1.27.3, Kubernetes 1.34.3) validated the metric side of the design but found that the load-bearing mechanism — a stock HPA (via KEDA) driving the CNPG Cluster scale subresource — cannot be built on stock CNPG.

  • Validated: the single-value Σ + target query returns the right number on real data (151 at target 150desired = ceil(151/150) = 2 = 1 primary + 1 read replica); the series/labels exist in VictoriaMetrics; the KEDA package installs and renders the ScaledObject into a managed HPA.
  • Blocked: that HPA reports ScalingActive=False, reason=InvalidSelector. The CNPG Cluster /scale subresource exposes no status.selector (the CRD has no labelSelectorPath), and the HPA controller requires the selector unconditionally — so it fails for every metric type (verified with both AverageValue and Value). Upstream CNPG #7923 (add that selector for HPA/KEDA) is closed as not planned, and the CNPG 1.30 docs recommend against HPA for a Cluster — so this is not fixable by a version bump.

Why this is not a return to rev1

The machinery that got the first revision rejected — SSA ownership, the marker annotation, the HelmRelease webhook, terminal-freeze — existed only because the chart declared replicas. §3 (the chart omitting the field under autoscaling) removes that regardless of mechanism. What the finding brings back is only a small write-the-count actuator, not the enforcement layer.

Decision requested (Timofei Larkin (@lllamnyp))

  • Option A — KEDA + a thin mirror shim: keep KEDA's decision loop by pointing its HPA at a proxy object that exposes a selector, and mirror the computed count into Cluster.spec.instances. Adds a shim + proxy object + the platform-wide KEDA dependency.
  • Option B — a lean actuation controller, no KEDA: a small controller reads the metric from VictoriaMetrics and writes Cluster.spec.instances directly with the min/max/quorum bounds and stabilization. Close to rev1 minus the ownership machinery (§3 already removes it), no KEDA dependency, at the cost of some stabilization logic.

Both keep §1 (validated metric encoding) and §3 (chart omits the field). The choice is where the desired-count computation lives and whether to take KEDA as a platform dependency. Your Alternative 4 (a thin actuation shim) turns out to be needed for PostgreSQL too — not because it lacks a scale subresource, but because that subresource has no selector.

The implementation branch for the code (cozystack/cozystack#3381) is held — slices 1–3 (postgres ScaledObject + cozy-lib helper, KEDA package + wiring, alerts/dashboard) and the two-phase migration are done and green, but the actuation path is frozen pending this decision.

release-note

NONE

Summary by CodeRabbit

  • Documentation
    • Updated the database horizontal autoscaling proposal with findings from the proof of concept.
    • Documented a limitation preventing standard KEDA/HPA actuation from scaling CloudNativePG clusters.
    • Reopened the scaling mechanism decision and added two alternatives for evaluation: a proxy-based approach and a dedicated controller.

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants