Kubernetes Basics - StatefulSets

Working with StatefulSets for stateful applications

StatefulSet Example

Download the YAML configuration file for the StatefulSet example

Download statefulset.yaml

Create the StatefulSet

kubectl apply -f statefulset.yaml

Applies the configuration from the YAML file to create the StatefulSet with 3 replicas.

Get the Pods List

kubectl get pods -o wide

Shows all pods with additional details like IP addresses and node assignments.

Get PersistentVolume Claims

kubectl get pvc

Lists all PersistentVolume Claims created by the StatefulSet.

Create a File in nginx-sts-2

kubectl exec nginx-sts-2 -it -- /bin/sh
cd /var/www
echo Hello > hello.txt

Opens a shell in the nginx-sts-2 pod and creates a file in the mounted volume.

Modify the Default Web Page

cd /usr/share/nginx/html
cat > index.html
Hello
Ctrl-D
exit

Changes the default Nginx web page content.

Reach nginx-sts-2 from nginx-sts-0

kubectl exec nginx-sts-0 -it -- /bin/sh
curl http://nginx-sts-2.nginx-headless
exit

Tests connectivity between pods using the headless service DNS.

Delete Pod 2

kubectl delete pod nginx-sts-2

Deletes the pod and watches as it is recreated with the same name.

Check if the File Still Exists

kubectl exec nginx-sts-2 -it -- /bin/sh
ls /var/www
exit

Verifies that the file persists after pod recreation due to PersistentVolume.

Cleanup - Delete StatefulSet

kubectl delete -f statefulset.yaml

Deletes the StatefulSet and its pods.

Cleanup - Delete PVCs

kubectl delete pvc www-nginx-sts-0
kubectl delete pvc www-nginx-sts-1
kubectl delete pvc www-nginx-sts-2

Deletes the PersistentVolume Claims to clean up storage resources.

YAML Configuration File

apiVersion: v1
kind: Service
metadata:
  name: nginx-headless
  labels:
    run: nginx-sts-demo
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    run: nginx-sts-demo
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: nginx-sts
spec:
  serviceName: nginx-headless
  replicas: 3
  selector:
    matchLabels:
      run: nginx-sts-demo
  template:
    metadata:
      labels:
        run: nginx-sts-demo
    spec:
      containers:
      - name: nginx
        image: nginx
        volumeMounts:
        - name: www
          mountPath: /var/www/
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      storageClassName: hostpath
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 10Mi

YAML Configuration Explanation:

Headless Service:

  • apiVersion: v1 → Specifies the Kubernetes API version
  • kind: Service → Defines this as a Service resource
  • metadata.name: nginx-headless → Names the service
  • clusterIP: None → Makes this a headless service (no load balancing)
  • selector.run: nginx-sts-demo → Selects pods with this label

StatefulSet Configuration:

  • apiVersion: apps/v1 → StatefulSet API version
  • kind: StatefulSet → Defines this as a StatefulSet resource
  • metadata.name: nginx-sts → Names the StatefulSet
  • serviceName: nginx-headless → Associates with the headless service
  • replicas: 3 → Creates 3 pod replicas
  • selector.matchLabels.run: nginx-sts-demo → Selects pods with this label

Pod Template:

  • template.metadata.labels.run: nginx-sts-demo → Labels for the pods
  • spec.containers.name: nginx → Container name
  • spec.containers.image: nginx → Uses the official Nginx image
  • volumeMounts.name: www → Mounts the volume named "www"
  • volumeMounts.mountPath: /var/www/ → Mounts to this directory in the container

Volume Claim Template:

  • volumeClaimTemplates.metadata.name: www → Names the volume claim template
  • storageClassName: hostpath → Uses hostPath storage class
  • accessModes: ReadWriteOnce → Volume can be mounted as read-write by a single node
  • resources.requests.storage: 10Mi → Requests 10MB of storage

How StatefulSets Work:

StatefulSets maintain a sticky identity for each of their Pods. These pods are created from the same spec, but are not interchangeable: each has a persistent identifier that it maintains across any rescheduling. When a StatefulSet's Pod is deleted, it is recreated with the same name and network identity. Each pod in a StatefulSet gets its own PersistentVolumeClaim, ensuring data persistence even when pods are rescheduled.