Kubernetes has few workload types, but choosing the wrong one is costly. A database in a Deployment even starts — and then teaches you, the hard way, why StatefulSet exists.
Course badge: tested on Kubernetes 1.35.
The map
| Type | Purpose | Stable identity? | Stable storage? |
|---|---|---|---|
| Pod | one-off tests | no | no |
| Deployment | stateless applications | no | no |
| StatefulSet | databases, queues, clusters | yes | yes |
| DaemonSet | one agent per node | per node | depends |
| Job | task until completion | no | no |
| CronJob | scheduled task | no | no |
Deployment: the default for stateless
A Deployment guarantees replicas, rollout and rollback. The pods are disposable and interchangeable.
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
revisionHistoryLimit: 5
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: ghcr.io/exemplo/api:1.4.2
ports:
- containerPort: 8080
Rollout:
kubectl rollout status deployment/api
kubectl rollout history deployment/api
kubectl rollout undo deployment/api
Cautions:
maxSurge/maxUnavailablemust fit the node capacity.- Misconfigured probes turn rollout into
CrashLoopBackOff. revisionHistoryLimitavoids infinite accumulation of ReplicaSets.
StatefulSet: identity matters
StatefulSet gives each pod:
- Ordinal name (
db-0,db-1,db-2). - Stable network via headless Service.
- Its own PVC via
volumeClaimTemplates. - Creation/removal order (usually sequential).
apiVersion: v1
kind: Service
metadata:
name: db-headless
spec:
clusterIP: None
selector:
app: db
ports:
- port: 5432
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: db
spec:
serviceName: db-headless
replicas: 3
selector:
matchLabels:
app: db
template:
metadata:
labels:
app: db
spec:
containers:
- name: db
image: postgres:16
ports:
- containerPort: 5432
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 5Gi
If you delete db-1, it comes back with the same name and the same PVC. That's what allows a database or a queue cluster to survive.
Cautions:
- Orphaned PVC after deleting the StatefulSet (by default, the PVC remains).
- Initialization order can make the cluster slow; some databases need their own init.
- Updates require strategy (
RollingUpdateorOnDelete).
DaemonSet: one per node
DaemonSet runs a pod on each node (or on a subset). It's the pattern for:
- CNI (flannel, Cilium).
- Log collection (Fluent Bit).
- Node metrics (node-exporter).
- Backup agents (Velero node-agent).
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-exporter
spec:
selector:
matchLabels:
app: node-exporter
template:
metadata:
labels:
app: node-exporter
spec:
tolerations:
- operator: Exists
containers:
- name: node-exporter
image: prom/node-exporter:v1.8.2
ports:
- containerPort: 9100
Caution: taints. If the node has a taint and the DaemonSet doesn't tolerate it, the pod doesn't run — and you discover that the monitoring agent doesn't cover exactly the problematic node.
Job and CronJob: tasks
Job runs until completion:
apiVersion: batch/v1
kind: Job
metadata:
name: backup
spec:
backoffLimit: 3
completions: 1
template:
spec:
restartPolicy: Never
containers:
- name: backup
image: ghcr.io/exemplo/backup:1.0
CronJob schedules:
apiVersion: batch/v1
kind: CronJob
metadata:
name: backup-diario
spec:
schedule: "0 2 * * *"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 3
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: backup
image: ghcr.io/exemplo/backup:1.0
Cautions:
concurrencyPolicy: Forbidavoids two overlapping executions.- high
backoffLimitcan generate infinite retry and noise. - A Job that never finishes needs
activeDeadlineSeconds. - CronJob in timezone: the cluster runs in UTC by default; adjust if the schedule matters.
Lab
- StatefulSet with PVC:
kubectl create ns workloads
kubectl -n workloads apply -f statefulset.yaml
kubectl -n workloads get pods,pvc
kubectl -n workloads delete pod db-1
kubectl -n workloads get pods -w
See db-1 come back with the same name and the same PVC.
- DaemonSet:
kubectl -n workloads apply -f daemonset.yaml
kubectl -n workloads get pods -o wide
- Job and CronJob:
kubectl -n workloads create job hello --image=busybox:1.36 -- echo hello
kubectl -n workloads logs job/hello
kubectl -n workloads create cronjob hello-cron --image=busybox:1.36 --schedule="*/1 * * * *" -- date
Common errors
| Symptom | Cause |
|---|---|
StatefulSet Pending |
PVC without storageClass or without PV |
| DaemonSet pods missing on a node | taint without toleration |
| Job in a loop | high backoffLimit + permanent error |
| Overlapping CronJob | concurrencyPolicy: Allow |
| Deployment doesn't update | same image/tag or wrong selector |
| PVC not reused | StatefulSet recreated with another name |
Checklist
- [ ] I know if the workload is stateless or stateful.
- [ ] Deployment has strategy and probes.
- [ ] StatefulSet has headless Service and
volumeClaimTemplates. - [ ] DaemonSet tolerates node taints.
- [ ] Jobs have retry limit and deadline.
- [ ] CronJobs have
concurrencyPolicydefined.
Glossary
- headless Service: Service without ClusterIP, used for stable DNS per pod.
- volumeClaimTemplates: PVC template per StatefulSet replica.
- taint/toleration: rule that repels/allows pods on nodes.
- backoffLimit: number of attempts of a Job.
- concurrencyPolicy: whether the CronJob can run in parallel.
Next
Now that you know how to choose the workload, let's expose everything with Services, Ingress, DNS and TLS.
Keep reading
Read also

StorCLI - Complete Cheat Sheet
StorCLI is the official and modern tool for managing Broadcom/LSI RAID controllers. This guide covers essential commands, syntax and use cases.
12 min de leitura
TutoriaisBusiness Services in Nyverra Portal: Translating IT into Business
The business doesn't feel a server go down — it feels email stop. The Business Services (Service Mapping) module of Nyverra ITSM Portal connects services like Email, ERP or PACS to CMDB assets, revealing the real impact of each failure.
5 min de leitura
SegurançaRPO vs RTO: How to Define Before Buying Backup (and Why Most Companies Get It Wrong)
Most companies buy backup asking the wrong question: "how much does it cost?". The right question is: how much data can I lose (RPO) and how long can I be down (RTO). Discover how to define these numbers per system and avoid purchasing protection based on price, not on real need.
9 min de leitura
Comments
No comments yet
Be the first to share your thoughts on this article.

Leave a comment