Blog | Blue Matador

What is a Kubernetes StatefulSet?

Written by Mark Siebert | Jul 16, 2020 5:00:05 PM
Kubernetes has a lot of features and deployment options for running containers. One of these is the StatefulSet. In this blog post, we’ll discuss what a StatefulSet is, what it can be used for, and how to create and update them.

 

What is a StatefulSet in Kubernetes?

A StatefulSet is a controller that helps you deploy and scale groups of Kubernetes pods.

When using Kubernetes, most of the time you don’t care how your pods are scheduled, but sometimes you care that pods are deployed in order, that they have a persistent storage volume, or that they have a unique, stable network identifier across restarts and reschedules. In those cases, StatefulSets can help you accomplish your objective.

Each pod created by the StatefulSet has an ordinal value (0 through # replicas - 1) and a stable network ID (which is statefulsetname-ordinal) assigned to it. You can also create a VolumeClaimTemplate in the manifest file that will create a persistent volume for each pod. When pods are deployed by a StatefulSet, they will go in order from 0 to the final pod and require that each pod is Running and Ready before creating the next pod.

When to use StatefulSet

Some examples of reasons you’d use a StatefulSet include:

  • A Redis pod that has access to a volume, but you want it to maintain access to the same volume even if it is redeployed or restarted
  • A Cassandra cluster and have each node maintain access to its data
  • A webapp that needs to communicate with its replicas using known predefined network identifiers

StatefulSets are available in Kubernetes 1.9 and later.

 

How to create a StatefulSet

Like everything else in Kubernetes, StatefulSets can be configured using a manifest file. StatefulSets require a headless service, which can be created in the same manifest file.

apiVersion: v1
kind: Service
metadata:
  name: redis
  namespace: default
  labels:
    app: redis
spec:
  ports:
  - port: 6379
    protocol: TCP
  selector:
    app: redis
  type: ClusterIP
  clusterIP: None
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis
spec:
  selector:
    matchLabels:
      app: redis
  serviceName: "redis"
  replicas: 1
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: redis:5.0.4
        command: ["redis-server", "--appendonly", "yes"]
        ports:
        - containerPort: 6379
          name: web
        volumeMounts:
        - name: redis-aof
          mountPath: /data
  volumeClaimTemplates:
  - metadata:
      name: redis-aof
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "gp2"
      resources:
        requests:
          storage: 1Gi

This example first creates a headless service that can be used by the StatefulSet, and then creates a StatefulSet that maintains one Redis pod connected to a volume. To actually create these resources, you’ll run the following command:

kubectl apply -f statefulset.yaml

 

How to update a Kubernetes StatefulSet

Updating a StatefulSet is easy. Just make changes to your manifest file, and then run the same command you used to create the StatefulSet:

kubectl apply -f statefulset.yam

What happens when you run this command depends on the update strategy you’ve selected for your StatefulSet. There are two update strategies:

 

OnDelete

If you’ve chosen  OnDelete  as the value of  .spec.updateStrategy.type  pods will not be replaced when you apply the manifest. Instead, you will have to manually delete existing StatefulSet pods before the new version will be created.

 

RollingUpdate

If you’ve chosen  RollingUpdate , when you apply the manifest, StatefulSet pods will be removed and then be replaced in reverse ordinal order. With this update strategy, you can also specify  .spec.updateStrategy.rollingUpdate.partition  to an ordinal value, and all pods with a higher ordinal value will be replaced with the new version, while old ones will be retained. This allows you to perform phased rollouts. Check out our blog on how to configure rolling updates on Kubernetes.

 

Next steps

StatefulSets provide a lot of value if you need a persistent volume or network ID for a pod. They are easy to create and update, and are a great feature in Kubernetes.

However, like the rest of Kubernetes, they can be hard to monitor with traditional tools. If you are looking for a monitoring solution for Kubernetes, consider Blue Matador. Blue Matador automatically checks for over 25 Kubernetes events out-of-the-box. We also monitor over 20 AWS services in conjunction with Kubernetes, providing full coverage for your entire production environment with no alert configuration or tuning required.