Databases 15 min read

Deploying a Scalable Redis Cluster on Kubernetes: Step‑by‑Step Guide

This article introduces Redis, explains its advantages, describes Redis Cluster architecture, and provides a detailed, hands‑on tutorial for deploying a Redis Cluster on Kubernetes using StatefulSets, PersistentVolumes, services, and a sample hit‑counter application, complete with configuration files and verification commands.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
Deploying a Scalable Redis Cluster on Kubernetes: Step‑by‑Step Guide

Redis Introduction

Redis stands for REmote DIctionary Server. It is an open‑source in‑memory data store commonly used as a database, cache, or message broker. Redis can store and manipulate advanced data types such as lists, maps, sets, and sorted sets, and it accepts keys in many formats, reducing client workload. It persists data to disk only for durability while keeping the database entirely in memory. Major tech companies like GitHub, Pinterest, Snapchat, Twitter, StackOverflow and Flickr use Redis.

Why Use Redis

It is extremely fast, written in ANSI C and runs on POSIX systems such as Linux, macOS and Solaris.

Redis is often ranked as the most popular key/value database and the most popular NoSQL database used with containers.

Its caching solution reduces calls to cloud database back‑ends.

Applications can access it via client API libraries.

All major programming languages have Redis support.

It is open‑source and stable.

What is Redis Cluster

Redis Cluster is a set of Redis instances that scales the database by partitioning data, making it more resilient. Each member (master or replica) manages a subset of hash slots. If a master becomes unavailable, its replica is promoted. In the minimal three‑master cluster, each master has one replica and is assigned a range of hash slots (0‑16383). Nodes communicate via an internal bus using a protocol to share cluster information.

Deploying Redis Cluster in Kubernetes

Deploying a Redis Cluster in Kubernetes is challenging because each Redis instance relies on a configuration file that tracks other cluster members and their roles. The solution combines Kubernetes StatefulSets and PersistentVolumes to manage configuration and storage.

Clone Deployment Files

git clone https://github.com/llmgo/redis-sts.git

Create StatefulSet Resource

[root@node01 redis-sts]# cat redis-sts.yml
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: redis-cluster
data:
  update-node.sh: |
    #!/bin/sh
    REDIS_NODES="/data/nodes.conf"
    sed -i -e "/myself/ s/[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/${POD_IP}/" ${REDIS_NODES}
    exec "$@"
  redis.conf: |+
    cluster-enabled yes
    cluster-require-full-coverage no
    cluster-node-timeout 15000
    cluster-config-file /data/nodes.conf
    cluster-migration-barrier 1
    appendonly yes
    protected-mode no
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis-cluster
spec:
  serviceName: redis-cluster
  replicas: 6
  selector:
    matchLabels:
      app: redis-cluster
  template:
    metadata:
      labels:
        app: redis-cluster
    spec:
      containers:
      - name: redis
        image: redis:5.0.5-alpine
        ports:
        - containerPort: 6379
          name: client
        - containerPort: 16379
          name: gossip
        command: ["/conf/update-node.sh", "redis-server", "/conf/redis.conf"]
        env:
        - name: POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        volumeMounts:
        - name: conf
          mountPath: /conf
          readOnly: false
        - name: data
          mountPath: /data
          readOnly: false
      volumes:
      - name: conf
        configMap:
          name: redis-cluster
          defaultMode: 0755
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 5Gi
      storageClassName: standard
$ kubectl apply -f redis-sts.yml
configmap/redis-cluster created
statefulset.apps/redis-cluster created
$ kubectl get pods -l app=redis-cluster
NAME               READY   STATUS    RESTARTS   AGE
redis-cluster-0    1/1     Running   0          53s
redis-cluster-1    1/1     Running   0          49s
redis-cluster-2    1/1     Running   0          46s
redis-cluster-3    1/1     Running   0          42s
redis-cluster-4    1/1     Running   0          38s
redis-cluster-5    1/1     Running   0          34s

Create Service

[root@node01 redis-sts]# cat redis-svc.yml
---
apiVersion: v1
kind: Service
metadata:
  name: redis-cluster
spec:
  type: ClusterIP
  clusterIP: 10.96.0.100
  ports:
  - port: 6379
    targetPort: 6379
    name: client
  - port: 16379
    targetPort: 16379
    name: gossip
  selector:
    app: redis-cluster
$ kubectl apply -f redis-svc.yml
service/redis-cluster created
$ kubectl get svc redis-cluster
NAME            TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                 AGE
redis-cluster   ClusterIP   10.96.0.100  <none>        6379/TCP,16379/TCP    35s

Initialize Redis Cluster

Next, we form the Redis cluster. To do this we run the following command and type yes to accept the configuration. The first three nodes become masters and the last three become replicas.
$ kubectl exec -it redis-cluster-0 -- redis-cli --cluster create --cluster-replicas 1 $(kubectl get pods -l app=redis-cluster -o jsonpath='{range.items[*]}{.status.podIP}:6379 ') 
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 10.244.2.11:6379 to 10.244.9.19:6379
Adding replica 10.244.9.20:6379 to 10.244.6.10:6379
Adding replica 10.244.8.15:6379 to 10.244.7.8:6379
M: 00721c43db194c8f2cacbafd01fd2be6a2fede28 10.244.9.19:6379 slots:[0-5460] (5461 slots) master
M: 9c36053912dec8cb20a599bda202a654f241484f 10.244.6.10:6379 slots:[5461-10922] (5462 slots) master
M: 2850f24ea6367de58fb50e632fc56fe4ba5ef016 10.244.7.8:6379 slots:[10923-16383] (5461 slots) master
S: 554a58762e3dce23ca5a75886d0ccebd2d582502 10.244.8.15:6379 replicates 2850f24ea6367de58fb50e632fc56fe4ba5ef016
S: 20028fd0b79045489824eda71fac9898f17af896 10.244.2.11:6379 replicates 00721c43db194c8f2cacbafd01fd2be6a2fede28
S: 87e8987e314e4e5d4736e5818651abc1ed6ddcd9 10.244.9.20:6379 replicates 9c36053912dec8cb20a599bda202a654f241484f
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
>>> Performing Cluster Check (using node 10.244.9.19:6379)
M: 00721c43db194c8f2cacbafd01fd2be6a2fede28 10.244.9.19:6379 slots:[0-5460] (5461 slots) master 1 additional replica(s)
M: 9c36053912dec8cb20a599bda202a654f241484f 10.244.6.10:6379 slots:[5461-10922] (5462 slots) master 1 additional replica(s)
S: 87e8987e314e4e5d4736e5818651abc1ed6ddcd9 10.244.9.20:6379 slots:(0 slots) slave replicates 9c36053912dec8cb20a599bda202a654f241484f
S: 554a58762e3dce23ca5a75886d0ccebd2d582502 10.244.8.15:6379 slots:(0 slots) slave replicates 2850f24ea6367de58fb50e632fc56fe4ba5ef016
S: 20028fd0b79045489824eda71fac9898f17af896 10.244.2.11:6379 slots:(0 slots) slave replicates 00721c43db194c8f2cacbafd01fd2be6a2fede28
M: 2850f24ea6367de58fb50e632fc56fe4ba5ef016 10.244.7.8:6379 slots:[10923-16383] (5461 slots) master 1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

Validate Cluster

$ kubectl exec -it redis-cluster-0 -- redis-cli cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:16
cluster_stats_messages_pong_sent:22
cluster_stats_messages_sent:38
cluster_stats_messages_ping_received:17
cluster_stats_messages_pong_received:16
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:38
$ for x in $(seq 0 5); do echo "redis-cluster-$x"; kubectl exec redis-cluster-$x -- redis-cli role; echo; done
redis-cluster-0
master
14
10.244.2.11
6379
14

redis-cluster-1
master
28
10.244.9.20
6379
28

redis-cluster-2
master
28
10.244.8.15
6379
28

redis-cluster-3
slave
10.244.7.8
6379
connected
28

redis-cluster-4
slave
10.244.9.19
6379
connected
14

redis-cluster-5
slave
10.244.6.10
6379
connected
28

Test Cluster

We intend to use the cluster and simulate node failures. For the first task we deploy a simple Python application; for the second we delete a node and observe cluster behavior.

Deploy Hit Counter Application

A simple application is deployed in front of a load balancer; it increments a counter stored in the Redis cluster and returns the count as an HTTP response.

$ kubectl apply -f app-deployment-service.yml
service/hit-counter-lb created
deployment.apps/hit-counter-app created

When repeatedly accessing the service, the counter increases, and after deleting a pod no data is lost.

$ curl `kubectl get svc hit-counter-lb -o json|jq -r .spec.clusterIP`
I have been hit 20 times since deployment.
$ curl `kubectl get svc hit-counter-lb -o json|jq -r .spec.clusterIP`
I have been hit 21 times since deployment.
$ curl `kubectl get svc hit-counter-lb -o json|jq -r .spec.clusterIP`
I have been hit 22 times since deployment.
$ kubectl delete pods redis-cluster-0
pod "redis-cluster-0" deleted
$ kubectl delete pods redis-cluster-1
pod "redis-cluster-1" deleted
$ curl `kubectl get svc hit-counter-lb -o json|jq -r .spec.clusterIP`
I have been hit 23 times since deployment.

Reference Documents

http://llmgo.cn/post/redis-003/

http://www.yunweipai.com/36338.html

https://blog.csdn.net/shuyun123456789/article/details/60868718

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

databaseKubernetesredisStatefulSetRedis Cluster
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.