k8s_redis_cluster_1
Redis-Cluster on Kubernetes: Hands-on Guide ①
Manifest (YAML) overview
Redis-Cluster overview
Redis-Cluster spreads data across three Redis Pods (masters), and each master Pod has a backup (replica) Pod.
If a Redis master Pod goes down, the backup (replica) Redis is promoted to master.
Let’s build Redis-Cluster with six Pods (3 masters, 3 replicas).
🔗
See here for an overall Redis-Cluster overview.
1. Redis-Cluster manifests (YAML)
When you deploy Redis-Cluster on Kubernetes, split the work into Config, Service, and creation (StatefulSet) roles and manage them as three YAML files.
2. File contents by deploy order
🟢 [Step 1] Redis config: redis-cluster-config.yaml
- kind: ConfigMap
- name (metadata:name): redis-cluster-config
⚠️ Names are strictly limited to lowercase (a-z), digits (0-9), and hyphen (`-`) (uppercase is not allowed)
- This is the ConfigMap settings file. The directives here are used to create redis.conf.
- The redis.conf that ships with the tarball is not used.
- If each Redis instance (Pod) needs a different value, you can set it dynamically with a command script in the StatefulSet. Example) cluster-announce-hostname redis-cluster-0,1,2...
🧑💻 Key values
- bind * -::* # IPs are assigned and change dynamically, so accept all IPs.
KISA (Korea Internet & Security Agency) [Cloud Vulnerability Assessment Guide] insists on setting an IP on bind for security. That is correct on VMs/bare metal, but you cannot do that in Kubernetes.
(You will need to explain this clearly to auditors on public-sector/finance projects.) - protected-mode no # Because bind is '*', setting 'yes' blocks external connections.
It may look like a security violation, but Kubernetes has its own security, so this setting is fine. - daemonize no # Do not set this to 'yes'.
- requirepass password # 💥Always set a password.
If the server or PC is on the internet, set a password even in a development environment.
Redis is not hacked by 🕵️people (hackers) but by 💻 programs that scan 24 hours a day.
Without a password, even a few minutes of a dev instance can be compromised immediately.
See here for details. 🔗 Redis Hacking
If you configure users.acl, you do not need to set 'requirepass'. - masterauth password # Always set this.
- cluster-node-timeout 3000 # Node-down detection time (3000ms (3sec)): set to 3 seconds.
- cluster-announce-hostname, cluster-announce-human-nodename These two items are injected dynamically
at Pod creation time: the initContainer command in statefulset.yaml looks up the Pod name.
So do not set them here.
echo "cluster-announce-hostname ${POD_FQDN}" >> /data/redis.conf
echo "cluster-announce-human-nodename ${POD_NAME}" >> /data/redis.conf
- users.acl: lines 90–91. Password ('#0cbc...' 64 chars) must be set separately.
See here for details. 🔗 ACL
💾 View redis-cluster-config.yaml
The values shown here are redis.conf settings applied at 90%+ of the 100+ sites redisGate has installed and operated.
(Adjust maxmemory to match your data size)
💻 On bare metal/VMs, change the following values.
- bind 114.x.y.z 127.0.0.1 -::1 -> pin an IP
- protected-mode yes
- port -> default 💥port 6379 is a major hacking target. Always use a different port.
- daemonize yes
- dir /app/redis -> also put pidfile, logfile, etc. under this dir
- aclfile /app/redis/users.acl -> per-user permissions: recommended
- #maxmemory <bytes> -> comment out (default)
① On a Redis-dedicated server, set 50%–90% of system memory
② If you have plenty of RAM: e.g. 16GB system memory and Redis using 1–2GB, (in practice) you may not need to set it
③ 💥 If Redis uses all system memory, the OS (Linux) kills the Redis process. - #cluster-announce-hostname "" -> comment out (default)
- #cluster-announce-human-nodename "" -> comment out (default)
🟢 [Step 2] Service config: redis-cluster-service.yaml
- kind: Service
- name (metadata:name): redis-cluster-service
⚠️ Names are strictly limited to lowercase (a-z), digits (0-9), and hyphen (`-`) (uppercase is not allowed)
- This is the Service settings file.
Even if Pod IPs change, it prepares a network address board so you can reach each Redis
by a stable domain name (FQDN: Fully Qualified Domain Name).
🧑💻 Key values
- clusterIP: None # 📍Set to 'None' (to identify each Pod DNS independently)
- port: 18504 # Redis port
- port: 28504 # Redis Cluster bus port
💾 View redis-cluster-service.yaml
🟢 [Step 3] Redis Pod creation manifest: redis-cluster-statefulset.yaml
Manifest file that creates Redis Pods (replicas, initContainers, memory, pvc (disk volume)).
- kind: StatefulSet
- name (metadata:name): redis-cluster
⚠️ Names are limited to lowercase (a-z), digits (0-9), and hyphen (`-`) (uppercase is not allowed)
Pod names are built from this name plus a number: redis-cluster-0,1,2.
The Pod name and serviceName are used to build an FQDN (Fully Qualified Domain Name) as follows.
redis-cluster-0.redis-cluster-service.default.svc.cluster.local
Each Redis can talk to other Redis instances or to the App by its unique FQDN.
When the IP changes, the new IP is bound to the FQDN.
🧑💻 Key values
- configMap: name: redis-cluster-config (linked to Step 1 Redis config)
- serviceName: redis-cluster-service (linked to Step 2 Service)
- replicas: 6 # Create 6 Redis Pods. Splitting roles into Master (3) and Replica (3) is decided when Redis-Cluster is created.
- image: redis:8.8.2 # Use version 8.8.2, released 17 Aug 2026 (Mon)
- imagePullPolicy: IfNotPresent # Use the local image
- command script: copy ConfigMap files from Step 1 and apply dynamic settings
- volumeMounts: mountPath: /data: stores all files Redis uses/manages
(redis.conf, users.acl, aof files, and so on).
💾 View redis-cluster-statefulset.yaml
🧑💻 initContainers: command: script notes
- ① Copy read-only redis.conf from ConfigMap to writable /data
Redis can rewrite the conf file with 'config rewrite', and when Master-Replica roles change the 'replicaof' directive is rewritten. So redis.conf must live in a read-write directory.
📄 initContainers: command: cp redis.conf - ② Copy users.acl and set permissions
📄 initContainers: command: cp users.acl - ③ Resolve Redis Cluster FQDN dynamically and inject cluster-announce-*name
📄 initContainers: command: cluster-announce-*name
🧑💻 containers: command: script notes
- ④ 🚩 Add a few handy aliases in .bashrc
📄 containers: command: .bashrc
With '--color=auto', filenames are colored as shown below.
dir file: redis-sentinel-model
exec file: cluster_create.sh
tar file: file redis-8.8.2.tar
- ⑤ redis.tar timestamps are UTC (UK). Switch to host OS time (Korea time here).
📄 containers: command: localtime
➡ Prep is done. Let’s create the Pods.
| << Preparing Redis on Kubernetes ③ | K8s Redis-Cluster Setup ② >> |
|---|
