Do you have a requirement to deploy a stateful application in your Kubernetes cluster? If yes, then this is the right article for you. Kubernetes has various controllers and the one we are going to be talking about today is StatefulSet Controller which will help us achieve the aforementioned task.
What is a StatefulSet?
Statefulset is a Kubernetes object that deploys and scales a group of Kubernetes pods but so does the deployment. Generally, when we have a deployment, we don’t care how pods are scheduled and what name they get, but in some cases, it is important that pods are deployed in order and have the same name through all the restarts and reschedules. This is where statefulset comes into the picture. Statefulset allocates a sticky identity[ a number starting from 0] to every pod instead of appending a random string to the pod’s name. Every pod in statefulset is started in a sequential order, so if for some reason pod-0 didn’t start, pod-1,2,3 and so on wouldn’t start as well.
When do we use Statefulset?
There can be multiple use cases for a statefulset, the most common one of them is when we want to replicate a database. The databases can’t be generally replicated by deployments/replicasets.
Why can’t we use deployments to replicate databases?
In the above diagram, we have a traditional deployment of mysql with no. of replicas set to 1. Also, we have a web app that reads/writes to our MySQL database and the MySQL database then stores the data in its persistent volume. This works perfectly for a single pod, but what happens when we scale up our database to match the needs of an increased workload. Say, we set no. of replicas = 3 and hit kubectl apply.
Now we have 3 independent mysql pods with no sharing of databases. This wouldn’t work for several reasons. When the web app tries to read/write data from/to the mysql, it would go to a different pod every time and we would end up with inconsistent data.
How would a Statefulset solve this problem?
When we deploy mysql or any other application as a statefulset it is possible to treat the first pod(which in this case happens to be mysql-0) as the primary pod, which will support both read and write requests meanwhile the other pods which are part of statefulset would only serve read requests. This would help us setup a primary-replica or master-slave architecture for databases which means that all the pods which are part of the statefulset would be in sync and share the same data.
How to create a Statefulset?
A statefulset manifest is pretty similar to that of deployment. The only difference is kind, serviceName and volumeClaimTemplates. Under serviceName, we define the name of the headless service which is nothing but a normal service object of kubernetes, it is treated as headless once we define it in statefulset manifest file. VolumeClaimTemplates section would serve as the pvc for each pod that would be created as a part of statefulset.
Below is an example of mysql as a statefulset.
apiVersion: apps/v1 kind: StatefulSet metadata: name: mysql spec: selector: matchLabels: app: mysql serviceName: "mysql" replicas: 3 template: metadata: labels: app: mysql spec: terminationGracePeriodSeconds: 10 containers: - name: mysql image: mysql ports: - containerPort: 3306 volumeMounts: - name: mysql-data mountPath: /var/lib/mysql env: - name: MYSQL_ROOT_PASSWORD value: password volumeClaimTemplates: - metadata: name: mysql-data spec: accessModes: ["ReadWriteOnce"] storageClassName: "gp2" resources: requests: storage: 10Gi --- apiVersion: v1 kind: Service metadata: name: mysql labels: app: mysql spec: ports: - port: 3306 clusterIP: None selector: app: mysql
This manifest would create a statefulset with 3 mysql pods, a headless service, 3 persistentVolumeClaim and persistentVolume[one for each pod] .
kubectl apply -f mysql.yml
Note – Even though Statefulset help us deploy stateful applications, it does not take care of the replication by itself. That part has to be handled seperately.
In this blog, we learned the basics of statefulset and how if we want to deploy a stateful application we could benefit from it. Statefulset in Kubernetes provides an ordinal number for each pod[beginning from 0]. This helps to easily set up primary-replica and master-slave architecture for stateful applications. It can be used to deploy stateful applications like mysql, mongodb, elasticsearch, wordpress, etc.
Happy Learning !!
Opstree is an End to End DevOps solution provider