Kubernetes_statefulsets
Kubernetes StatefulSets and DaemonSets
Section titled “Kubernetes StatefulSets and DaemonSets”Overview
Section titled “Overview”StatefulSets and DaemonSets are two specialized workload resources in Kubernetes that address specific use cases beyond the standard Deployment.
When to Use Each
Section titled “When to Use Each”| Feature | Deployment | StatefulSet | DaemonSet |
|---|---|---|---|
| Use Case | Stateless apps | Stateful apps | Node-level daemons |
| Pod Identity | Random | Stable, ordinal | Unique per node |
| Storage | Shared/EmptyDir | Persistent volumes | HostPath/Local PV |
| Scaling | Any order | Ordered | One per node |
| Networking | Cluster DNS | Headless + stable | Cluster DNS |
StatefulSet
Section titled “StatefulSet”StatefulSets provide:
- Stable, unique network identifiers: Pods retain their identity across rescheduling
- Stable, persistent storage: PersistentVolume claims persist across pod rescheduling
- Ordered, graceful deployment and scaling: Pods are created, updated, and deleted in order
- Ordered, automated rolling updates: Updates proceed in reverse ordinal order
Basic StatefulSet
Section titled “Basic StatefulSet”apiVersion: apps/v1kind: StatefulSetmetadata: name: my-statefulsetspec: serviceName: my-headless-service replicas: 3 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp image: myapp:latest ports: - containerPort: 80 name: http volumeMounts: - name: data mountPath: /data volumeClaimTemplates: - metadata: name: data spec: accessModes: ["ReadWriteOnce"] storageClassName: standard resources: requests: storage: 1GiHeadless Service
Section titled “Headless Service”StatefulSets require a headless service for stable network identity:
apiVersion: v1kind: Servicemetadata: name: my-headless-servicespec: clusterIP: None # Makes it headless selector: app: myapp ports: - name: http port: 80 targetPort: 80Pod Naming Convention
Section titled “Pod Naming Convention”Pods in a StatefulSet get stable names:
my-statefulset-0my-statefulset-1my-statefulset-2
These names persist across rescheduling, enabling:
- Stable DNS entries:
my-statefulset-0.my-headless-service.default.svc.cluster.local - Stable hostnames: Used in pod manifests
StatefulSet Scaling
Section titled “StatefulSet Scaling”# Scale upkubectl scale statefulset my-statefulset --replicas=5
# Scale down (pods are terminated in reverse order: 4, 3, 2...)kubectl scale statefulset my-statefulset --replicas=2
# View current replicaskubectl get statefulset my-statefulsetUpdate Strategies
Section titled “Update Strategies”spec: updateStrategy: type: RollingUpdate # Default rollingUpdate: partition: 2 # Only update pods with ordinal >= 2Or use OnDelete strategy - pods are only updated when manually deleted:
spec: updateStrategy: type: OnDeletePod Management Policy
Section titled “Pod Management Policy”spec: podManagementPolicy: Parallel # Default is OrderedReady- OrderedReady: One pod at a time, in order
- Parallel: All pods created/terminated simultaneously
PersistentVolumeClaim Templates
Section titled “PersistentVolumeClaim Templates”Each pod gets its own PVC from the template:
spec: volumeClaimTemplates: - metadata: name: data spec: accessModes: ["ReadWriteOnce"] storageClassName: fast-storage resources: requests: storage: 10GiStatefulSet Example: Database
Section titled “StatefulSet Example: Database”apiVersion: apps/v1kind: StatefulSetmetadata: name: postgres-statefulsetspec: serviceName: postgres replicas: 3 selector: matchLabels: app: postgres template: metadata: labels: app: postgres spec: containers: - name: postgres image: postgres:14 env: - name: POSTGRES_DB value: mydb - name: POSTGRES_USER value: admin - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: name: postgres-secret key: password ports: - containerPort: 5432 name: postgres volumeMounts: - name: postgres-data mountPath: /var/lib/postgresql/data volumeClaimTemplates: - metadata: name: postgres-data spec: accessModes: ["ReadWriteOnce"] storageClassName: fast-storage resources: requests: storage: 20Gi---apiVersion: v1kind: Servicemetadata: name: postgresspec: clusterIP: None selector: app: postgres ports: - port: 5432 targetPort: 5432DaemonSet
Section titled “DaemonSet”DaemonSets ensure that all (or specific) nodes run a copy of a specific pod.
Basic DaemonSet
Section titled “Basic DaemonSet”apiVersion: apps/v1kind: DaemonSetmetadata: name: logging-agent labels: app: loggingspec: selector: matchLabels: app: logging-agent template: metadata: labels: app: logging-agent spec: containers: - name: fluentd image: fluentd:v1.16 volumeMounts: - name: varlog mountPath: /var/log - name: varlibdockercontainers mountPath: /var/lib/docker/containers readOnly: true volumes: - name: varlog hostPath: path: /var/log - name: varlibdockercontainers hostPath: path: /var/lib/docker/containersDaemonSet with Node Selection
Section titled “DaemonSet with Node Selection”Run pods only on specific nodes:
spec: nodeSelector: disktype: ssd # Only run on nodes with this label tolerations: - key: "node-role.kubernetes.io/master" effect: NoSchedule - key: "critical" effect: NoSchedule operator: ExistsDaemonSet Update Strategies
Section titled “DaemonSet Update Strategies”spec: updateStrategy: type: RollingUpdate # or OnDelete rollingUpdate: maxUnavailable: 1 # Max pods unavailable during updateMonitoring Agent Example
Section titled “Monitoring Agent Example”apiVersion: apps/v1kind: DaemonSetmetadata: name: node-exporterspec: selector: matchLabels: app: node-exporter template: metadata: labels: app: node-exporter spec: hostNetwork: true hostPID: true containers: - name: node-exporter image: prom/node-exporter:v1.6.1 args: - --path.procfs=/host/proc - --path.sysfs=/host/sys - --path.rootfs=/host volumeMounts: - name: proc mountPath: /host/proc readOnly: true - name: sys mountPath: /host/sys readOnly: true - name: root mountPath: /host readOnly: true volumes: - name: proc hostPath: path: /proc - name: sys hostPath: path: /sys - name: root hostPath: path: /Running on Control Plane Nodes
Section titled “Running on Control Plane Nodes”To run DaemonSet pods on master nodes:
spec: tolerations: - key: "node-role.kubernetes.io/control-plane" operator: Exists effect: NoSchedule - key: "node-role.kubernetes.io/master" operator: Exists effect: NoScheduleWorking with StatefulSets
Section titled “Working with StatefulSets”Debugging StatefulSets
Section titled “Debugging StatefulSets”# List StatefulSetskubectl get statefulset
# Describe StatefulSetkubectl describe statefulset my-statefulset
# Get pods (note stable naming)kubectl get pods -l app=myapp
# Check PersistentVolumeClaimskubectl get pvc
# View pod logs (use stable pod name)kubectl logs my-statefulset-0
# Delete pod (will be recreated with same identity)kubectl delete pod my-statefulset-0
# Manually force delete a stuck podkubectl delete pod my-statefulset-0 --grace-period=0 --forceTroubleshooting Common Issues
Section titled “Troubleshooting Common Issues”-
Pod stuck in Pending:
Terminal window kubectl describe pvc <pvc-name># Check storage class, available storage -
Pod stuck in ContainerCreating:
Terminal window kubectl describe pod <pod-name># Check volume mounting issues -
Scaling stuck:
Terminal window kubectl get events --sort-by='.lastTimestamp'# Check for resource constraints or PVC issues
Working with DaemonSets
Section titled “Working with DaemonSets”Debugging DaemonSets
Section titled “Debugging DaemonSets”# List DaemonSetskubectl get daemonset
# Describe DaemonSetkubectl describe daemonset logging-agent
# Check which nodes have the daemonkubectl get pods -o wide | grep <daemonset-name>
# View DaemonSet rollout statuskubectl rollout status daemonset logging-agentCommon DaemonSet Use Cases
Section titled “Common DaemonSet Use Cases”- Log collectors: Fluentd, Logstash
- Monitoring agents: Prometheus node exporter, Datadog
- Storage daemons: Ceph, GlusterFS
- Networking: CNI plugins, kube-proxy
- Security: Falco, Auditbeat
Best Practices
Section titled “Best Practices”StatefulSet Best Practices
Section titled “StatefulSet Best Practices”- Use for truly stateful applications: Databases, message queues
- Always use headless service: Required for stable network identity
- Configure proper storage: Use appropriate StorageClass
- Set appropriate resources: Memory/CPU requests for scheduling
- Plan your scaling strategy: Consider data rebalancing
- Use readiness probes: Ensure pods are ready before traffic
DaemonSet Best Practices
Section titled “DaemonSet Best Practices”- Use nodeSelector/tolerations: Target specific nodes
- Set appropriate resources: Since they run on every node
- Use hostNetwork wisely: Consider port conflicts
- Handle upgrades carefully: Use updateStrategy appropriately
- Consider pod disruption budgets: Prevent service interruption
Summary
Section titled “Summary”StatefulSets are ideal for:
- Databases (PostgreSQL, MySQL, MongoDB)
- Message queues (Kafka, RabbitMQ)
- Distributed systems requiring stable identity
- Applications needing persistent storage with stable names
DaemonSets are ideal for:
- Log aggregation (Fluentd, Filebeat)
- Monitoring (Prometheus node exporter)
- Cluster storage (Ceph, Rook)
- Network plugins (CNI providers)
- System daemons (kube-proxy)
Both resources provide specialized behavior that Deployments cannot replicate, making them essential tools for specific Kubernetes workloads.