Skip to main content

Kubernetes Workloads

Learn how to manage applications using Kubernetes controllers.

1. Deployments

The standard way to run stateless applications (web servers, APIs).
  • ReplicaSet: Manages the number of pod copies.
  • Rolling Updates: Updates pods without downtime.
  • Rollbacks: Revert to previous versions if something goes wrong.
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 15

Managing Deployments

# Apply
kubectl apply -f deployment.yaml

# Scale manually
kubectl scale deployment nginx-deployment --replicas=5

# Update image (triggers rolling update)
kubectl set image deployment/nginx-deployment nginx=nginx:1.22

# Check rollout status
kubectl rollout status deployment/nginx-deployment

# View history
kubectl rollout history deployment/nginx-deployment

# Undo rollout
kubectl rollout undo deployment/nginx-deployment

2. StatefulSets

Used for stateful applications (Databases, Kafka, Zookeeper).
  • Stable Network ID: web-0, web-1 (not random).
  • Stable Storage: PersistentVolumeClaims are kept even if pods are deleted.
  • Ordered Deployment: 0 -> 1 -> 2.
  • Ordered Termination: 2 -> 1 -> 0.
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: "mysql"
  replicas: 3
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:8.0
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "password"
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 10Gi

3. DaemonSets

Ensures that all (or some) Nodes run a copy of a Pod.
  • Use cases: Log collectors (Fluentd), Monitoring agents (Prometheus Node Exporter).
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd
spec:
  selector:
    matchLabels:
      name: fluentd
  template:
    metadata:
      labels:
        name: fluentd
    spec:
      containers:
      - name: fluentd
        image: fluentd:v1

4. Jobs & CronJobs

Job

Runs a pod until it completes successfully (exit code 0).
  • Use cases: Batch processing, database migrations.
apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never
  backoffLimit: 4

CronJob

Creates Jobs on a schedule (like Linux cron).
apiVersion: batch/v1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            imagePullPolicy: IfNotPresent
            command:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure

Key Takeaways

WorkloadUse CaseExample
DeploymentStateless appsWeb servers, APIs
StatefulSetStateful appsDatabases, Kafka
DaemonSetNode agentsLogging, Monitoring
JobOne-off tasksDB Migration
CronJobScheduled tasksBackups

5. Horizontal Pod Autoscaler (HPA)

Automatically scales the number of pods based on observed CPU/memory utilization or custom metrics.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api-deployment
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80

HPA vs VPA

FeatureHPAVPA
What it scalesNumber of podsResources per pod
Best forStateless appsStateful apps, right-sizing
Can run together?Yes, but don’t use same metricUse different metrics
Interview Tip: HPA requires resource requests to be set. Without requests, HPA cannot calculate utilization percentage.

6. Pod Disruption Budgets (PDB)

Ensures a minimum number of pods remain available during voluntary disruptions (e.g., node drains, cluster upgrades).
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: api-pdb
spec:
  minAvailable: 2        # At least 2 pods must be running
  # OR
  # maxUnavailable: 1    # At most 1 pod can be down
  selector:
    matchLabels:
      app: api
Use Case: During kubectl drain, Kubernetes respects PDBs. If draining a node would violate the PDB, the drain waits.

7. Deployment Strategies Deep Dive

Rolling Update (Default)

Updates pods incrementally, ensuring availability.
strategy:
  type: RollingUpdate
  rollingUpdate:
    maxUnavailable: 25%   # Max pods that can be unavailable
    maxSurge: 25%         # Max extra pods during update

Recreate

Kills all existing pods before creating new ones.
  • Use Case: When you cannot run two versions simultaneously (e.g., database schema conflicts).
strategy:
  type: Recreate

Blue-Green Deployment (Manual with Services)

Run two identical environments. Switch traffic instantly.
# Blue deployment (current)
metadata:
  name: app-blue
  labels:
    version: blue

# Green deployment (new version)
metadata:
  name: app-green
  labels:
    version: green

# Service points to one version
selector:
  version: blue  # Switch to 'green' to cutover

Canary Deployment

Route a small percentage of traffic to the new version.
  • Requires Ingress controller or Service Mesh (Istio) for traffic splitting.

8. Pod Affinity & Anti-Affinity

Control which nodes pods are scheduled on based on labels.

Node Affinity

Schedule pods on nodes with specific labels.
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: disktype
          operator: In
          values:
          - ssd

Pod Anti-Affinity

Spread pods across nodes/zones to avoid single points of failure.
affinity:
  podAntiAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchLabels:
          app: redis
      topologyKey: "kubernetes.io/hostname"
Interview Tip: Use topologyKey: "topology.kubernetes.io/zone" to spread pods across availability zones for high availability.

9. Taints & Tolerations

Taints are applied to nodes to repel pods. Tolerations allow pods to be scheduled on tainted nodes.
# Taint a node
kubectl taint nodes node1 key=value:NoSchedule
# Pod with toleration
spec:
  tolerations:
  - key: "key"
    operator: "Equal"
    value: "value"
    effect: "NoSchedule"
EffectBehavior
NoScheduleNew pods won’t be scheduled
PreferNoScheduleSoft version - avoid if possible
NoExecuteEvict existing pods + no new scheduling

Interview Questions & Answers

AspectDeploymentStatefulSet
Pod NamesRandom (app-abc123)Ordered (app-0, app-1)
StorageShared or ephemeralDedicated PVC per pod
Scaling OrderParallelSequential (0→1→2)
Use CaseStateless appsDatabases, Kafka
  • ReplicaSet ensures a specified number of pod replicas are running
  • Deployment manages ReplicaSets and provides:
    • Rolling updates
    • Rollback capability
    • Update history
  • You almost never create ReplicaSets directly; use Deployments instead.
  1. A new ReplicaSet is created with the updated pod template
  2. New pods are created in the new ReplicaSet
  3. Old pods are terminated from the old ReplicaSet (respecting maxUnavailable)
  4. Old ReplicaSet is kept for rollback (scaled to 0)
Use Pod Anti-Affinity with topologyKey:
affinity:
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      podAffinityTerm:
        labelSelector:
          matchLabels:
            app: my-app
        topologyKey: "topology.kubernetes.io/zone"
Or use Pod Topology Spread Constraints for more control.
Init containers run before app containers and are used for:
  • Wait for dependencies (database, service)
  • Clone git repos
  • Run database migrations
  • Generate config files
They run sequentially and must complete successfully before app containers start.
  1. Check logs: kubectl logs <pod> --previous
  2. Describe pod: kubectl describe pod <pod> (check Events)
  3. Check resources: Is the container OOMKilled?
  4. Exec into container: kubectl exec -it <pod> -- sh (if it starts briefly)
  5. Override command: Create a debug pod with command: ["/bin/sleep", "infinity"]

Common Pitfalls

1. Missing Resource Limits: Without limits, a single pod can consume all node resources, affecting other pods.2. No Readiness Probes: Traffic is routed to pods before they’re ready, causing 502 errors.3. Single Replica Deployments: No high availability. Always run at least 2-3 replicas in production.4. Not Using PDBs: During upgrades, all pods could be evicted simultaneously.5. Forgetting Anti-Affinity: All replicas could land on the same node, defeating HA.

Next: Kubernetes Services →