DEV Community

Abhay Singh Kathayat
Abhay Singh Kathayat

Posted on

Running Stateful Applications with StatefulSets in Kubernetes

Running Stateful Applications with StatefulSets in Kubernetes

In Kubernetes, StatefulSets are a controller used to manage stateful applications. Unlike Deployments (which are typically used for stateless applications), StatefulSets provide guarantees about the ordering and uniqueness of pods, making them ideal for applications that require persistent storage and stable network identities, such as databases, caches, or distributed systems.

Key Features of StatefulSets:

  1. Stable, unique network identifiers: Each pod in a StatefulSet has a unique identity that remains stable across restarts. For example, a pod's hostname will always be pod-name-0, pod-name-1, etc.
  2. Stable storage: StatefulSets can be used in conjunction with PersistentVolumes to ensure that data is retained even when pods are rescheduled or restarted.
  3. Ordered, graceful deployment and scaling: Pods in a StatefulSet are created and deleted in a specific order, ensuring that each pod is initialized and terminated sequentially.

Steps for Running Stateful Applications with StatefulSets

1. Define the StatefulSet

To define a StatefulSet, you need to create a YAML configuration file. Below is an example of a StatefulSet definition for a Redis cluster, where each Redis instance will use a persistent volume.

# redis-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis
spec:
  serviceName: "redis"
  replicas: 3
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
        - name: redis
          image: redis:6.0
          volumeMounts:
            - name: redis-data
              mountPath: /data
  volumeClaimTemplates:
    - metadata:
        name: redis-data
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 1Gi
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • serviceName: A headless service is created to give each pod in the StatefulSet a stable DNS name.
  • replicas: Specifies the number of pod replicas (in this case, 3 Redis instances).
  • volumeClaimTemplates: This ensures that each pod in the StatefulSet gets its own PersistentVolumeClaim for data storage, providing stateful storage.

2. Apply the StatefulSet

You can apply the YAML definition to your Kubernetes cluster:

kubectl apply -f redis-statefulset.yaml
Enter fullscreen mode Exit fullscreen mode

This command will create the StatefulSet along with the corresponding PersistentVolumeClaims and pods.

3. Create a Headless Service

A headless service is required to ensure each pod in the StatefulSet gets a stable network identity. Here's how you can define it:

# redis-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: redis
spec:
  clusterIP: None
  selector:
    app: redis
  ports:
    - port: 6379
Enter fullscreen mode Exit fullscreen mode

The clusterIP: None creates a headless service, which makes Kubernetes assign DNS names to the pods based on their index (e.g., redis-0, redis-1, etc.).

4. Accessing the StatefulSet Pods

Once the StatefulSet is deployed, each pod in the StatefulSet can be accessed by its unique name. For example:

  • redis-0.redis
  • redis-1.redis
  • redis-2.redis

To get the list of pods, run:

kubectl get pods -l app=redis
Enter fullscreen mode Exit fullscreen mode

You can then interact with each pod using its DNS name.

5. Scaling the StatefulSet

StatefulSets support scaling, but the scaling happens in a controlled manner:

kubectl scale statefulset redis --replicas=5
Enter fullscreen mode Exit fullscreen mode

Kubernetes will add pods one by one, respecting the order of the existing pods. The pods will be named redis-3, redis-4, and so on.

6. Managing Persistent Storage

StatefulSets ensure that each pod gets its own persistent storage. When a pod is deleted or rescheduled, Kubernetes will reattach the PersistentVolume from the previous pod to the new pod. This allows the application to retain its data.

7. Deleting a StatefulSet

When deleting a StatefulSet, Kubernetes will follow a controlled process to delete the pods in reverse order. If you want to delete a StatefulSet, run:

kubectl delete statefulset redis
Enter fullscreen mode Exit fullscreen mode

This will delete the StatefulSet and the associated pods, but the persistent volumes will remain unless explicitly deleted.

Use Cases for StatefulSets

  • Databases: StatefulSets are perfect for running databases like PostgreSQL, MySQL, MongoDB, and more, as they require stable storage and stable network identities for replication and clustering.
  • Distributed Systems: Systems like Apache Kafka, Cassandra, and Elasticsearch benefit from StatefulSets' ability to provide stable identities and persistent storage for each node.
  • Caching Systems: Applications like Redis and Memcached often use StatefulSets to maintain consistent state across distributed caches.

Key Differences Between StatefulSets and Deployments

Feature StatefulSet Deployment
Pod Identity Stable and unique (e.g., pod-0) Dynamic and ephemeral
Persistent Storage Each pod has its own persistent volume Volumes are shared or ephemeral
Scaling Ordered scaling (one by one) Pods can be scaled independently
Pod Rescheduling Pod identity is preserved across rescheduling Pod identity is not preserved
Pod Deletion Pods are deleted in reverse order Pods are deleted randomly

Conclusion

StatefulSets provide a robust way to manage stateful applications in Kubernetes. They ensure that applications that rely on persistent data and stable network identities, like databases and distributed systems, can function efficiently in a cloud-native environment. By combining StatefulSets with PersistentVolumes, Kubernetes can manage stateful workloads with ease, making it ideal for applications that need to maintain state across pod restarts and rescheduling.

Top comments (0)