Open In App

Kubernetes StatefulSets: Running Stateful Applications in Containers

Last Updated : 25 Oct, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

StatefulSets are Kubernetes components that are used specifically for deploying stateful applications. In Kubernetes on the basis on methods of deploying. There are two types of applications – Stateful applications and stateless applications. Therefore, There are two ways for deploying an application on Kubernetes – through Deployment (for deploying stateless applications) and through StatefulSets (for deploying stateful applications).

Applications that maintain any form of persistent state or data are called stateful applications. Most of the database applications that we build like MySQL and MongoDB are stateful applications. The basic point of difference between a stateful and a stateless application is the need of persistent storage. Stateful applications requires a persistent storage while stateless applications do not have a need to store data, therefore they don’t require any persistent storage.

Stateful Applications And Stateless Applications

So what do we mean by stateful or stateless applications, basically all applications have some degree of state that is – in some applications the state of the application does not really impact the user (we will discuss this in stateless application section). These applications are called stateless applications. While other applications (like databases, message queues, caches, etc.) have a much higher degree of state because they rely on storage. This state does impact the user, that is we can not handle requests in a database independently. This type of applications are called Stateful applications. To explain these points further:

Stateful Applications

Those applications that maintain some form of persistent state or data are called stateful applications. The key characteristic that differentiate them from stateless applications is that these applications don’t rely on storing data locally and they don’t treat each request as independent. They manage data between interactions. Sometimes stateless applications connect to the stateful application to forward the requests to a database.

Stateless Applications

Those applications that do not maintain any form of persistent state or data locally are called stateless applications. In stateless applications, each request or interaction is treated independently. These applications are designed to be highly scalable, easy to manage and fault-tolerant because unlike Stateful applications, they don’t have to track past interactions or requests.

Stateless applications are deployed using deployment component. Deployment is an abstraction of pods and allows you to replicate the application meaning it allows you to run to 1, 5, 10 or n identical pods of the same stateless application.

StatefulSets

As we discussed earlier, StatefulSets are Kubernetes component that is used specifically for stateful applications. according to the official Kubernetes documentation – StatefulSets are API objects in Kubernetes that are used to manage stateful applications. StatefulSets represents the set of pods with unique, persistent identities, and elastic hostnames. It makes us assured about the ordering of scaling and deployments in case of stateful applications since during scaling pods in stateful applications, pods get created as well as deleted in a specific order (gets created one by one and last one is deleted first).

Note:- The structure of a StatefulSet YAML file is identical to a deployment, the only difference is that it has a service name to define a service.

Example of a StatefulSets

apiVersion: apps/v1
kind: StatefulSet
metadata:
name: gfg-statefulset
annotations:
description: "This is a sample GFG statefulset"
spec:
selector:
matchLabels:
app: nginx
serviceName: "nginx"
replicas: 4
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumes:
- name: www
persistentVolumeClaim:
claimName: myclaim





Deploying A Stateful Application Using Kubernetes StatefulSets

In this section, we will learn how to deploy a stateful Redis cluster using Kubernetes. Following the tutorial step by step in order to deploy the stateful set:

Step 1. Creating a kubernetes namespace where we will keep all our resources to deploy. For creating a namespace, enter the following command in your terminal:

kubectl create ns gfg-namespace

This will create you a namespace called “gfg-namespace” You will get a similar output:

Kubectl create namespace

Step 2. Create a statefulset.yaml file and enter the following code inside the file. You can create the file by using the command:

touch statefulset.yaml

Now enter the following code inside the statefulset.yaml:

---
apiVersion: v1
kind: ConfigMap
metadata:
name: redis-cluster
data:
update-node.sh: |
#!/bin/sh
REDIS_NODES="/data/nodes.conf"
sed -i -e "/myself/ s/[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/${POD_IP}/" ${REDIS_NODES}
exec "$@"
redis.conf: |+
cluster-enabled yes
cluster-require-full-coverage no
cluster-node-timeout 15000
cluster-config-file /data/nodes.conf
cluster-migration-barrier 1
appendonly yes
protected-mode no
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis-cluster
spec:
serviceName: redis-cluster
replicas: 6
selector:
matchLabels:
app: redis-cluster
template:
metadata:
labels:
app: redis-cluster
spec:
containers:
- name: redis
image: redis:5.0.1-alpine
ports:
- containerPort: 6379
name: client
- containerPort: 16379
name: gossip
command: ["/conf/update-node.sh", "redis-server", "/conf/redis.conf"]
env:
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
volumeMounts:
- name: conf
mountPath: /conf
readOnly: false
- name: data
mountPath: /data
readOnly: false
volumes:
- name: conf
configMap:
name: redis-cluster
defaultMode: 0755
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "hostpath"
resources:
requests:
storage: 50Mi
---
apiVersion: v1
kind: Service
metadata:
name: redis-cluster
spec:
clusterIP: None
ports:
- port: 6379
targetPort: 6379
name: client
- port: 16379
targetPort: 16379
name: gossip
selector:
app: redis-cluster

Step 3. Now similar to previous step, create a service file named app.yaml and enter the following code into it:

touch app.yaml
apiVersion: v1
kind: Service
metadata:
name: hit-counter-lb
spec:
type: LoadBalancer
ports:
- port: 80
protocol: TCP
targetPort: 5000
selector:
app: myapp
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hit-counter-app
spec:
replicas: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: aimvector/api-redis-ha:1.0
ports:
- containerPort: 5000





Step 4. Enter the following command to apply the app.yaml file in our namespace:

 kubectl -n gfg-namespace apply -f app.yaml

Step 5. Now we can apply the statefulset.yaml in our namespace. Enter the following command to apply the statefulset:

kubectl -n gfg-namespace apply -f statefulset.yaml

It will create configmap, service and statefulset for the redis-cluster. it will give you a similar output:

Create Configmaps,statefull applications

Step 6. We have successfully created our pods. in our Redis cluster we have 6 pods running. In order to check if the pods are running or not, we can get the list of all pods inside our namespace by the following command

 kubectl -n gfg-namespace get pods

This will show you 6 pods running, all the pods are indexed properly like we discussed earlier. If all the pods are not yet running, you shall wait and enter the command again since it takes some time for pods to get running. You will get a similar output:

Pods

Step 7. Now we should check if there are equal number of Persistant Volumes are running, for that enter the following code in the terminal:

kubectl -n gfg-namespace get pv

You will get 6 PVs running, each one for a pod. You will get a similar output:
Get Persistent volume

This is what Kubernetes does, it creates a pod, then it creates the volume and assigns the volume to the pod and move to the next Kubernetes pod, it repeats the same thing for all the pods.

Step 8. Now let’s scale up our pods form 6 to 10, for that we can enter the following command:

 kubectl -n gfg-namespace scale statefulset redis-cluster --replicas=10

Step 9. Let’s again check our pods by the command

 kubectl -n gfg-namespace get pods

And this time we have 10 pods running indexed from 0 to 9. You will also get a similar output:

Created Pods

Step 10. Similarly we can scale down our pods to 3 by enter the following command:

kubectl -n gfg-namespace scale statefulset redis-cluster --replicas=3

and now you will get this output:

namespace get pods

We now have only 3 pods. This is how we use StatefulSets in order to deploy Stateful applications. Let’s now discuss some differences between deployment and StatefulSet

Differences Between Deployment and StatefulSet

StatefulSet

Deployment

StatefulSets are Kubernetes component that is used specifically for stateful applications.

Deployment is used to deploy stateless applications.

In StatefulSets, the pods get created as well as deleted in a specific order

In Deployment, all pods are created parallelly.

When we scale down StatefulSets, the last pod gets deleted

When we scale down a deployment a random pod is picked up and deleted

A sticky and predictable name is assigned to the pods

A random name is assigned to the pods.

Each pod uses its own persistent volume (like we saw in the tutorial.)

All the pods use the same persistent volume

Conclusion

In this article we discussed about Kubernetes StatefulSets. These are Kubernetes used to deploy stateful applications. We also discussed what are these stateful and stateless applications? Stateful applications are applications that maintain some form of persistent state or data. While stateless applications are those applications that do not maintain any form of persistent state or data locally. To learn more about how to deploy StatefulSet we have an article on “How to Use Kubernetes StatefulSets“. We hope that this article helped you gain a basic insight on what Kubernetes StatefulSets are and why are they used in deploying Stateful applications.

We would like to end this article with some frequently asked questions about Kubernetes StatefulSets.

FAQs On Kubernetes StatefulSets

1. When are StatefulSets used?

StatefulSets are used to deploy Stateful applications. Therefore, whenever their is a need of any stateful application, we use StatefulSets.

2. Can StatefulSets be used in hybrid cloud environments?

Yes StatefulSets can be used in hybrid cloud environments.

3. How can you scale a StatefulSet?

StatefulSets can be scaled by the following command:

kubectl -n [NAMESPACE] scale statefulset [NAME] –replicas=[NUMBER OF REPLICAS]

4. Do all database applications use StatefulSets?

No, all database applications don’t use StatefulSets necessarily. Using StatefulSets for database applications depends on specific requirements of the project and the nature of Database.

5. Can we scale pods in StatefulSets horizontally?

Yes, you can scale StatefulSets pods horizontally. Number of replicas can be scaled up and down by the command we discussed in question 3 while maintaining the ordered nature of pods.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads