StatefulSets in Azure Kubernetes Service (AKS)
This article introduces Kubernetes StatefulSets and how they can be used in Azure Kubernetes Service (AKS) to manage stateful applications.
What are StatefulSets?
StatefulSets are Kubernetes objects used to manage stateful applications. Unlike Deployments, which manage stateless applications and can restart pods in any order, StatefulSets provide guarantees about the ordering and uniqueness of Pods. These guarantees are essential for applications that require stable network identifiers, stable persistent storage, and ordered, graceful deployment and scaling.
Key Features of StatefulSets
- Stable, unique network identifiers: Each Pod in a StatefulSet gets a unique, stable hostname. For example, a StatefulSet named
webwith 3 replicas might have Pods namedweb-0,web-1, andweb-2. - Stable persistent storage: Each Pod can be automatically associated with a unique PersistentVolumeClaim (PVC). When a Pod is rescheduled, it retains its association with the same PVC.
- Ordered, graceful deployment and scaling: Pods are created, updated, and deleted in a specific, ordered sequence. This ensures that operations are performed predictably.
- Ordered, automated rolling updates: When updating a StatefulSet, Pods are updated in reverse ordinal order (e.g.,
web-2, thenweb-1, thenweb-0).
When to Use StatefulSets
StatefulSets are ideal for applications that:
- Require stable network identities.
- Require stable persistent storage.
- Require ordered, graceful deployment and scaling.
- Require ordered, automated rolling updates.
- Require ordered, automated rollbacks.
Common examples include:
- Database clusters (e.g., MySQL, PostgreSQL, MongoDB)
- Message queues (e.g., Kafka, RabbitMQ)
- Distributed file systems (e.g., Ceph)
- Any application where the order of operations or stable identity is critical.
StatefulSet vs. Deployment
Here's a comparison of StatefulSets and Deployments:
| Feature | StatefulSet | Deployment |
|---|---|---|
| Pod Identity | Stable and unique (e.g., app-0, app-1) |
Ephemeral and interchangeable (e.g., generated names) |
| Network Identity | Stable hostnames | Dynamic hostnames |
| Storage | Stable PersistentVolumeClaims per Pod | Shared storage or ephemeral storage |
| Update Strategy | Ordered rolling updates (reverse ordinal) | Rolling updates (any order) |
| Scaling | Ordered scaling (up and down) | Unordered scaling |
| Use Case | Stateful applications (databases, queues) | Stateless applications (web servers, APIs) |
Creating a StatefulSet
You define a StatefulSet in a YAML manifest. The following is a basic example of a StatefulSet for a simple web application that requires stable storage:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web-app
spec:
serviceName: "web-app-service" # Headless service for stable network IDs
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: k8s.gcr.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
In this example:
serviceNamepoints to a headless Service. A headless service creates DNS entries for each Pod, enabling stable network identities.replicasspecifies the desired number of Pods.volumeClaimTemplatesdefines a template for the PersistentVolumeClaims (PVCs) that will be created for each Pod. Each Pod will get its own PVC (e.g.,www-web-app-0,www-web-app-1).
Key Components for StatefulSets
Headless Services
A headless Service is crucial for StatefulSets. It doesn't get a cluster IP and instead, the Kubernetes DNS server returns the IP addresses of the Pods that match the selector. This allows direct access to individual Pods using stable DNS names.
apiVersion: v1
kind: Service
metadata:
name: web-app-service
labels:
app: nginx
spec:
ports:
- port: 80
name: web
selector:
app: nginx
clusterIP: None # This makes it a headless service
PersistentVolumeClaims (PVCs)
StatefulSets often leverage volumeClaimTemplates to automatically provision persistent storage for each Pod. This ensures that each Pod has its own dedicated storage that persists independently of the Pod's lifecycle.
Managing StatefulSets in AKS
You can manage StatefulSets in AKS using standard Kubernetes tools like kubectl.
Creating a StatefulSet
Save the StatefulSet definition to a YAML file (e.g., statefulset.yaml) and apply it:
kubectl apply -f statefulset.yaml
Viewing StatefulSets
kubectl get statefulsets
Viewing Pods managed by a StatefulSet
Notice the ordinal index in the Pod names:
kubectl get pods -l app=nginx
Scaling a StatefulSet
You can scale a StatefulSet up or down:
kubectl scale statefulset web-app --replicas=5
When scaling down, Pods are terminated in reverse ordinal order (e.g., web-4, then web-3).
Updating a StatefulSet
To update the Pods, you typically modify the Pod template in the StatefulSet definition and then apply the changes. The update will proceed in a rolling fashion according to the defined update strategy (default is RollingUpdate).
Considerations for AKS
- Storage Classes: Ensure you have appropriate Storage Classes defined in your AKS cluster to provision the desired type of persistent storage (e.g., Azure Disk, Azure Files).
- Resource Limits: Define resource requests and limits for your containers to ensure stable performance and prevent resource contention.
- Service Discovery: Understand how your application will discover other instances. Headless Services are key for this with StatefulSets.
- Backup and Restore: Implement a robust backup and restore strategy for your persistent volumes.
Conclusion
StatefulSets are a powerful Kubernetes feature that enables the reliable management of stateful applications. By providing stable identities, storage, and ordered operations, StatefulSets are essential for deploying complex, distributed stateful workloads on Azure Kubernetes Service (AKS).