KubeErrors

Completed: Every container in the pod exited successfully

Completed means all containers finished with exit status 0 and will not be restarted. For a Job this is success. For a Deployment it usually means the workload was not meant to be long-running.

Applies to: All Kubernetes versions

What it means

A pod reaches the Succeeded phase — displayed as Completed by kubectl get pods — when all of its containers have terminated successfully and none will be restarted. This is the intended end state for Jobs and CronJobs. Seeing it under a Deployment means something different: a Deployment's pods have restartPolicy: Always, so a container that exits successfully is restarted, and the pod normally cycles into CrashLoopBackOff rather than settling at Completed. A genuinely completed pod under a long-running controller is therefore a signal that the workload type is wrong for what the container actually does.

Most common causes

How to diagnose it

  1. Check what owns the pod: kubectl get pod POD -o jsonpath='{.metadata.ownerReferences[*].kind}'. A Job means this is normal; a ReplicaSet means it is not.
  2. Confirm the exit code was actually 0: kubectl describe pod POD under Last State.
  3. Read the logs to see whether the work was really done or the process merely returned early: kubectl logs POD.
  4. If a process daemonises, check the entrypoint — a foreground process is required for the container to stay alive.

How to fix it

  1. For genuine batch work, use a Job or CronJob. Set ttlSecondsAfterFinished so completed pods are cleaned up automatically instead of accumulating.
  2. If a long-running process is daemonising, run it in the foreground. Most servers have a flag for this.
  3. If a shell entrypoint is exiting, use exec so the real process replaces the shell and becomes PID 1 — this also makes signal handling work correctly.
  4. Nothing needs fixing for a completed Job. Its pods are retained on purpose so the logs remain readable.

Notes

Completed pods still hold their API objects and their logs on the node, so a CronJob running frequently with no history limits will accumulate them until they become their own problem. successfulJobsHistoryLimit and failedJobsHistoryLimit exist for this.

Related

Sources

Pages on this site are written with AI assistance from the primary sources listed on each page, then checked against those sources before publishing.