Skip to main content

Valkey (component)

A Kustomize component that gives an app a small in-namespace Valkey (open-source Redis fork) instance for caching, session storage, or queueing. Single-replica, no persistence, intentionally cheap to lose.

What it composes

  • Deployment <app>-valkey running the official Valkey image.
  • Service <app>-valkey exposing the standard port on ClusterIP only.
  • Secret with a generated auth password (sourced from the app's SOPS-encrypted Secret if the app overrides it).
  • emptyDir volume — no PVC, no Longhorn replica. Cache lost on restart, deliberately.

How an app uses it

# k8s/apps/talos/<app>/kustomization.yaml
components:
- ../../../components/talos/valkey

The app's Deployment references <app>-valkey:6379 for its cache. If the app needs a persistent Valkey (queue jobs that must survive restart), it should not use this component — drop a custom StatefulSet with a PVC instead.

Why single-replica, no persistence

  • Cache vs. store. If the workload can't survive losing its Valkey, the workload is using Valkey as a store, not a cache. Use Postgres (via cnpg) or MongoDB (via mongodb) for state.
  • One replica is enough. A failed Valkey gets rescheduled. Apps that depend on it usually have a Redis client with reconnect-and-retry built in.
  • No PVC means no Longhorn replica overhead and no backup tier consideration. Caches are the wrong shape for backups.

Why Valkey, not Redis

Valkey is the BSD-licensed fork that took over after Redis's license change. Functionally a drop-in: every Redis client in every app talks to it without changes. The reasons here:

  • Licence clarity. No Redis SLA / commercial-clause concerns.
  • Active community + Linux Foundation stewardship.
  • API-compatible — when Redis ships a new feature that Valkey doesn't have, the workloads already running here don't need it.

Operational notes

  • Wipe + restart is the standard recovery: kubectl rollout restart deployment <app>-valkey. Cache repopulates from upstream sources.
  • Memory limits are set on the Deployment patch — Valkey gracefully evicts when it hits the limit (LRU by default). Tune per app if eviction is too aggressive.
  • The auth password is rotated together with the rest of the app's SOPS-encrypted secrets — see Topics → SOPS / age key rotation for the procedure.

Cluster Deployment

Kubernetes Metadata
  • Image: valkey/valkey:9.1.0-alpine@sha256:a35428eba9043cc0b79dbe54100f0c92784f2de00ad09b01182bfb1c5c83d1bd
Rendered manifests (kustomize build)
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: valkey
spec:
replicas: 1
selector:
matchLabels:
app: valkey
serviceName: valkey
template:
metadata:
labels:
app: valkey
spec:
containers:
- args:
- valkey-server
image: valkey/valkey:9.1.0-alpine@sha256:a35428eba9043cc0b79dbe54100f0c92784f2de00ad09b01182bfb1c5c83d1bd
livenessProbe:
initialDelaySeconds: 10
periodSeconds: 10
tcpSocket:
port: 6379
name: valkey
ports:
- containerPort: 6379
name: client
readinessProbe:
initialDelaySeconds: 3
periodSeconds: 5
tcpSocket:
port: 6379
resources:
limits:
memory: 512Mi
requests:
cpu: 50m
memory: 128Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
volumeMounts:
- mountPath: /conf
name: conf
- mountPath: /data
name: data
securityContext:
fsGroup: 1000
fsGroupChangePolicy: OnRootMismatch
runAsGroup: 1000
runAsNonRoot: true
runAsUser: 999
seccompProfile:
type: RuntimeDefault
volumes:
- emptyDir: {}
name: conf
- emptyDir: {}
name: data