CKAD — Restart Policies
What Are Restart Policies?
The restartPolicy field in a Pod spec controls what Kubernetes does when a container exits. It applies to all containers in the Pod.
Restart Policy Options
| Policy | Behavior | Default For | Use Case |
|---|---|---|---|
Always |
Always restart, regardless of exit code | Pods, Deployments | Long-running services (web servers, APIs) |
OnFailure |
Restart only on non-zero exit code | Jobs | Batch processing, retryable tasks |
Never |
Never restart | — | One-time tasks, debugging |
Important: restartPolicy applies at the Pod level, not the container level. All containers in a Pod share the same restart policy.
Always (Default)
The default policy for standalone Pods and Deployment-managed Pods. Kubernetes will always restart the container, even if it exits successfully.
apiVersion: v1
kind: Pod
metadata:
name: web-server
spec:
restartPolicy: Always # This is the default — you can omit it
containers:
- name: nginx
image: nginx:1.27
When the container exits:
- Exit code 0 → restart
- Exit code 1 → restart
- OOMKilled → restart
OnFailure
Restart the container only when it exits with a non-zero exit code. Commonly used with Jobs.
apiVersion: v1
kind: Pod
metadata:
name: batch-task
spec:
restartPolicy: OnFailure
containers:
- name: task
image: busybox:1.36
command: ["/bin/sh", "-c", "echo 'processing data' && exit 0"]
When the container exits:
- Exit code 0 → Pod moves to
Succeededstate, no restart - Exit code 1 → container restarts
OnFailure with Jobs
apiVersion: batch/v1
kind: Job
metadata:
name: data-processor
spec:
template:
spec:
restartPolicy: OnFailure # Required for Jobs (or Never)
containers:
- name: processor
image: busybox:1.36
command: ["/bin/sh", "-c", "echo 'job done'"]
Never
Never restart the container, regardless of how it exits. The Pod moves directly to Succeeded or Failed depending on the exit code.
apiVersion: v1
kind: Pod
metadata:
name: one-shot
spec:
restartPolicy: Never
containers:
- name: task
image: busybox:1.36
command: ["/bin/sh", "-c", "echo 'task complete'"]
When the container exits:
- Exit code 0 → Pod status is
Succeeded - Exit code 1 → Pod status is
Failed
When to Use Never
| Scenario | Why |
|---|---|
| Debugging | Inspect the container state after failure without it restarting |
| One-time tasks | Run once and check the result |
| Jobs that manage their own retries | Use backoffLimit on the Job instead |
Restart Policy and Workload Resources
Different workload resources have restrictions on which restart policies they accept:
| Workload | Allowed Policies | Default |
|---|---|---|
| Standalone Pod | Always, OnFailure, Never |
Always |
| Deployment / ReplicaSet / DaemonSet | Always only |
Always |
| Job | OnFailure, Never only |
— (must specify) |
| CronJob | OnFailure, Never only |
— (must specify) |
Exam tip: Deployments ONLY support restartPolicy: Always. Jobs ONLY support OnFailure or Never. This is a common trap in exam questions.
Restart Backoff Behavior
When a container keeps failing, Kubernetes uses exponential backoff for restarts:
1st restart → 10s delay
2nd restart → 20s delay
3rd restart → 40s delay
4th restart → 80s delay
5th restart → 160s delay
6th+ restart → 300s delay (capped)
This is what produces the CrashLoopBackOff status. After 5 minutes of running successfully, the backoff timer resets.
# Watch the backoff in action
kubectl get pod failing-pod -w
# Check restart count
kubectl get pod failing-pod -o jsonpath='{.status.containerStatuses[0].restartCount}'
Next: Learn how to control which nodes your Pods run on with Node Selection →