Workload Controllers Overview
| Controller | Use Case | Pod Identity | Scaling |
|---|---|---|---|
| Deployment | Stateless apps | Interchangeable | Horizontal |
| StatefulSet | Databases, queues | Stable, ordered | Ordered |
| DaemonSet | Node agents | One per node | Per node |
| Job | Batch tasks | Temporary | Parallelism |
| CronJob | Scheduled tasks | Temporary | On schedule |
StatefulSets
StatefulSets manage stateful applications that need:
- Stable network identities
- Persistent storage per pod
- Ordered deployment and scaling
StatefulSet vs Deployment
| Feature | Deployment | StatefulSet |
|---|---|---|
| Pod names | Random (app-7d9f8-abc12) | Ordered (app-0, app-1, app-2) |
| Storage | Shared or none | Dedicated PVC per pod |
| Scaling | Any order | Sequential (0→1→2) |
| Deletion | Any order | Reverse (2→1→0) |
| DNS | Via Service only | Individual pod DNS |
PostgreSQL StatefulSet
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
ports:
- containerPort: 5432
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: pg-secret
key: password
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
volumeMounts:
- name: postgres-data
mountPath: /var/lib/postgresql/data
resources:
requests:
memory: "256Mi"
cpu: "250m"
volumeClaimTemplates:
- metadata:
name: postgres-data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
---
# Headless service for StatefulSet DNS
apiVersion: v1
kind: Service
metadata:
name: postgres
spec:
clusterIP: None
selector:
app: postgres
ports:
- port: 5432Pod DNS entries:
postgres-0.postgres.default.svc.cluster.localpostgres-1.postgres.default.svc.cluster.localpostgres-2.postgres.default.svc.cluster.local
DaemonSets
DaemonSets ensure one pod runs on every (or selected) node. Perfect for:
- Log collectors (Fluentd, Filebeat)
- Monitoring agents (Node Exporter, Datadog)
- Network plugins (Calico, Cilium)
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-exporter
namespace: monitoring
spec:
selector:
matchLabels:
app: node-exporter
template:
metadata:
labels:
app: node-exporter
spec:
hostNetwork: true
containers:
- name: node-exporter
image: prom/node-exporter:latest
ports:
- containerPort: 9100
hostPort: 9100
volumeMounts:
- name: proc
mountPath: /host/proc
readOnly: true
- name: sys
mountPath: /host/sys
readOnly: true
volumes:
- name: proc
hostPath:
path: /proc
- name: sys
hostPath:
path: /sys
tolerations:
- operator: Exists # Run on ALL nodes including mastersNode Selection
spec:
template:
spec:
nodeSelector:
node-type: worker # Only on worker nodes
# Or use affinity for more control
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values: ["linux"]Jobs
Jobs run tasks to completion (batch processing, migrations, backups).
apiVersion: batch/v1
kind: Job
metadata:
name: db-migration
spec:
backoffLimit: 3 # Retry up to 3 times
activeDeadlineSeconds: 600 # Timeout after 10 min
template:
spec:
restartPolicy: Never
containers:
- name: migrate
image: nextgen-app:1.0
command: ["npm", "run", "migrate"]
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: db-secret
key: urlParallel Jobs
apiVersion: batch/v1
kind: Job
metadata:
name: batch-processor
spec:
completions: 10 # Total tasks to complete
parallelism: 3 # Run 3 pods at a time
template:
spec:
restartPolicy: Never
containers:
- name: worker
image: batch-worker:1.0CronJobs
apiVersion: batch/v1
kind: CronJob
metadata:
name: nightly-backup
spec:
schedule: "0 2 * * *" # 2 AM daily
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 3
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: backup
image: backup-tool:1.0
command: ["/bin/sh", "-c", "backup.sh && upload-to-s3.sh"]| Concurrency Policy | Behavior |
|---|---|
| Allow | Multiple jobs can run simultaneously |
| Forbid | Skip new job if previous still running |
| Replace | Cancel running job, start new one |
Managing Workloads
# StatefulSets
kubectl get statefulsets
kubectl scale statefulset postgres --replicas=5
kubectl rollout status statefulset postgres
# DaemonSets
kubectl get daemonsets -A
kubectl rollout status daemonset node-exporter -n monitoring
# Jobs
kubectl get jobs
kubectl describe job db-migration
kubectl logs job/db-migration
# CronJobs
kubectl get cronjobs
kubectl create job --from=cronjob/nightly-backup manual-backupSummary
You've learned:
- StatefulSets for databases with stable identity and storage
- DaemonSets for node-level agents and monitoring
- Jobs for batch processing and one-time tasks
- CronJobs for scheduled automation
- Choosing the right controller for each workload type
Next Steps
Next, we'll cover Kubernetes troubleshooting, resource management, and production best practices.