In this example, we will examine how a Stateful Service can be implemented with the help of a StatefulSet resource.
This example assumes a Kubernetes installation is available. Currently, we are using Minikube as we need some support for PersistentVolumes. Check the INSTALL documentation for installing Minikube.
To access the PersistentVolume used in this demo, let’s mount a local directory into the Minikube VM that we later then use a PersistentVolume mounted into the Pod:
minikube start --mount --mount-string="$(pwd)/logs:/tmp/example"
This startup command makes this directory available within the Minikube VM at the path /tmp/example
.
Let’s create now two PersistentVolumes for the replicas of our StatefulSet later:
kubectl create -f https://k8spatterns.io/StatefulService/pvs.yml
These persistent volumes are the local directories logs/1
and logs/2
.
As described for the Stateful Service pattern, we need a headless service for the StatefulSet. Let’s create one with the following:
kubectl create -f https://k8spatterns.io/StatefulService/service.yml
Now its time to create the StatefulSet with
kubectl create -f https://k8spatterns.io/StatefulService/statefulset.yml
To access the service, we are creating a regular Service exposed via nodePort
:
kubectl create -f https://k8spatterns.io/StatefulService/service-nodeport.yml
To access the service on Minikube, we need to start a tunnel to the VM and store the URL to the service in a text file that we pick up later.
minikube service random-generator-np --url > /tmp/random-url.txt &
Now we can access our service with:
# Pick the URL from the service tunnel and curl it
url=$(cat /tmp/random-url.txt)
curl -s $url | jq .
We can also look at the logs created.
curl -s $url/logs
As you can see, the logs differ from call to call, depending on which endpoint you are hitting with this request.
You can also check for those log files in the directory ./logs/1
and .logs/2
Now that we set up, we can play a bit with this StatefulSet:
We can scale it down with
kubectl scale statefulset --replicas 1 rg
What happens to the PerstitenVolumeClaims created for this StatefulSet (kubectl get pvc
)? Has it been deleted, too? What happens when you query the service?
Now scale up to three replicas:
kubectl scale statefulset --replicas 3 rg
Recheck the PVCs. Is it the Pod with index 1 attached back to its original PersistentVolume? How is the new Pod nr. 3 attached to which PV?
Finally, let’s check how the pods can be addressed within the internal network.
For this, jump into one of the pods with
kubectl exec -it rg-0 -- bash
And then, from within the Pod, check the DNS entry for the headless Service:
dig SRV random-generator.default.svc.cluster.local
You will find all the internal IP addresses of the StatefulSet’s Pod in the answer.