Redis-Sentinel Sidecar Pattern Hands-on Guide on Kubernetes ①


Sidecar pattern concept

This page covers a tightly coupled two-container (two-process) design in one Pod. For example, you may attach a log collector or security proxy (sidecar) next to a main web-server container (Nginx, Node.js). Use a sidecar when it is subordinate to the main container. If the main container goes down, a surviving sidecar is useless.

The idea is a bit different: Sentinel should run separately from Redis (it monitors Redis, so it must not die with Redis in the same Pod; dedicated Sentinel Pods are the right design). Still, if you must run Redis-Sentinel in only three Pods, you can try this pattern.   Fortunately Sentinel uses only about 1–2% of one CPU core (under 5% at peak) and about 10MB of memory, so we will build it as a sidecar.

1. Redis-Sentinel sidecar YAML spec

When deploying the Redis-Sentinel sidecar pattern on Kubernetes, split Config, Service, and StatefulSet into three YAML files.

┌──────────────────────────────────────────────────────────┐ │ 1. redis-sentinel-sidecar-config.yaml (ConfigMap) │ │ : redis.conf, sentinel.conf, users.acl │ └──────────────────┬───────────────────────────────────────┘ │ [Step 1: provide config] ▼ ┌──────────────────────────────────────────────────────────┐ │ 2. redis-sentinel-sidecar-service.yaml (Service) │ │ : redis-sentinel-service, port, sentinel-port │ └──────────────────┬───────────────────────────────────────┘ │ [Step 2: prepare Service] ▼ ┌──────────────────────────────────────────────────────────┐ │ 3. redis-sentinel-sidecar-statefulset.yaml (StatefulSet) │ │ : Config, Service -> redis-sentinel-0~3 (3Pods) │ │ Persistent Volume Claim (PVC) │ └──────────────────────────────────────────────────────────┘ [Step 3: create Redis/Sentinel Pods]

2. File contents in apply order

🟢 [Step 1] Redis-Sentinel sidecar config: redis-sentinel-sidecar-config.yaml

  • kind: ConfigMap
  • metadata.name: redis-sentinel-sidecar-config
    ⚠️ Names may use only lowercase a-z, digits 0-9, and hyphen (`-`) (no uppercase)
  • This ConfigMap holds the directives used to create redis.conf and sentinel.conf.
  • The default redis.conf and sentinel.conf from the Redis tarball are not used.
  • If each Redis instance (Pod) needs different values, inject them dynamically with a command script in the StatefulSet.   Example: replica-priority 100, 110, 120

🧑‍💻 Key fields

  • bind * -::* # Pod IPs are assigned dynamically and change, so bind all addresses.
    KISA Cloud Vulnerability Assessment Guide requires setting a specific IP on bind for security.   That is correct on VMs and bare metal, but you cannot pin bind to a fixed IP on Kubernetes.
    (Explain this clearly to auditors on public-sector and financial projects.)
  • protected-mode no # Because bind is '*', setting protected-mode yes would block external clients.
    It looks like a security exception, but Kubernetes already isolates the network, so this setting is fine.
  • daemonize no # Do not set this to yes.
  • requirepass password # 💥 Always set a password. If the host is on the internet, set a password even in development. Redis is not hacked by a person at a keyboard; 💻 programs scan 24 hours a day. Without a password, even a few minutes of a “dev” instance can be taken over.
    See: 🔗 Redis Hacking
    If you configure users.acl, requirepass is optional.
  • masterauth password # Always set this.
  • replica-priority 100 # 📍Redis-0 100, Redis-1 110, Redis-2 120
    Injected dynamically from the StatefulSet initContainer command.
  • replica-announce-ip # 📍redis-0.redis-service...
    Injected dynamically from the StatefulSet initContainer command.
    echo "replica-announce-ip redis-$INDEX.redis-service.default.svc.cluster.local" >> /data/redis.conf
  • users.acl: lines 66–67. Set the 64-character password ('#0cbc...') separately.
    See: 🔗 ACL
💾 View redis-sentinel-sidecar-config.yaml ▼
📄 redis-sentinel-sidecar-config.yaml

These values are the redis.conf settings redisGate has applied at 90%+ of 100+ production sites.   (Tune maxmemory to your data size)

💻 On bare metal or VMs, change the following.

  • bind 114.x.y.z 127.0.0.1 -::1 -> bind a specific IP
  • protected-mode yes
  • port -> default 💥6379 is a prime hacking target. Use another port.
  • daemonize yes
  • dir /app/redis -> put pidfile, logfile, etc. in this dir
  • aclfile /app/redis/users.acl -> per-user ACLs: recommended
  • #maxmemory <bytes> -> leave commented (default)
    ① Dedicated Redis server: set 50%–90% of system RAM
    ② Plenty of RAM: if the host has 16GB and Redis uses 1–2GB, you can skip maxmemory
    ③ 💥 If Redis consumes all RAM, Linux will kill the Redis process.
  • # replica-announce-ip -> leave commented (default)

🟢 [Step 2] Service: redis-sentinel-sidecar-service.yaml

  • kind: Service
  • metadata.name: redis-sentinel-service
    ⚠️ Names may use only lowercase a-z, digits 0-9, and hyphen (`-`) (no uppercase)
  • This is the Service YAML.   Even when Pod IPs change, a stable FQDN (Fully Qualified Domain Name) lets clients reach each Redis like a network directory.

🧑‍💻 Key fields

  • clusterIP: None # 📍 set to None (per-Pod DNS identity)
  • port: 18504 # Redis port
  • port: 28504 # Sentinel port
💾 View redis-sentinel-sidecar-service.yaml ▼
📄 redis-sentinel-sidecar-service.yaml

🟢 [Step 3] Redis/Sentinel Pod spec: redis-sentinel-sidecar-statefulset.yaml

StatefulSet spec for Redis Pods (replicas, initContainers, memory, PVC).

  • kind: StatefulSet
  • metadata.name: redis-sentinel
    ⚠️ Names may use only lowercase a-z, digits 0-9, and hyphen (`-`) (no uppercase)
    Kubernetes names Pods redis-sentinel-0,1,2 from this name.
    Pod name + serviceName form the FQDN:
    redis-sentinel-0.redis-sentinel-service.default.svc.cluster.local
    Each Redis gets a unique FQDN for Redis-to-Redis, Sentinel-to-Redis, and app traffic. When the IP changes, DNS maps the same FQDN to the new IP.

🧑‍💻 Key fields

  • configMap: name: redis-sentinel-sidecar-config (links to Step 1 Redis/Sentinel config)
  • serviceName: redis-sentinel-service (links to Step 2 Service)
  • replicas: 3
    • Pod ① Redis-0 (Master) / Sentinel-0
    • Pod ② Redis-1 (Replica-1) / Sentinel-1
    • Pod ③ Redis-2 (Replica-2) / Sentinel-2
  • image: redis:8.8.2 # Redis 8.8.2, released 2026-08-17 (Mon)
  • imagePullPolicy: IfNotPresent # use local image
  • command script: copy ConfigMap files and inject dynamic settings
  • volumeMounts mountPath /data: all Redis files (redis.conf, users.acl, AOF, etc.).
💾 redis-sentinel-sidecar-statefulset.yaml ▼
📄 redis-sentinel-sidecar-statefulset.yaml

🧑‍💻 initContainers command script

  • Extract the Pod index (redis-sentinel-0 -> 0, redis-sentinel-1 -> 1, redis-sentinel-2 -> 2) and use it for per-Pod dynamic config.
    📄 initContainers: command

  • Do not overwrite redis.conf if it already exists (copy and inject only on first boot).
    Redis writes redis.conf on important events, so do not copy a fresh file over it on restart.
    📄 initContainers: command: redis.conf

  • Do not overwrite users.acl if it already exists (copy only on first boot).
    📄 initContainers: command: users.acl

  • Do not overwrite sentinel.conf if it already exists (copy and inject only on first boot).
    📄 initContainers: command: sentinel.conf

🧑‍💻 containers command script

  • Add convenient aliases to .bashrc
    📄 containers: command: .bashrc
    With '--color=auto', filenames are colored as follows:
    dir file: redis-sentinel-model
    exec file: cluster_create.sh
    tar file: file redis-8.8.2.tar
  • Default time is UTC. Switch to host OS time (Korea).
    📄 containers command: use host OS time

➡ YAML is ready. Next we create the Pods.


<< K8s Redis-Sentinel App ② K8s Sidecar Pattern Setup ② >>

Email 답글이 올라오면 이메일로 알려드리겠습니다.