Docs
/
Docker Kubernetes
Chapter 10
10 — Kubernetes Workloads
Deployment
The most common workload — manages stateless pods with rolling updates.
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
labels:
app: api
spec:
replicas: 3
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: my-app:1.0.0
ports:
- containerPort: 3000
env:
- name: NODE_ENV
value: "production"
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "1"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
kubectl apply -f deployment.yaml
kubectl get deployments
kubectl rollout status deployment/api
kubectl rollout history deployment/api
kubectl rollout undo deployment/api # Rollback
kubectl scale deployment/api --replicas=5 # Scale
ReplicaSet
Ensures N pod replicas are running. Managed automatically by Deployments — rarely created directly.
StatefulSet
For stateful applications (databases, message brokers) that need:
- Stable pod names (
db-0,db-1,db-2) - Stable persistent storage per pod
- Ordered startup/shutdown
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-alpine
ports:
- containerPort: 5432
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
| Deployment | StatefulSet | |
|---|---|---|
| Pod names | Random (api-abc12) | Ordered (db-0, db-1) |
| Storage | Shared or no persistent | Unique PVC per pod |
| Scaling | Any order | Sequential (0→1→2) |
| Use case | Stateless apps | Databases, Kafka, Redis |
DaemonSet
Runs one pod per node. Used for node-level services.
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: log-agent
spec:
selector:
matchLabels:
app: log-agent
template:
metadata:
labels:
app: log-agent
spec:
containers:
- name: fluentd
image: fluentd:latest
volumeMounts:
- name: logs
mountPath: /var/log
volumes:
- name: logs
hostPath:
path: /var/log
Use cases: Log collectors (Fluentd), monitoring agents (Prometheus node exporter), network plugins.
Job & CronJob
Job (Run to Completion)
apiVersion: batch/v1
kind: Job
metadata:
name: db-migration
spec:
template:
spec:
containers:
- name: migrate
image: my-app:1.0.0
command: ["node", "migrate.js"]
restartPolicy: Never
backoffLimit: 3 # Retry 3 times on failure
CronJob (Scheduled)
apiVersion: batch/v1
kind: CronJob
metadata:
name: daily-report
spec:
schedule: "0 2 * * *" # 2 AM daily
jobTemplate:
spec:
template:
spec:
containers:
- name: report
image: my-app:1.0.0
command: ["node", "generateReport.js"]
restartPolicy: Never
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
Health Probes
| Probe | Purpose | Action on Failure |
|---|---|---|
| Liveness | Is the app alive? | Restart container |
| Readiness | Is the app ready for traffic? | Remove from service |
| Startup | Has the app started? | Don't check liveness until started |
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 15
periodSeconds: 20
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
startupProbe:
httpGet:
path: /health
port: 3000
failureThreshold: 30
periodSeconds: 10
# App has 300s (30 × 10) to start up
Key Takeaways
- Deployment for stateless apps (most common) — supports rolling updates and rollbacks
- StatefulSet for databases and stateful services — stable names and persistent storage
- DaemonSet for node-level agents (logging, monitoring)
- Job for one-time tasks; CronJob for scheduled tasks
- Always set liveness and readiness probes — K8s needs to know your app's health
- Always set resource requests and limits — prevents pods from consuming entire node