Interactive Lab ยท CKA ยท Intermediate

STATEFULSETS

$ kubectl get statefulset postgres -o wide
🗃 StatefulSets vs Deployments
  • 1A StatefulSet gives each pod a stable, persistent identity: fixed name (pod-0, pod-1...), stable DNS hostname, and a PVC that follows the pod through restarts.
  • 2Pods are created and deleted in order. Scaling up waits for each pod to be Running before starting the next. Scaling down deletes in reverse order.
  • 3Use StatefulSets for databases (Postgres, MySQL, MongoDB), message queues (Kafka), and distributed systems that need stable peer discovery.
If your app does not need stable hostnames, persistent storage per pod, or ordered startup use a Deployment. StatefulSets add complexity.
📝 StatefulSet manifest
  • 1serviceName must reference a Headless Service (clusterIP: None). This enables stable DNS for each pod.
  • 2volumeClaimTemplates creates a PVC per pod automatically. pod-0 gets data-postgres-0, pod-1 gets data-postgres-1. They survive restarts.
  • 3Pod names follow the pattern: statefulset-name-ordinal. postgres-0, postgres-1, postgres-2.
StatefulSet manifest
apiVersion: apps/v1 kind: StatefulSet metadata: name: postgres spec: serviceName: "postgres" replicas: 3 selector: matchLabels: app: postgres template: metadata: labels: app: postgres spec: containers: - name: postgres image: postgres:16 volumeMounts: - name: data mountPath: /var/lib/postgresql/data volumeClaimTemplates: - metadata: name: data spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: 10Gi
🔗 Headless Service Stable DNS per pod
  • 1A headless service has clusterIP: None. DNS returns individual pod IPs instead of a single virtual IP.
  • 2Each StatefulSet pod gets a stable DNS entry: postgres-0.postgres.default.svc.cluster.local. Pods can connect to specific replicas by name.
  • 3This is how Postgres replication, Kafka broker discovery, and Elasticsearch cluster formation work in Kubernetes.
Headless Service
apiVersion: v1 kind: Service metadata: name: postgres spec: clusterIP: None selector: app: postgres ports: - port: 5432 # DNS entries created: # postgres-0.postgres.default.svc.cluster.local # postgres-1.postgres.default.svc.cluster.local # postgres-2.postgres.default.svc.cluster.local
StatefulSet vs Deployment
Pod namesStatefulSet: pod-0, pod-1. Deployment: random hash.
Startup orderStatefulSet: sequential. Deployment: parallel.
StorageStatefulSet: PVC per pod. Deployment: shared/ephemeral.
Use caseDatabases, queues. Not for stateless apps.
Key Fields
serviceNameMust reference a headless service (clusterIP: None)
volumeClaimTemplatesCreates one PVC per pod automatically
podManagementPolicyOrderedReady (default) or Parallel
DNS patternpod-N.svc.namespace.svc.cluster.local
Done