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.
Some examples of reasons you’d use a StatefulSet include:
StatefulSets are available in Kubernetes 1.9 and later.
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
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:
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.
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.
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.