English

Share with friends

Note

Kubernetes StatefulSets can revolutionize the way you manage stateful applications in a distributed environment. If you're already familiar with Kubernetes, you know how challenging it can be to handle stateful workloads. In this blog post, we will demystify StatefulSets in Kubernetes, explore practical examples, and discuss best practices.

Kubernetes StatefulSet - What is it, Examples & Best Practices cover image

StatefulSets are a vital component in the Kubernetes ecosystem, specifically designed to manage stateful applications.

Unlike Deployments, which are best suited for stateless workloads, StatefulSets offer unique capabilities that ensure stability, scalability, and consistency for stateful applications.

With StatefulSets, you can easily define and manage multiple instances, known as Pods, each with its own identity, stable network name, and persistent storage.

Throughout this blog post, we will the look into the intricacies of StatefulSets in Kubernetes by examining real-world use cases.

But this isn't just about theory. We'll be rolling up our sleeves and diving into practical examples to illustrate the power of StatefulSets.

So, grab a cup of coffee and get ready to unlock the potential of Kubernetes StatefulSets. Let's get started!

What is StatefulSet in Kubernetes?

In Kubernetes, a StatefulSet is a resource that allows you to manage stateful applications. It provides a way to deploy and scale stateful applications while ensuring stable network identities and persistent storage for each instance.

Imagine you have a distributed application where each instance needs to maintain its own unique identity and state. For example, a database or a messaging system.

In a traditional deployment, it can be challenging to manage and scale these instances while maintaining their individual identities and data.

That's where StatefulSets come in. They provide a higher level of abstraction for managing these stateful applications in Kubernetes.

Let's break down the key concepts.

Stable Network Identities

StatefulSets assign a unique and stable hostname to each instance. This means that even if instances are scaled up or down, their network identities will remain consistent.

Also Read: How to Create, Manage, and Use Kubernetes Secrets?

Ordered Deployment and Scaling

StatefulSets ensure that instances are deployed and scaled in a controlled and predictable order.

Each instance is created one by one, and Kubernetes waits for each one to be up and running before proceeding to the next.

Persistent Storage

StatefulSets provide the ability to use persistent volumes for each instance.

These volumes are associated with a specific instance and maintain data even if the instance is restarted or rescheduled to a different node.

This ensures that stateful applications can reliably store and retrieve data.

Headless Services

StatefulSets automatically create a corresponding headless service. This service enables the discovery of individual instances using their stable network identities.

It allows other applications or services to interact with specific instances directly.

Note

StatefulSets are only accessible in Kubernetes 1.5 and higher. Run kubectl version to determine your Kubernetes version.

Also Read: The Only Kubectl Cheat Sheet You'll Ever Need

How to Create StatefulSet in Kubernetes?

To create a StatefulSet in Kubernetes, you need to define a YAML configuration file that describes the desired state of the StatefulSet.

Here are the step-by-step instructions with examples:

Step 1: Create a YAML file (e.g., statefulset.yaml) and open it in a text editor.

Step 2: Define the API version, kind, and metadata for the StatefulSet. For example:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: my-statefulset

Step 3: Specify the spec section, which includes the desired properties of the StatefulSet. This includes the number of replicas, pod template, and persistent volume claim.

Here is example.

spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  serviceName: my-statefulset
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: my-image
        ports:
        - containerPort: 8080
        volumeMounts:
        - name: data
          mountPath: /data
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi

In the above example, we create a StatefulSet with three replicas. The pod template specifies a container named "my-container" with an image named "my-image" listening on port 8080.

It also defines a volume mount and a persistent volume claim named "data" with a storage size of 1Gi.

Step 4: Save the YAML file.

Step 5: Apply the YAML file using the kubectl apply command:

kubectl apply -f statefulset.yaml

You can check the status of the StatefulSet and its pods using commands such as kubectl get statefulset and kubectl get pods.

Also Read: Kubectl Config Set Context Tutorial

How to Edit StatefulSet in Kubernetes?

To edit a StatefulSet in Kubernetes, you can use the kubectl edit command or update .spec.replicas of the StatefulSet manifests, and then do a kubectl apply:

Option 1: Using kubectl edit command

Step 1: Open a terminal or command prompt.

Step 2: Run the following command, replacing <statefulset-name> with the name of your StatefulSet:

kubectl edit statefulset <statefulset-name>

This command will open the StatefulSet YAML configuration in the default editor configured in your environment (e.g., Vim, Nano).

Step 3: Modify the YAML file as needed. You can make changes to various properties such as the number of replicas, container image, ports, or volume claims.

Step 4: Save the changes and exit the editor.

Kubernetes will automatically update the StatefulSet with the modified configuration. The changes may trigger pod restarts or other actions based on the modifications made.

Option 2: Modifying the YAML file directly

Step 1: Locate the YAML file that was used to create the StatefulSet.

Step 2: Open the file in a text editor.

Step 3: Make the necessary changes to the YAML file.

Step 4: Save the file.

Step 5: Apply the changes using the kubectl apply command:

kubectl apply -f statefulset.yaml

Kubernetes will compare the modified YAML file with the existing StatefulSet configuration and apply the changes accordingly.

Option 3: Using Patch:

kubectl patch statefulsets <stateful-set-name> -p '{"spec":{"replicas":<new-replicas>} }'

Verify the changes made by checking the Kubernetes StatefulSet's status using commands such as kubectl describe statefulset <statefulset-name> or kubectl get statefulset <statefulset-name>.

Also Read: How to Set up Multiple Apps on One Load Balancer in Kubernetes?

How to Get StatefulSet in Kubernetes?

To get information about a StatefulSet in Kubernetes, you can use the kubectl get command.

Here's how you can retrieve the details of a StatefulSet.

Step 1: Open a terminal or command prompt.

Step 2: Run the following command, replacing <statefulset-name> with the name of your StatefulSet:

kubectl get statefulset <statefulset-name>

You can retrieve the pods associated with the StatefulSet using the kubectl get pods command with a selector that matches the labels of the StatefulSet. For example:

kubectl get pods -l app=<statefulset-name>

This command will list all the pods that are part of the specified StatefulSet.

Also Read: What is Helm in Kubernetes?

How to Restart StatefulSet in Kubernetes?

To restart StatefulSets in Kubernetes, here are the various ways:

Restart Deployment

To gracefully restart all pods in a deployment, you can use the rollout restart command. This will trigger a rolling update, replacing the pods one by one.

kubectl rollout restart deployment <deployment-name>

Restart StatefulSet

Similar to restarting a deployment, you can restart all pods in a StatefulSet using the rollout restart command.

kubectl rollout restart statefulset <statefulset-name>

Delete and Let Deployment Reschedule

If a pod is part of a deployment and you want to force restart it, you can delete the pod. The deployment will automatically create a new pod to replace the deleted one.

kubectl delete pod <pod-name>

Now, let's look at a complete StatefulSet example.

Kubernetes StatefulSet Example

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: my-statefulset
spec:
  serviceName: my-statefulset
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: nginx:latest
        ports:
        - containerPort: 80
        volumeMounts:
        - name: data
          mountPath: /data
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

In this example:

  • The StatefulSet is named "my-statefulset".

  • The StatefulSet will create three replicas.

  • The pods belonging to the StatefulSet are selected using the label "app: my-app".

  • The pod template specifies a container named "my-container" with the NGINX image and port 80 exposed.

  • A volume mount named "data" is configured, with the mount path set to "/data" inside the container.

  • The StatefulSet also defines a volume claim template named "data" with a request for 1Gi of storage. It uses the ReadWriteOnce access mode, which means the volume can be mounted by a single pod at a time.

This example demonstrates a simple StatefulSet that deploys three NGINX pods. Each pod will have its own persistent volume claim named "data", allowing them to store data persistently.

Also Read: Kubernetes Best Practices for Security, Namespaces, Resource Limits, and More

Kubernetes StatefulSet Best Practices

Below are some best practices to consider when working with StatefulSets in Kubernetes:

1.Use a Stable Network Identity

Set the serviceName field in the StatefulSet spec to ensure stable DNS names for each pod. This allows other services to reliably connect to specific instances of the StatefulSet.

Here's how to do this.

spec:
  serviceName: my-statefulset

2.Define Persistent Storage

Use Persistent Volume Claims (PVCs) to provide persistent storage for each instance. Define a volumeClaimTemplates section in the StatefulSet spec to specify the storage requirements.

Here is another example of Kubernetes StatefulSet best practice.

spec:
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi

3.Manage Initialization and Ordering

Use init containers or lifecycle hooks to manage initialization and ensure a specific order of operations. Init containers can perform tasks like setting up configurations or performing pre-start checks.

Here's how to do it.

spec:
  template:
    spec:
      initContainers:
      - name: init-container
      image: busybox
    command: ['sh', '-c', 'echo Initializing...']

4.Configure Pod Disruption Budgets (PDB)

Define a Pod Disruption Budget to control the number of pods that can be simultaneously disrupted during maintenance or updates. This ensures high availability and prevents excessive downtime.

Here's an example of how to configure PDB.

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: my-pdb
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: my-app

5.Implement Rolling Updates

Use rolling updates to ensure a smooth transition during updates or scaling operations.

This involves modifying the StatefulSet and allowing Kubernetes to gradually update or scale pods while maintaining the required replicas.

Here's how to do it for Kubernetes StatefulSet.

kubectl patch statefulset my-statefulset -p '{"spec":{"updateStrategy":{"type":"RollingUpdate"} }}'

6.Handle Stateful Application Scaling

When scaling StatefulSets, carefully consider the statefulness of the application. Scaling up should preserve data consistency while scaling down may require proper data migration or backup strategies.

Here's how to do it.

kubectl scale statefulset my-statefulset --replicas=5

7.Backup and Restore Data

Implement backup and restore mechanisms for the data stored in persistent volumes. This ensures data availability and resilience in case of failures or disaster recovery scenarios.

Use tools like velero or create custom backup scripts to back up and restore persistent volume data.

Since we are talking about persistent volume data, let us discuss more Persistent Volumne and how it works with StatefulSet

Also Read: EBS vs EFS vs S3 - Which One to Choose?

Kubernetes StatefulSet and Persistent Volume

Kubernetes StatefulSet and Persistent Volume complement each other in managing stateful applications by providing stable network identities and durable storage. Here's a brief explanation of how they work together:

StatefulSet

StatefulSets in Kubernetes ensure ordered deployment, scaling, and management of stateful applications.

They assign stable network identities, such as DNS names, to each pod, allowing other services to reliably connect to specific instances.

StatefulSets also manage the lifecycle of pods, ensuring orderly scaling and rescheduling.

Persistent Volume (PV) and Persistent Volume Claim (PVC)

Persistent Volumes provide durable storage that is independent of the pod lifecycle. Persistent Volume Claims act as requests for specific PV resources.

They allow pods, including those managed by StatefulSets, to request and use persistent storage without being aware of the underlying storage details.

By using Persistent Volumes and Persistent Volume Claims within a StatefulSet, you can achieve reliable data storage and maintain data persistence across pod restarts and rescheduling.

Example of Persistent Volume and StatefulSet in Kubernetes

Consider a StatefulSet running a database application. Each pod in the StatefulSet requires persistent storage to maintain its data.

You can define a Persistent Volume and Persistent Volume Claim to provide storage for the database.

The StatefulSet ensures that each pod is assigned a unique hostname and the corresponding Persistent Volume is mounted to the pod consistently.

This combination allows the database pods to maintain their network identity, such as DNS name, and their data persists across pod restarts or rescheduling.

Here is an example of YAML Configuration:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: my-statefulset
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: my-image
        volumeMounts:
        - name: data
          mountPath: /data
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi

In the above example, the StatefulSet defines a Persistent Volume Claim template named "data" and mounts it to the pods' containers.

This ensures that each pod in the StatefulSet has its own persistent storage volume, allowing the stateful application to store and retrieve data reliably.

Kubernetes Deployment vs StatefulSet

Kubernetes provides two key resources for managing application deployments: Deployments and StatefulSets.

Kubernetes Deployment

  • Deployments are primarily used for stateless applications, where individual pod instances are interchangeable.

  • Deployments ensure the desired number of pod replicas are running at all times and handle scaling, rolling updates, and rollbacks.

  • Deployments do not provide stable network identities or ordered pod creation and termination.

Here's an example YAML configuration of Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-container
          image: my-image

In the above example, a Deployment named "my-deployment" is created with three replicas.

The Deployment ensures that three instances of the pod are always running.

Scaling, rolling updates, and rollbacks can be performed on the Deployment, allowing for easy management of stateless applications.

Also Read: Everything You Need to Know About Kubernetes Namespaces

Kubernetes StatefulSet

  • StatefulSets are designed for stateful applications that require stable network identities and persistent storage.

  • StatefulSets provide ordered and unique network identities (e.g., DNS names) for each pod instance, allowing for reliable communication.

  • StatefulSets manage the lifecycle of individual pods, ensuring ordered creation, scaling, and termination.

  • Each pod in a StatefulSet can be associated with its own Persistent Volume Claim (PVC) for durable storage.

Let's have a look at StatefulSet YAML configuration:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: my-statefulset
spec:
  replicas: 3
  serviceName: my-service
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-container
          image: my-image
          volumeMounts:
            - name: data
              mountPath: /data
  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 1Gi

In the above example, a StatefulSet named "my-statefulset" is created with three replicas. The StatefulSet ensures ordered creation, scaling, and termination of pods.

Each pod has a unique network identity, and a Persistent Volume Claim template named "data" is defined, providing persistent storage to each pod.

Kubernetes StatefulSet vs Stateless

Kubernetes StatefulSet and stateless resources (such as Deployments) serve different purposes and are used for different types of applications.

Here's a comparison between StatefulSet and stateless resources in Kubernetes:

StatefulSet

  • StatefulSet is used to deploy stateful applications requiring unique network identities and persistent storage.

  • StatefulSet provides stable network identities (such as DNS names) to each pod, allowing for reliable communication.

  • StatefulSet manages the lifecycle of individual pods, ensuring ordered creation, scaling, and termination.

  • Each pod in a StatefulSet can have its own persistent storage volume, preserving data across pod restarts and rescheduling.

Here are a few use cases for StatefulSet:

  • Databases (e.g., MySQL, PostgreSQL)

  • Distributed storage systems (e.g., Cassandra, Elasticsearch)

  • Messaging queues (e.g., Kafka)

Stateless Resources (Deployments, For Example)

  • Stateless resources are used for deploying stateless applications, where each instance of the application is interchangeable.

  • Deployments manage the desired number of replicas of the application and handle scaling, rolling updates, and rollbacks.

  • Pods created by Deployments do not have stable network identities, and their lifecycle is managed independently.

Here are a few use cases for Deployments:

  • Web servers (e.g., Nginx, Apache)

  • Microservices

  • Stateless APIs

Also Read: Monitoring & Testing Tools for Microservices

StatefulSet in Kubernetes: Some Important Terms

1. VolumeClaimTemplates: When using StatefulSets, you often need to provide persistent storage to each pod.

VolumeClaimTemplates allow you to define the desired properties of a Persistent Volume Claim (PVC) dynamically.

Each pod in the StatefulSet receives its own PVC based on the template, ensuring that it has its own dedicated storage volume.

This allows stateful applications to maintain their data across pod restarts or rescheduling.

2.Pod Management Policies: Pod management policies in StatefulSets define how pods are created, updated, and terminated.

The two common policies are "OrderedReady" and "Parallel".

  • The "OrderedReady" policy (default) ensures that pods are created and updated in sequential order. The StatefulSet controller ensures that a new pod is not started until the previous pod is running and ready.

  • The "Parallel" policy allows for pods to be created and updated simultaneously, without enforcing a specific order.

Final Thoughts on Kubernetes StatefulSet

Kubernetes StatefulSet is a powerful resource for deploying and managing stateful applications in a Kubernetes cluster.

In this article, we have explored the key features and benefits of StatefulSets, along with best practices for using them effectively.

Throughout the article, we have discussed important considerations when working with StatefulSets, such as the proper configuration of headless services, volumeClaimTemplates, and pod management policies.

By following the best practices outlined in this article, you can harness the full potential of StatefulSets to deploy and manage your stateful applications in a reliable and scalable manner.

Happy stateful deployments, and may the "pods" be ever in your favor!

Share with friends

Priyansh Khodiyar's profile

Written by Priyansh Khodiyar

Priyansh is the founder of UnYAML and a software engineer with a passion for writing. He has good experience with writing and working around DevOps tools and technologies, APMs, Kubernetes APIs, etc and loves to share his knowledge with others.

Further Reading

Life is better with cookies 🍪

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt out if you wish. Cookie Policy