You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Browse filesBrowse the repository at this point in the historyBrowse files
authored
fix: stop updating workloads on every reconcile by owning API-server defaults (#317)
Fixes#315.
## Problem
`ensureStatefulSet` / `ensureDeployment` assign the whole desired spec
inside their `CreateOrUpdate` mutate functions, while the builders leave
every API-server-defaulted field unset. Each reconcile clobbers the
stored defaults back to zero values, `CreateOrUpdate` sees a diff, and
the operator issues an Update — every pass, forever, with
`metadata.generation` stuck. Observed impact: ~1–2k
`statefulsets.update` Admin Activity audit events/hour on a
3-shard/6-node cluster; on GKE these land in the non-excludable
`_Required` bucket (details in #315).
This implements the **narrow fix** discussed in the issue thread (own
the defaults in the builders), as suggested there — small and
backportable; a Server-Side Apply migration can follow separately.
## Changes
**`buildValkeyNodePodTemplateSpec` / `buildContainersDef`** — set the
pod-template fields the API server would default, so the built template
already equals the stored one:
- pod: `restartPolicy`, `dnsPolicy`, `schedulerName`,
`terminationGracePeriodSeconds` (30 when unset), empty `securityContext`
when none is configured, volume `defaultMode`s
- containers (applied after `mergePatchContainers`, so user container
patches are normalized the same way the API server would):
`imagePullPolicy` (tag-aware, mirroring API-server logic),
`terminationMessagePath`/`Policy`, port `protocol`, env
`fieldRef.apiVersion`
**`buildValkeyNodeStatefulSet`** — `podManagementPolicy`,
`updateStrategy` (RollingUpdate, partition 0), `revisionHistoryLimit`,
`persistentVolumeClaimRetentionPolicy` (Retain/Retain; note: requires
the `StatefulSetAutoDeletePVC` gate, on by default since 1.27, GA 1.32 —
on older clusters with the gate off the API server drops the field and
this one field would resume churning).
**`buildValkeyNodeDeployment`** — `revisionHistoryLimit`,
`progressDeadlineSeconds`.
**`upsertService`** — the rebuilt `ports` slice now sets `protocol` and
`targetPort`, which made the headless Service churn the same way.
The PDB reconcile already mutates field-wise with values that round-trip
cleanly, so it needed no change.
## Tests
- New envtest regression test: reconcile a ValkeyNode, capture the
StatefulSet `resourceVersion`, reconcile 3 more times, assert it is
unchanged. Fails on `main`, passes here (envtest runs a real API server,
so real defaulting is exercised).
- `TestBuildValkeyNodePodTemplateSpec_PodSecurityContext_NilIsNoop`
updated: omitting the field now yields the empty `securityContext` the
API server defaults to — semantically identical (no security settings
applied), and required for the no-op property.
- `make test` green (75/75 specs + unit tests, envtest k8s 1.35).
## Caveat
This is intentionally the treadmill-y narrow fix: a future Kubernetes
version defaulting a new field would reintroduce churn for that field
until added here. The durable fix is SSA with generated
ApplyConfigurations, per the discussion in #315.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Signed-off-by: Matan David <matan.david@eon.io>
Signed-off-by: Joseph Heyburn <34041368+jdheyburn@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Joseph Heyburn <34041368+jdheyburn@users.noreply.github.com>
Co-authored-by: Joseph Heyburn <jdheyburn@gmail.com>
0 commit comments