Skip to content

Redis

Deploy Redis on Kubernetes using the official redis Docker image. Supports four architectures: standalone (single instance), replication (primary + replicas), Sentinel (automatic HA failover), and cluster (horizontal sharding). The chart keeps simple defaults for development while exposing production controls for authentication, TLS, persistence, memory limits, dual-stack Services, and External Secrets Operator integration.

OOMKilled: Redis stores all data in memory — always set maxmemory and resources.limits.memory

Redis is an in-memory data store. If your dataset grows beyond the container’s memory limit, Kubernetes kills the pod with OOMKilled. Always set resources.limits.memory and configure config.redis with maxmemory (slightly below the memory limit) and a maxmemory-policy appropriate for your use case. Without these, Redis will consume all available memory.

Sentinel clients must use the Sentinel service — direct master connection breaks after failover

In Sentinel mode, the master pod changes after a failover event. Applications that connect directly to the master pod IP or hostname will fail after failover. Always use a Sentinel-aware client library that queries the Sentinel service (port 26379) to discover the current master dynamically.

Architectures

ArchitectureUse CaseHAHorizontal Scale
standaloneDevelopment, low-traffic caching.
replicationRead scaling via replicas, manual failover.Read only
sentinelAutomatic failover HA for persistent data.Read only
clusterLarge datasets exceeding single-node memory.Full

Standalone

Single Redis instance with persistent storage (RDB/AOF).

Application client TCP:6379 Redis StatefulSet (1 pod) in-memory + AOF PVC (data)

Sentinel

Redis primary with replicas, monitored by Sentinel for automatic failover.

Application client query Sentinel (3 pods) monitors + failover Master read + write pod-0 repl Replica read-only pod-1 PVC PVC

Key Features

  • Four architectures — standalone, replication, Sentinel, cluster
  • Sentinel quorum — configurable failover quorum (default: 2 out of 3 Sentinels)
  • Cluster mode — 6 nodes by default (3 master + 3 replica), auto-initialized via init Job
  • TLS encryption — mutual TLS for all Redis connections
  • existingSecret — keep credentials out of the values file
  • External Secrets Operator — optional external-secrets.io/v1 resource for Redis auth Secret materialization
  • Dual-stack Services — optional Service ipFamilyPolicy and ipFamilies across Redis, Sentinel, cluster, and metrics Services
  • config.redis — custom redis.conf lines (maxmemory, eviction policy, etc.)
  • Prometheus exporteroliver006/redis_exporter sidecar with ServiceMonitor
  • Non-root — runs as UID/GID 999 by default

Installation

HTTPS repository:

helm repo add helmforge https://repo.helmforge.dev
helm repo update
helm install my-redis helmforge/redis -f values.yaml

OCI registry:

helm install my-redis oci://ghcr.io/helmforgedev/helm/redis -f values.yaml

Deployment Examples

# values.yaml — Redis standalone (persistent, single instance)
architecture: standalone

auth:
  enabled: true
  existingSecret: redis-credentials
  existingSecretPasswordKey: redis-password

standalone:
  persistence:
    enabled: true
    size: 20Gi
  resources:
    requests:
      memory: 256Mi
      cpu: 100m
    limits:
      memory: 1Gi

config:
  redis: |
    maxmemory 800mb       # ~80% of limits.memory; leave headroom for overhead
    maxmemory-policy allkeys-lru
    save 900 1            # RDB: save after 900s if at least 1 key changed
    save 300 10
    appendonly yes        # AOF for durability

metrics:
  enabled: true
  serviceMonitor:
    enabled: true
# values.yaml — Redis Sentinel HA (primary + 3 replicas + 3 Sentinels)
# Requires Sentinel-aware client (redis-py, Jedis, ioredis with Sentinel option)
# Connect to port 26379 (Sentinel) — clients discover the current primary dynamically
architecture: sentinel

auth:
  enabled: true
  existingSecret: redis-credentials
  existingSecretPasswordKey: redis-password

replication:
  replicaCount: 3
  primary:
    persistence:
      enabled: true
      size: 20Gi
    resources:
      limits:
        memory: 2Gi
  replica:
    persistence:
      enabled: true
      size: 20Gi

sentinel:
  replicaCount: 3 # always deploy an ODD number of Sentinels
  quorum: 2 # minimum Sentinels that must agree to trigger failover
  downAfterMilliseconds: 60000 # time without response before marking as down
  failoverTimeout: 180000

config:
  redis: |
    maxmemory 1700mb   # ~85% of limits.memory
    maxmemory-policy allkeys-lru

metrics:
  enabled: true
  serviceMonitor:
    enabled: true

pdb:
  enabled: true # prevent all Sentinel pods from being evicted simultaneously
# values.yaml — Redis Cluster (horizontal sharding for large datasets)
# Cluster mode distributes keys across 3 master shards (each with 1 replica)
# Requires cluster-aware client library
architecture: cluster

auth:
  enabled: true
  existingSecret: redis-credentials
  existingSecretPasswordKey: redis-password

cluster:
  nodes: 6 # total pods: 3 masters + 3 replicas (minimum for cluster)
  replicasPerMaster: 1
  initJob:
    enabled: true # Job that runs redis-cli --cluster create after pods are ready
  persistence:
    enabled: true
    size: 20Gi
  resources:
    limits:
      memory: 2Gi

config:
  redis: |
    maxmemory 1700mb   # per-shard; total dataset capacity = maxmemory × number of masters
    maxmemory-policy allkeys-lru

metrics:
  enabled: true
  serviceMonitor:
    enabled: true
# values.yaml — Redis as ephemeral cache (no persistence, LRU eviction)
# Data is lost on pod restart — acceptable only for pure caching use cases
architecture: standalone

auth:
  enabled: true
  existingSecret: redis-credentials
  existingSecretPasswordKey: redis-password

standalone:
  persistence:
    enabled: false # ephemeral; no PVC
  resources:
    requests:
      memory: 128Mi
    limits:
      memory: 512Mi

config:
  redis: |
    maxmemory 400mb           # ~80% of limits.memory
    maxmemory-policy allkeys-lru   # evict least-recently-used keys when full
    save ""                   # disable RDB snapshots
    appendonly no             # disable AOF (pure cache mode)
# values.yaml - auth Secret managed by External Secrets Operator
auth:
  enabled: true
  existingSecret: redis-credentials
  existingSecretPasswordKey: redis-password

externalSecrets:
  enabled: true
  apiVersion: external-secrets.io/v1
  refreshInterval: 1h
  secretStoreRef:
    name: platform-secrets
    kind: ClusterSecretStore
  data:
    - secretKey: redis-password
      remoteRef:
        key: prod/redis
        property: password
External Secrets Operator is optional

The chart renders the Redis auth ExternalSecret only when externalSecrets.enabled=true. It does not install the operator or create the referenced SecretStore.

Production Path

Use defaults for local development, cache experiments, and disposable clusters. For production, choose the topology first: sentinel for automatic failover of a single logical dataset, or cluster when the dataset must be sharded across multiple masters.

Always set resources.limits.memory and config.redis maxmemory together. Keep maxmemory below the memory limit so Redis has room for client buffers, persistence buffers, Lua, and allocator overhead. Use existing Secrets or External Secrets for credentials, enable TLS when traffic crosses a trust boundary, and enable PodDisruptionBudget for Sentinel or clustered deployments.

Configuration Reference

Image

ParameterTypeDefaultDescription
image.repositorystringdocker.io/library/redisRedis image.
image.tagstring"8.6.3"Image tag.

Authentication

ParameterTypeDefaultDescription
auth.enabledbooleantrueEnable password authentication.
auth.passwordstring""Redis password. Auto-generated if empty.
auth.existingSecretstring""Existing secret with Redis password.
auth.existingSecretPasswordKeystringredis-passwordKey for the password in the existing secret.

TLS

ParameterTypeDefaultDescription
tls.enabledbooleanfalseEnable TLS. Requires tls.existingSecret with cert/key/CA.
tls.existingSecretstring""Secret with tls.crt, tls.key, ca.crt.
tls.certFilenamestringtls.crtCertificate filename in the TLS Secret.
tls.keyFilenamestringtls.keyPrivate key filename in the TLS Secret.
tls.caFilenamestringca.crtCA filename in the TLS Secret.

Standalone

ParameterTypeDefaultDescription
standalone.persistence.enabledbooleantrueEnable PVC for standalone.
standalone.persistence.sizestring8GiPVC size.
standalone.resourcesobject{}CPU and memory requests/limits.

Replication

ParameterTypeDefaultDescription
replication.replicaCountinteger2Number of replica pods.
replication.primary.persistence.sizestring8GiPrimary PVC size.
replication.replica.persistence.sizestring8GiReplica PVC size.

Sentinel

ParameterTypeDefaultDescription
sentinel.replicaCountinteger3Number of Sentinel pods (always use an odd number).
sentinel.quoruminteger2Minimum Sentinels that must agree to trigger failover.
sentinel.downAfterMillisecondsinteger60000Milliseconds before marking a primary as down.
sentinel.failoverTimeoutinteger180000Failover timeout in milliseconds.
sentinel.parallelSyncsinteger1Replicas that sync in parallel during failover.

Cluster

ParameterTypeDefaultDescription
cluster.nodesinteger6Total cluster nodes (minimum 6: 3 masters + 3 replicas).
cluster.replicasPerMasterinteger1Replicas per master shard.
cluster.initJob.enabledbooleantrueRun redis-cli --cluster create Job after pods are ready.
cluster.persistence.sizestring8GiPVC size per cluster node.

Configuration and Metrics

ParameterTypeDefaultDescription
config.redisstring""Extra lines appended to redis.conf (maxmemory, save, appendonly, etc.).
config.sentinelstring""Extra lines appended to sentinel.conf.
metrics.enabledbooleanfalseDeploy redis_exporter Prometheus sidecar.
metrics.image.tagstringv1.69.0redis_exporter image tag.
metrics.serviceMonitor.enabledbooleanfalseCreate Prometheus ServiceMonitor resource.
pdb.enabledbooleanfalseEnable PodDisruptionBudget.
service.ports.redisinteger6379Redis client port.
service.ports.sentinelinteger26379Sentinel client port.
service.ipFamilyPolicystringomittedService IP family policy: SingleStack, PreferDualStack, or RequireDualStack.
service.ipFamiliesarray[]Ordered Service IP families (IPv4, IPv6). Empty uses cluster default.
extraManifestsarray[]Extra Kubernetes manifests.

External Secrets Operator

ParameterTypeDefaultDescription
externalSecrets.enabledbooleanfalseRender ExternalSecret for the Redis auth Secret.
externalSecrets.apiVersionstringexternal-secrets.io/v1ExternalSecret API version.
externalSecrets.refreshIntervalstring"0"ExternalSecret refresh interval.
externalSecrets.secretStoreRef.namestring""Existing SecretStore or ClusterSecretStore name.
externalSecrets.dataarray[]Remote references mapped to Redis password keys.
Set maxmemory to ~80% of resources.limits.memory

Redis needs headroom above maxmemory for internal overhead (AOF buffers, client output buffers, Lua, etc.). A safe rule: set maxmemory to 80–85% of resources.limits.memory. For example, a pod with limits.memory: 1Gi should use maxmemory 820mb.

Dual-stack Networking

Redis Services accept Kubernetes dual-stack settings. By default service.ipFamilyPolicy is omitted and service.ipFamilies is empty, so the cluster default remains authoritative. Set these only when the target cluster supports the requested IP families.

service:
  ipFamilyPolicy: PreferDualStack
  ipFamilies:
    - IPv4
    - IPv6

PreferDualStack is the safest explicit policy for clusters that may be single-stack or dual-stack. Use RequireDualStack only when both IPv4 and IPv6 are guaranteed.

Upgrade Notes

Sentinel failover during rolling upgrades is expected behavior

In Sentinel mode, rolling upgrades restart the primary pod and trigger a failover. Sentinel promotes a replica to primary. Applications using Sentinel-aware clients handle this transparently. Expect a brief connection interruption (seconds) during master pod restart.

  • Switching from standalone to sentinel or cluster requires a fresh deployment and data migration (redis-cli --rdb, Valkey migration tools, or a DUMP/RESTORE approach)
  • Persistence changes only affect new pods; existing PVCs retain their size
  • Custom config.redis lines are appended to the generated redis.conf

More Information