Redis
I know I'm going to need Redis in the future for some buffering between database and functions. There are lots of uses for Redis, in-memory data structure storage (also known as database in Ram). I had particular use for Redis when I had a lot of worker scripts
that would normally write to an SQL database (MariaDB), and to the same table and line, which on occasion resulted in lock. So, all the workers started to write to the Redis server, and as Honey badger, Redis don't give a fuck about huge loads and just takes it... I then wrote a simple single db worker
that on its own time and speed offloaded data to the database.
Redis
You can read much more about Redis here: https://redis.io it’s not that difficult.
There are multiple ways to deploy Redis, with multiple master - slave nodes, and so on... but for my purpose, I need only one. If a node fails where it runs, Kubernetes will start it on another, so High Availability is acceptable with small outages, till it starts elsewhere.
Persistence
I usually don't store long term data in Redis and try to consume them as fast as I can, however this whole thing is in RAM. If the pod dies, the data dies with it. Redis supports two types of persistence: regular backups every X seconds or minutes (snapshots), or a kind of log that keeps every transaction as it happens, and this is replayed back when Redis starts up. I'm going for the second one here, since it offers a backup near 1:1 always. Honestly, read about both methods here: https://redis.io/topics/persistence. We are going with AOF
.
For persistent storage I'm going to use 5GB of Longhorn distributed storage I set up before.
Guide
So, create one directory where we keep configs. This guide assumes you have the same setup as my K3s server, or close enough.
mkdir redis-deployment
cd redis-deployment
Namespace
I'm going to put everything related to Redis to its own namespace:
kubectl create namespace redis-server
Persistent storage PVC
Next create a pvc.yaml
file, and create a claim for 5GB:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: redis-pvc
namespace: redis-server
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 5Gi
kubectl apply -f pvc.yaml
Redis deployment
We have disk space. Next, the main deployment. I will use basically the official Redis docker container, since it’s produced for arm64, and we do not need to do any special stuff.
Official Docker repository is here: https://hub.docker.com/_/redis/
Create deployment.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-server
namespace: redis-server
spec:
replicas: 1
selector:
matchLabels:
app: redis-server
template:
metadata:
labels:
app: redis-server
name: redis-server
spec:
nodeSelector:
node-type: worker
containers:
- name: redis-server
image: redis
args: ["--appendonly", "yes"]
ports:
- name: redis-server
containerPort: 6379
volumeMounts:
- name: lv-storage
mountPath: /data
env:
- name: ALLOW_EMPTY_PASSWORD
value: "yes"
volumes:
- name: lv-storage
persistentVolumeClaim:
claimName: redis-pvc
Nothing special in this deployment; I have explained these values before. The only new argument is:
- args - Which is a way to pass arguments to Docker image. If you look at the official repository, these arguments are the ones that turn on persistence.
#Apply
kubectl apply -f deployment.yaml
It might take a minute to start, but for me, it deployed without issue.
Check:
root@control01:~/redis-deployment# kubectl get pods -n redis-server
NAME READY STATUS RESTARTS AGE
redis-server-f7d87db47-v4xkl 1/1 Running 0 12d
Service
I like for Redis to have its own IP, so that not only pods in the same namespace can reach it, but everybody around!
You should know by now, that for this I'm using MetalLB
on my Kubernetes cluster.
Create service.yaml
apiVersion: v1
kind: Service
metadata:
name: redis-server
namespace: redis-server
spec:
selector:
app: redis-server
type: LoadBalancer
ports:
- name: redis-port
protocol: TCP
port: 6379
targetPort: 6379
loadBalancerIP: 192.168.0.204
192.168.0.204
is the next free IP from my MetalLB IP pool, so this is where my Redis will live.
#Apply
kubectl apply -f service.yaml
Check if everything is ok:
root@control01:/home/ubuntu/redis-kubernetes# kubectl get svc -n redis-server
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
redis-server LoadBalancer 10.43.203.164 192.168.0.204 6379:30771/TCP 41m
Looks fine.
/etc/hosts
I'm adding a new entry to every Kubernetes node for Redis:
echo '192.168.0.204 redis redis.cube.local' >> /etc/hosts
Check
apt install telnet -y
root@control01:~/redis-deployment# telnet redis.cube.local 6379
Trying 192.168.0.204...
Connected to redis.
Escape character is '^]'
Done and done. Redis is up and running on Raspberry Pi 4 Kubernetes cluster, DietPi arm64. If your mouth is dry like mine now, you will get something to drink and maybe help me to get some liquids too 🙂 (smooth, I know /s).