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

Architecture Use Case HA Horizontal Scale
standalone Development, low-traffic caching.
replication Read scaling via replicas, manual failover. Read only
sentinel Automatic failover HA for persistent data. Read only
cluster Large datasets exceeding single-node memory. Full

Standalone

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

ApplicationclientTCP:6379RedisStatefulSet (1 pod)in-memory + AOFPVC (data)

Sentinel

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

ApplicationclientquerySentinel (3 pods)monitors + failoverMasterread + writepod-0replReplicaread-onlypod-1PVCPVC

Key Features

  • Four architectures — standalone, replication, Sentinel, cluster
  • Sentinel quorum — configurable failover quorum (default: 2 out of 3 Sentinels)
  • Sentinel master set — configurable primary discovery name for Sentinel-aware clients
  • 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
  masterSet: mymaster # Sentinel master set name used by clients
  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

Parameter Type Default Description
image.repository string docker.io/library/redis Redis image.
image.tag string "8.8.0" Image tag.

Authentication

Parameter Type Default Description
auth.enabled boolean true Enable password authentication.
auth.password string "" Redis password. Auto-generated if empty.
auth.existingSecret string "" Existing secret with Redis password.
auth.existingSecretPasswordKey string redis-password Key for the password in the existing secret.

TLS

Parameter Type Default Description
tls.enabled boolean false Enable TLS. Requires tls.existingSecret with cert/key/CA.
tls.existingSecret string "" Secret with tls.crt, tls.key, ca.crt.
tls.certFilename string tls.crt Certificate filename in the TLS Secret.
tls.keyFilename string tls.key Private key filename in the TLS Secret.
tls.caFilename string ca.crt CA filename in the TLS Secret.

Standalone

Parameter Type Default Description
standalone.persistence.enabled boolean true Enable PVC for standalone.
standalone.persistence.size string 8Gi PVC size.
standalone.resources object {} CPU and memory requests/limits.

Replication

Parameter Type Default Description
replication.replicaCount integer 2 Number of replica pods.
replication.primary.persistence.size string 8Gi Primary PVC size.
replication.replica.persistence.size string 8Gi Replica PVC size.

Sentinel

Parameter Type Default Description
sentinel.replicaCount integer 3 Number of Sentinel pods (always use an odd number).
sentinel.masterSet string mymaster Master set name used by Sentinel-aware clients.
sentinel.quorum integer 2 Minimum Sentinels that must agree to trigger failover.
sentinel.downAfterMilliseconds integer 60000 Milliseconds before marking a primary as down.
sentinel.failoverTimeout integer 180000 Failover timeout in milliseconds.
sentinel.parallelSyncs integer 1 Replicas that sync in parallel during failover.

Cluster

Parameter Type Default Description
cluster.nodes integer 6 Total cluster nodes (minimum 6: 3 masters + 3 replicas).
cluster.replicasPerMaster integer 1 Replicas per master shard.
cluster.initJob.enabled boolean true Run redis-cli --cluster create Job after pods are ready.
cluster.persistence.size string 8Gi PVC size per cluster node.

Configuration and Metrics

Parameter Type Default Description
config.redis string "" Extra lines appended to redis.conf (maxmemory, save, appendonly, etc.).
config.sentinel string "" Extra lines appended to sentinel.conf.
metrics.enabled boolean false Deploy redis_exporter Prometheus sidecar.
metrics.image.tag string v1.69.0 redis_exporter image tag.
metrics.serviceMonitor.enabled boolean false Create Prometheus ServiceMonitor resource.
pdb.enabled boolean false Enable PodDisruptionBudget.
service.ports.redis integer 6379 Redis client port.
service.ports.sentinel integer 26379 Sentinel client port.
service.ipFamilyPolicy string omitted Service IP family policy: SingleStack, PreferDualStack, or RequireDualStack.
service.ipFamilies array [] Ordered Service IP families (IPv4, IPv6). Empty uses cluster default.
extraManifests array [] Extra Kubernetes manifests.

External Secrets Operator

Parameter Type Default Description
externalSecrets.enabled boolean false Render ExternalSecret for the Redis auth Secret.
externalSecrets.apiVersion string external-secrets.io/v1 ExternalSecret API version.
externalSecrets.refreshInterval string "0" ExternalSecret refresh interval.
externalSecrets.secretStoreRef.name string "" Existing SecretStore or ClusterSecretStore name.
externalSecrets.data array [] 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