Deploy a Redis Cluster on Kubernetes with StatefulSets and Headless Services
This guide walks through deploying a Redis cluster on Kubernetes, covering the challenges of stateful workloads, the use of StatefulSets and Headless Services, configuration of persistence, and step‑by‑step commands to create, initialize, and expose the cluster.
Today we will try to deploy a Redis cluster in Kubernetes to explore Kubernetes details and features. (Background on Redis‑cluster is omitted.)
1. Problem Analysis
Deploying a Redis cluster on Kubernetes is similar to deploying a regular application, but there are key issues to consider:
Redis is a stateful application Each pod stores different data and its IP can change, so a plain Deployment and Service are unsuitable. Use a StatefulSet together with a Headless Service to provide stable identities and storage.
Data persistence Although Redis is memory‑based, it needs disk persistence for recovery. In a cluster you must use a shared file system plus PersistentVolumes so all pods can share the same storage.
2. Concept Introduction
Before starting, let’s introduce a few core concepts.
1) Headless Service
A Headless Service is a Service without a ClusterIP. In Kubernetes DNS it resolves to the list of IPs of the associated Pods instead of a single virtual IP.
2) StatefulSet
StatefulSetis a Kubernetes resource designed for stateful applications. It behaves like a specialized Deployment with the following characteristics:
Each Pod gets a stable network identity (e.g., redis‑0, redis‑1) and stable storage.
Pods are started and terminated in a strictly ordered sequence.
Pods retain their PersistentVolume even after deletion.
StatefulSet must be used together with a Headless Service, which adds a DNS entry for each pod in the form $(podname).$(headless‑service‑name).
3. Solution Architecture
Using StatefulSet and Headless Service, the deployment diagram is shown below:
The main steps are:
Configure a shared NFS file system.
Create PersistentVolume and PersistentVolumeClaim.
Create a ConfigMap for the Redis configuration.
Create a Headless Service.
Create a StatefulSet.
Initialize the Redis cluster.
4. Actual Operations
To simplify, we skip PV/PVC and use a plain Volume for data.
4.1 Create ConfigMap
Create redis.conf with the following content:
appendonly yes
cluster-enabled yes
cluster-config-file /var/lib/redis/nodes.conf
cluster-node-timeout 5000
dir /var/lib/redis
port 6379Then create the ConfigMap:
kubectl create configmap redis-conf --from-file=redis.conf4.2 Create Headless Service
apiVersion: v1
kind: Service
metadata:
name: redis-service
labels:
app: redis
spec:
ports:
- name: redis-port
port: 6379
clusterIP: None
selector:
app: redis
appCluster: redis-cluster4.3 Create StatefulSet
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
name: redis-app
spec:
serviceName: "redis-service"
replicas: 6
template:
metadata:
labels:
app: redis
appCluster: redis-cluster
spec:
terminationGracePeriodSeconds: 20
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- redis
topologyKey: kubernetes.io/hostname
containers:
- name: redis
image: "registry.cn-qingdao.aliyuncs.com/gold-faas/gold-redis:1.0"
command:
- "redis-server"
args:
- "/etc/redis/redis.conf"
- "--protected-mode"
- "no"
resources:
requests:
cpu: "100m"
memory: "100Mi"
ports:
- name: redis
containerPort: 6379
protocol: "TCP"
- name: cluster
containerPort: 16379
protocol: "TCP"
volumeMounts:
- name: "redis-conf"
mountPath: "/etc/redis"
- name: "redis-data"
mountPath: "/var/lib/redis"
volumes:
- name: "redis-conf"
configMap:
name: "redis-conf"
items:
- key: "redis.conf"
path: "redis.conf"
- name: "redis-data"
emptyDir: {}4.4 Initialize the Cluster
Create a temporary Ubuntu pod to act as a manager:
kubectl run -i --tty redis-cluster-manager --image=ubuntu --restart=Never /bin/bashInside the pod, install tools, download and compile Redis 5.0.3, then copy redis-cli to /usr/local/bin.
Obtain the IPs of the six pods using nslookup on the DNS names, e.g.: nslookup redis-app-0.redis-service Initialize the three master nodes:
redis-cli --cluster create 172.17.0.10:6379 172.17.0.11:6379 172.17.0.12:6379Add the three slave nodes, specifying the master IDs returned in the previous step:
redis-cli --cluster add-node 172.17.0.13:6379 172.17.0.10:6379 --cluster-slave --cluster-master-id adf443a4d33c4db2c0d4669d61915ae6faa96b46
redis-cli --cluster add-node 172.17.0.14:6379 172.17.0.11:6379 --cluster-slave --cluster-master-id 6e5adcb56a871a3d78343a38fcdec67be7ae98f8
redis-cli --cluster add-node 172.17.0.16:6379 172.17.0.12:6379 --cluster-slave --cluster-master-id c061e37c5052c22f056fff2a014a9f63c3f47ca0Verify the cluster status with redis-cli -c on any node.
5. Expose the Cluster with a Service
apiVersion: v1
kind: Service
metadata:
name: gold-redis
labels:
app: redis
spec:
ports:
- name: redis-port
protocol: "TCP"
port: 6379
targetPort: 6379
selector:
app: redis
appCluster: redis-clusterDeploy the Service and test connectivity; the cluster should now be fully operational.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Open Source Linux
Focused on sharing Linux/Unix content, covering fundamentals, system development, network programming, automation/operations, cloud computing, and related professional knowledge.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
