kubelet asks the container runtime to start the container's entrypoint process — from the runtime's point of view, this is a completely ordinary start, identical to any healthy Pod.
StartThe entrypoint process terminates — a missing environment variable causes a startup exception, a config file is absent, a dependent service (database) isn't reachable yet. The container exits with a non-zero code.
Exitkubelet notices the container exited and checks the Pod's restartPolicy (default: Always). Since it's Always, kubelet restarts the container immediately the first time.
Restart PolicyBecause nothing about the underlying cause (bad config, unreachable dependency) has changed, the restarted container fails identically within moments. This is a Pod's own restart loop, entirely local to the node — no scheduler or API server round-trip is needed for a restart.
RepeatAfter the first couple of rapid restarts, kubelet doesn't keep restarting instantly — it applies exponential backoff: 10s → 20s → 40s → 80s..., capped at 5 minutes. This is precisely the "CrashLoopBackOff" state: Kubernetes has decided the container is unhealthy and is deliberately slowing down the restart rate.
Checkpointkubectl get pods shows CrashLoopBackOff as the status, and RESTARTS climbs with every cycle. The Pod is never marked Failed outright — it stays in this loop indefinitely unless the underlying cause is fixed or the Pod is deleted.
StatusEach restart, image pull, and backoff decision generates an Event object visible via kubectl describe pod — this Events section, not the top-line status, is where the actual reason (OOMKilled, failed liveness probe, non-zero exit code) usually shows up.
Eventskubectl logs <pod> --previous retrieves stdout/stderr from the last crashed container instance — the current instance may not have produced any output yet, so this flag is essential, not optional.
Diagnosekubectl describe pod shows the Last State block with the exact exit code and reason (e.g. Error, OOMKilled). An exit code of 137 specifically points to an OOM kill or SIGKILL, not an application-level error.
DescribeDeleting/recreating the Pod, or waiting, does nothing on its own — the backoff timer resets with a new Pod, but the same underlying issue (bad config, missing secret, insufficient memory limit) causes the same crash again. Only fixing the actual cause breaks the loop.
Resolve| Term | Meaning |
|---|---|
| restartPolicy | Pod-level setting (Always, OnFailure, Never) controlling container restart behavior |
| Exponential Backoff | Increasing delay between restart attempts, capped at 5 minutes, to avoid a tight crash loop |
| --previous | kubectl logs flag retrieving output from the last crashed container instance |
| Last State | describe pod section showing the previous container's termination reason & exit code |
| Exit Code 137 | 128 + SIGKILL(9) — typically an OOM kill or forced termination |
| Exit Code 1 | Generic application-level error, uncaught exception |
| OOMKilled | Container exceeded its memory limit and was killed by the kernel cgroup controller |
| Liveness Probe | Health check that, if it keeps failing, causes kubelet to restart the container |
| Startup Probe | Gate that delays liveness/readiness checks until an app finishes a slow startup |
| Events | Per-object log of state changes/reasons, viewed via kubectl describe or get events |