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
DeploymentStatefulSet
Pod namesRandom (api-abc12)Ordered (db-0, db-1)
StorageShared or no persistentUnique PVC per pod
ScalingAny orderSequential (0→1→2)
Use caseStateless appsDatabases, 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

ProbePurposeAction on Failure
LivenessIs the app alive?Restart container
ReadinessIs the app ready for traffic?Remove from service
StartupHas 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