Skip to main content

K3s Kubernetes


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.


You can read much more about Redis here: 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.


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: We are going with AOF.

For persistent storage I'm going to use 5GB of Longhorn distributed storage I set up before.


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


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
  name: redis-pvc
  namespace: redis-server
    - ReadWriteOnce
  storageClassName: longhorn
      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:

Create deployment.yaml:

apiVersion: apps/v1
kind: Deployment
  name: redis-server
  namespace: redis-server
  replicas: 1
      app: redis-server
        app: redis-server
        name: redis-server
        node-type: worker
      - name: redis-server
        image: redis
        args: ["--appendonly", "yes"]
          - name: redis-server
            containerPort: 6379
          - name: lv-storage
            mountPath: /data
            - name: ALLOW_EMPTY_PASSWORD
              value: "yes"
        - name: lv-storage
            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.
kubectl apply -f deployment.yaml

It might take a minute to start, but for me, it deployed without issue.


root@control01:~/redis-deployment# kubectl get pods -n redis-server
NAME                           READY   STATUS    RESTARTS   AGE
redis-server-f7d87db47-v4xkl   1/1     Running   0          12d


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
  name: redis-server
  namespace: redis-server
    app: redis-server
  type: LoadBalancer
    - name: redis-port
      protocol: TCP
      port: 6379
      targetPort: 6379
  loadBalancerIP: is the next free IP from my MetalLB IP pool, so this is where my Redis will live.

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  6379:30771/TCP   41m

Looks fine.


I'm adding a new entry to every Kubernetes node for Redis:

echo ' redis redis.cube.local' >> /etc/hosts


apt install telnet -y
root@control01:~/redis-deployment# telnet redis.cube.local 6379
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).