Releases: melancholictheory/wellcake
Release list
v0.8.2
Maintenance release: dependency bumps only, no operator behaviour changes.
Changed
- ginkgo 2.32.1 to 2.32.2 and gomega 1.42.1 to 1.43.0 (test dependencies).
- Release workflow actions: docker/setup-qemu-action 4.2.0 to 4.4.0, docker/setup-buildx-action 4.3.0 to 4.4.1, docker/build-push-action 7.3.0 to 7.4.0.
- README links the Helm charts published as OCI artifacts on GHCR.
Images: ghcr.io/melancholictheory/wellcake:0.8.2 (multi-arch). Charts: oci://ghcr.io/melancholictheory/charts/valkey-operator and oci://ghcr.io/melancholictheory/charts/valkey-cluster, version 0.8.2.
v0.8.1
Maintenance release: dependency bumps (Kubernetes libraries to 0.35.8, ginkgo to 2.32.1, docker/setup-buildx-action to 4.3.0).
helm upgrade --install valkey-operator \
oci://ghcr.io/melancholictheory/charts/valkey-operator --version 0.8.1v0.8.0
A maintenance release.
Changed
- Updated the
github.com/redis/go-redis/v9client to 9.22.0.
Fixed
- The e2e suite retries the cert-manager install, so a transient GitHub download error (a 503) no longer fails the whole pipeline in
BeforeSuite.
Install
helm upgrade --install valkey-operator \
oci://ghcr.io/melancholictheory/charts/valkey-operator --version 0.8.0v0.7.2
A small feature release that completes the read/write Service split for Replication.
Replica-only read Service
0.7.1 added <cluster>-primary for writes. 0.7.2 adds <cluster>-replicas, a ClusterIP that load-balances across the replica pods only, so read traffic can be spread across replicas separately from the primary. Point read clients at:
<cluster>-replicas.<namespace>.svc.cluster.local:6379
The cluster-wide <cluster> Service (all pods) and <cluster>-primary (writes) are unchanged. It reuses the valkey.wellcake.io/role label the operator already maintains, so a pod demoted on failover starts serving reads through it on its own.
Install
helm upgrade --install valkey-operator \
oci://ghcr.io/melancholictheory/charts/valkey-operator --version 0.7.2v0.7.1
A small bugfix release.
Primary-only Service for Replication
The cluster-wide client Service (<cluster>) selects every pod, so a Replication client that needs to write could land on a read-only replica at random. Replication clusters now also get a <cluster>-primary Service that resolves to the current primary only and follows failover. Point write clients at:
<cluster>-primary.<namespace>.svc.cluster.local:6379
The operator does this by stamping a valkey.wellcake.io/role label (primary or replica) on the data pods and moving it on failover; the Service selects role=primary. The cluster-wide <cluster> Service is unchanged and still fine for reads or cluster-aware clients.
Thanks to @luukrijnbende for the report (#30).
Install
helm upgrade --install valkey-operator \
oci://ghcr.io/melancholictheory/charts/valkey-operator --version 0.7.1v0.7.0
The headline in this release is automatic recovery from losing a majority of a Cluster's primaries, the one failure gossip cannot fix on its own.
Recovering a Cluster from a lost primary majority
A Cluster fails a single primary over by gossip vote, which needs a majority of masters. Lose more than half the primaries at once (an AZ outage, a bad drain, a correlated crash) and the survivors aren't a quorum, so gossip can't vote any replica in. The cluster then sits in cluster_state:fail with unserved slots for as long as the outage lasts, even though the dead primaries' replicas are healthy and current.
The operator now recovers from this. It acts only once the survivors are provably below a voting quorum, the cluster has been stuck for a 45s debounce, and each dead primary is fenced from two independent perspectives: the k8s API (pod or node not serving) and a direct data-path check (unreachable, or reachable but reporting cluster_state:fail). A primary that is reachable and reports cluster_state:ok is genuinely serving and is never taken over. It then runs CLUSTER FAILOVER TAKEOVER on the best surviving replica of each shard, and the re-created primaries rejoin as replicas through their retained PVCs.
Automatic for the Cache profile; opt-in for Durable via the valkey.wellcake.io/quorum-takeover annotation, since a forced takeover can drop acknowledged writes. Write safety rests on Valkey's own minority-write-block (a primary cut off from the majority stops accepting writes after cluster-node-timeout), not on proving the old process is dead. Full reasoning in ADR 0006.
Validated live on k3d: a majority of primaries fenced, the cluster recovered to cluster_state:ok with zero data loss, and the fenced primaries rejoined as replicas on their own.
Least-privilege replication user
Replicas now authenticate to their primary as a dedicated replicator ACL user, granting only +psync +replconf +ping and no key access, instead of the full-access default user. A leaked replication credential can now neither read nor write data. It is seeded for every replicating topology, password rotation re-keys it in place so replica links stay up, and the replicator and sentinel-user names are reserved against ValkeyACL.
Install
helm upgrade --install valkey-operator \
oci://ghcr.io/melancholictheory/charts/valkey-operator --version 0.7.0v0.6.0
Fixes a long-standing packaging bug: chart upgrades never actually updated the CRDs.
The problem
The operator chart shipped its CRDs in a top-level crds/ directory. Helm installs that directory exactly once, on first install, and silently ignores it on every upgrade afterwards. So any install created with an early chart version has been running against the schema it was first installed with: fields added since (spec.logging, spec.podSecurityContext, and others) never reached the cluster, and resources using them were rejected or pruned.
The fix
CRDs now ship as chart templates, so helm upgrade applies schema changes like any other resource. Two new values:
crd.enabled(defaulttrue) — set tofalsewhen the CRDs are managed outside the chart, e.g. by a cluster admin or GitOps.crd.keep(defaulttrue) — stampshelm.sh/resource-policy: keep. This matters: as templates the CRDs fall under Helm's lifecycle, and deleting a CRD deletes every custom resource of that kind, so without ithelm uninstallwould take out every ValkeyCluster in scope.
This follows what kubebuilder's helm/v2-alpha plugin does, and its reasoning for diverging from the Helm convention.
Upgrading from 0.5.1 or earlier: one-time step required
CRDs installed from the old crds/ directory carry no Helm ownership metadata, so the first upgrade fails with invalid ownership metadata. Adopt them once, then upgrade normally:
for crd in valkeyclusters.cache.wellcake.io valkeyacls.cache.wellcake.io; do
kubectl label crd "$crd" app.kubernetes.io/managed-by=Helm --overwrite
kubectl annotate crd "$crd" \
meta.helm.sh/release-name=<release> \
meta.helm.sh/release-namespace=<namespace> --overwrite
doneThis only relabels existing objects. Nothing is deleted, so stored ValkeyClusters are untouched.
Verified on a live cluster
Not just rendered: installing published chart 0.5.1 and upgrading to this one reproduces the invalid ownership metadata failure; after the adoption step the upgrade succeeds and a CRD schema change actually reaches the API server; and helm uninstall leaves both the CRDs and a live ValkeyCluster in place.
Full changelog: v0.5.1...v0.6.0
v0.5.1
Supply-chain release: the published Helm charts are now signed. No operator behaviour changed.
Added
- Signed Helm charts. The charts pushed to
ghcr.io/melancholictheory/chartsare signed with cosign, keyless: the signature is bound to the release workflow's GitHub OIDC identity through a short-lived Fulcio certificate, so there is no private key to store or rotate. The image already carried provenance and SBOM attestations; the charts had nothing, and now they do.
Charts are signed by digest, so a signature binds to that exact artifact and cannot be voided by moving a tag. Verify one with:
cosign verify ghcr.io/melancholictheory/charts/valkey-operator:0.5.1 \
--certificate-identity-regexp '^https://github\.com/melancholictheory/wellcake/\.github/workflows/release\.yml@' \
--certificate-oidc-issuer https://token.actions.githubusercontent.comNote on the Artifact Hub signature warning
If you saw Artifact Hub report 429 Too Many Requests while checking the cosign signature, this release does not fix that. The warning comes from ghcr's OCI referrers endpoint, which redirects to a legacy GitHub packages URL with the digest truncated; it fails regardless of whether a signature exists. Signing the charts was worth doing on its own merits, not as a workaround for that probe.
Full changelog: v0.5.0...v0.5.1
v0.5.0
Data-plane telemetry and resilience built on Valkey 9.1+. Every directive is version-gated, so nothing changes for older servers.
Added
valkey_operator_tls_cert_expiry_seconds— seconds until the earliest-expiring served certificate across a cluster's pods (Valkey 9.1+). TLS auto-reload already automates the reaction to a renewal, but nothing observed whether one actually happened, and Valkey does not refuse to start on an expired certificate. A stalled cert-manager renewal was therefore a silent outage waiting to happen; this is the signal that catches it.valkey_operator_thread_utilization_ratio— real 0-1 thread utilization from the Valkey 9.1+ active-time counters. Under I/O threading, process CPU sits near 100% because the threads busy-poll, so CPU% is a misleading input for rightsizing.valkey_operator_zone_colocated_groups— replication groups (per shard for Cluster) whose pods all landed in a single availability zone. The operator's zone spread is a soft constraint, so the scheduler can quietly co-locate a primary and its replica and void the HA the spread implies. Works on any Valkey version, and needs the chart's ClusterRole variant, which now grants read access to nodes.hash-seedpinned per cluster on Valkey 9.1+, so a primary and its replicas return identical SCAN-family results and client cursors survive the failovers and pod replacements the operator itself drives.
Changed
- Durable Cluster primaries on Valkey 9.0+ now also carry the
safeshutdown token, so descheduling that cannot fail over becomes visible instead of silently dropping a slot owner. Cache keepsfailoveralone: on an availability-first profilesafewould stall a drain.
Not included
Hot-aware resharding (cluster-slot-stats) was surveyed and deliberately left out. It would have to bypass valkey-cli's own slot picker, fighting the existing Atomic Slot Migration flow, for a benefit no one has measured yet. It belongs in its own design doc, gated on an actual observed hotspot.
Full changelog: v0.4.0...v0.5.0
v0.4.0
Exploits Valkey 9.1+ features found by a feature-gap review. Every directive is version-gated, so nothing changes for older servers.
Added
spec.logging.format(json|logfmt|legacy) renderslog-formatfor structured server logs, gated on Valkey 9.1+. Opt-in; leave it unset for the default.cluster-config-save-behavior best-efforton memory-backed (Cache) Cluster pods running Valkey 9.1+, so a failednodes.confsave keeps an availability-first pod serving instead of crashing it. Durable/PVC clusters keep the safesyncdefault.
Changed
- Cluster pods on Valkey 9.0+ now set an explicit
terminationGracePeriodSeconds(30s), giving the graceful SIGTERM manual failover a guaranteed time budget instead of leaning on the Kubernetes default.
Full changelog: v0.3.0...v0.4.0