Managing Stateful Applications with StatefulSets in Kubernetes

Updated: January 30, 2024 By: Guest Contributor Post a comment

Introduction

Managing stateful applications can be a complex task in containerized environments. Unlike stateless applications, stateful ones require a stable storage that persists across restarts and a unique network identity. Kubernetes offers various resources to help manage such applications, and one of the key abstractions available is the StatefulSet. In this tutorial, you’ll learn about StatefulSets in Kubernetes, how they differ from other controllers such as Deployments, and how you can utilize them for running stateful applications smoothly.

Understanding StatefulSets

StatefulSets are Kubernetes resources specifically designed for applications that require a stable identity and storage. They guarantee the following:

  • Stable, unique network identifiers.
  • Stable, persistent storage.
  • Ordered, graceful deployment and scaling.
  • Ordered, automated rolling updates.

In addition, pods in a StatefulSet have a sticky identity. Each pod is based on the same spec but is not interchangeable: each has a persistent identifier (a unique ordinal index) that maintains across any rescheduling.

Creating Your First StatefulSet

Now, let’s start with a basic example of a StatefulSet. Here is how you define one for a simple web application that requires stable storage:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx
  serviceName: "nginx"
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "my-storage-class"
      resources:
        requests:
          storage: 1Gi

To deploy this StatefulSet, save the configuration into a file such as nginx-statefulset.yaml and run this command:

kubectl create -f nginx-statefulset.yaml

After deployment, you can check the status of your StatefulSet:

kubectl describe statefulset web

Scaling and Managing StatefulSets

Scaling a StatefulSet is similar to scaling any other type of application in Kubernetes:

kubectl scale statefulset web --replicas=5

When you scale a StatefulSet, pods are created or deleted in order, ensuring no overlap and maintaining the identity of each pod.

Updating a StatefulSet requires a similar approach to Deployments. You can perform rolling updates by changing the image or configuration and applying the update:

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

Advanced Usage: Using Headless Services

StatefulSets usually work with headless services to control the domain of each pod. A headless service allows pods to be addressed individually, which is a common requirement for stateful applications. Here’s how you create a headless service for our StatefulSet:

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx

Apply the headless service using kubectl:

kubectl apply -f headless-service.yaml

This service acts as the DNS record for the StatefulSet, allowing each member to have a stable network identity.

StatefulSets and Persistent Volumes

One of the complexities of managing stateful applications is handling storage. Persistent Volumes (PVs) and Persistent Volume Claims (PVCs) are essential when it comes to StatefulSet configuration. Each pod in the StatefulSet mounts a PVC that is backed by a PV, allowing it to retain data across failures and restarts.

The following code shows the `volumeClaimTemplates` field that dynamically provisions storage for each pod in the set:

volumeClaimTemplates:
- metadata:
    name: www
  spec:
    accessModes: [ "ReadWriteOnce" ]
    storageClassName: "standard"
    resources:
      requests:
        storage: 1Gi

Whenever a pod is instantiated by the StatefulSet, it automatically creates a new PVC according to the template, which results in the dynamic provisioning of a PV that matches the requirements.

Conclusion

StatefulSets provide a powerful way to handle stateful applications in Kubernetes, offering predictable names, persistent storage, and ordered operations. By following the guidelines and examples provided in this tutorial, you will be equipped to deploy and manage your stateful applications efficiently.