Explore More on StatefulSets in K8s

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.

Conclusion

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 !!


Blog Pundit: Sanjeev Pandey, Deepak Gupta and Sandeep Rawat

Opstree is an End to End DevOps solution provider

Connect Us

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: