• Stars
    star
    160
  • Rank 234,703 (Top 5 %)
  • Language
    Shell
  • Created over 8 years ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Redis Cluster on Kubernetes

Redis Cluster on Kubernetes

This module is intended to simplify the creation and operation of a Redis Cluster deployment in Kubernetes. I don't recommend that you run this in production - it's just meant to be an illustrative example of a nontrivial Stateful Set deployment.

Requirements

  • Kubernetes 1.17.0+
  • Minikube to run the module locally

How it works

These directions assume some familiarity with Redis Cluster.

When you create the resources in Kubernetes, it will create a 6-member (the minimum recommended size) Stateful Set cluster where members 0-2 are master nodes and all other members are replicas.

Testing it out

To launch the cluster, have Kubernetes create all the resources in redis-cluster.yml:

$ kubectl create -f redis-cluster.yml
service/redis-cluster created
configmap "redis-cluster-config" configured
poddisruptionbudget.policy/redis-cluster-pdb created
statefulset.apps/redis-cluster created

Wait a bit for the service to initialize.

Once all the pods are initialized, you can see that Pod "redis-cluster-0" became the cluster master with the other nodes as slaves.

$ kubectl exec redis-cluster-0 -- redis-cli cluster nodes
Defaulted container "redis-cluster" out of: redis-cluster, init-redis-cluster (init)
532505ce41c64ddf4aff143406eb90424c29c138 10.1.0.136:6379@16379 myself,master - 0 1642662784000 1 connected 0-5461
1f188afd5f2a228320cc43753e4b6a1c01c32445 10.1.0.139:6379@16379 slave 532505ce41c64ddf4aff143406eb90424c29c138 0 1642662785392 1 connected
07939f1e633cd3538f8730017aa5ce1d0f8ba680 10.1.0.140:6379@16379 slave de3b3a6d02c81f4104566828e8a523b46e31cd02 0 1642662785000 0 connected
de3b3a6d02c81f4104566828e8a523b46e31cd02 10.1.0.137:6379@16379 master - 0 1642662784386 0 connected 5462-10922
c53e989fa503b04ecc7c651f448a7fc07ac3c975 10.1.0.138:6379@16379 master - 0 1642662786399 2 connected 10923-16383
a43a4a9d81ae095bfdd373ed2c9aebbe958d086a 10.1.0.141:6379@16379 slave c53e989fa503b04ecc7c651f448a7fc07ac3c975 0 1642662784000 2 connected

Also, you should be able to use redis-cli to connect to a cluster node we just created

$ kubectl exec -it redis-cluster-0 -- redis-cli

You can also check the slot configuration here:

$ kubectl exec redis-cluster-0 -- redis-cli --cluster check localhost 6379
Defaulted container "redis-cluster" out of: redis-cluster, init-redis-cluster (init)
localhost:6379 (55a74f86...) -> 0 keys | 5462 slots | 1 slaves.
10.1.0.126:6379 (f5b39569...) -> 0 keys | 5461 slots | 1 slaves.
10.1.0.125:6379 (742cf86e...) -> 0 keys | 5461 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node localhost:6379)
M: 55a74f86cf241a90f66a94a6c1789e031adbcc0c localhost:6379
   slots:[0-5461] (5462 slots) master
   1 additional replica(s)
M: f5b39569a75fe72cb16e207f2947d22c625a39ab 10.1.0.126:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: ddea6fbe8baa7938504f9f1ff503f0f190b49bc3 10.1.0.127:6379
   slots: (0 slots) slave
   replicates 55a74f86cf241a90f66a94a6c1789e031adbcc0c
M: 742cf86e53a93473d17d352d2100b7db9dc61b72 10.1.0.125:6379
   slots:[5462-10922] (5461 slots) master
   1 additional replica(s)
S: 054f92cfb064e5cd762e466799311fbc21228049 10.1.0.128:6379
   slots: (0 slots) slave
   replicates 742cf86e53a93473d17d352d2100b7db9dc61b72
S: ccc463f1aa52c9afd12aa945d7869c2a44f81c9d 10.1.0.129:6379
   slots: (0 slots) slave
   replicates f5b39569a75fe72cb16e207f2947d22c625a39ab
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

To add more nodes to the cluster, you can simply use normal stateful set scaling:

kubectl scale -n default statefulset redis-cluster --replicas=12

Newly-created nodes will join the cluster as replicas.

To clean this mess off your Minikube VM:

$ kubectl delete service,statefulsets redis-cluster
$ kubectl delete configmaps redis-cluster-config
$ kubectl delete poddisruptionbudgets.policy redis-cluster-pd

# To prevent potential data loss, deleting a statefulset doesn't delete the pods. Gotta do that manually.
$ kubectl delete pod redis-cluster-0 redis-cluster-1 redis-cluster-2 redis-cluster-3 redis-cluster-4 redis-cluster-5

TODO

  • Add documentation for common Redis Cluster operations: adding nodes, resharding, deleting nodes
  • Test some failure scenarios
  • Use a persistentvolume to store backup files
  • Create a ScheduledJob to do automated backups once this feature is finished.
  • Make it easier to assign new masters
  • Cluster members should check whether nodes.conf exists and if so, skip pod initialization.