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.
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.
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).
Sentinel
Redis primary with replicas, monitored by Sentinel for automatic failover.
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/v1resource for Redis auth Secret materialization - Dual-stack Services — optional Service
ipFamilyPolicyandipFamiliesacross Redis, Sentinel, cluster, and metrics Services config.redis— customredis.conflines (maxmemory, eviction policy, etc.)- Prometheus exporter —
oliver006/redis_exportersidecar 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: passwordThe 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.6.3" | 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.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. |
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
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
standalonetosentinelorclusterrequires a fresh deployment and data migration (redis-cli --rdb, Valkey migration tools, or aDUMP/RESTOREapproach) - Persistence changes only affect new pods; existing PVCs retain their size
- Custom
config.redislines are appended to the generatedredis.conf