Skip to content

Choosing a controller

Each workload controller manages pods. They differ in what they promise about identity, ordering and placement.

ControllerUse whenGuarantee
DeploymentStateless replicasInterchangeable pods, rolling updates
StatefulSetStateful membersStable name, stable storage, ordered rollout
DaemonSetNode-level agentsOne pod per matching node
JobRun to completionRetries until the success count is met
CronJobScheduled workCreates Jobs on a schedule

Deployments give you no identity

Deployment pods get random name suffixes and are replaced freely. Nothing about a given pod persists across a restart — not its name, not its storage, not its position in a cluster.

This is exactly right for a web server and exactly wrong for a database replica.

StatefulSets trade speed for identity

A StatefulSet gives each pod an ordinal name (db-0, db-1), a stable DNS entry via a headless Service, and its own PersistentVolumeClaim that survives rescheduling.

Rollouts happen one pod at a time, in reverse ordinal order, waiting for each to become ready before continuing.

Jobs and the completion count

apiVersion: batch/v1
kind: Job
metadata:
  name: migrate
spec:
  backoffLimit: 3
  template:
    spec:
      restartPolicy: Never
      containers:
        - name: migrate
          image: myapp:1.4
          command: ['./migrate']

backoffLimit counts failed pods, not failed containers. With restartPolicy: Never a failure creates a new pod; with OnFailure the container restarts inside the existing pod. The two produce different pod counts for the same number of failures, which makes debugging confusing if you are not expecting it.