Deployments keep Pods running. A Job does the opposite: it runs a Pod until the container exits 0, then stops.
Job seed-db completions: 1 parallelism: 1 backoffLimit: 6
└─▶ Pod seed-db-x7k2p exit 0 → Job Complete
exit 1 → new Pod after 10s, 20s, 40s … up to backoffLimitCreate one
kubectl create job seed-db --image=busybox -- sh -c 'echo seeding; sleep 2'
kubectl get jobs
kubectl get podsNAME STATUS COMPLETIONS DURATION AGE
seed-db Running 0/1 3s 3s
seed-db Complete 1/1 5s 8sThe Pod shows Completed afterwards and is kept so you can read it:
kubectl logs job/seed-db
kubectl describe job seed-dbdescribe shows Pods Statuses: 0 Active / 1 Succeeded / 0 Failed and the conditions. To block until it is done:
kubectl wait --for=condition=complete job/seed-db --timeout=60sThe spec
apiVersion: batch/v1
kind: Job
metadata:
name: seed-db
spec:
completions: 1 # how many successful Pods are needed
parallelism: 1 # how many run at once
backoffLimit: 2 # retries before the Job is Failed
template:
spec:
restartPolicy: Never # or OnFailure; never Always
containers:
- name: seed
image: busybox
command: ["sh", "-c", "echo seeding"]A Pod that exits non-zero counts as a failure. After backoffLimit retries the Job gets a Failed condition with reason BackoffLimitExceeded, and no more Pods are created. Deleting the Job deletes its Pods.
CronJob
A CronJob creates a Job on a schedule.
CronJob cleanup schedule: "*/5 * * * *"
├─▶ Job cleanup-29096885 (09:05) ─▶ Pod
├─▶ Job cleanup-29096890 (09:10) ─▶ Pod
└─▶ Job cleanup-29096895 (09:15) ─▶ Podkubectl create cronjob cleanup --image=busybox --schedule="*/5 * * * *" -- sh -c 'echo cleaning'
kubectl get cronjobs
kubectl create job cleanup-now --from=cronjob/cleanupThe last line runs the CronJob's template once, immediately. It is the standard way to test one.
| Field | Meaning |
|---|---|
schedule | Five cron fields: minute hour day-of-month month day-of-week |
suspend: true | Stop creating Jobs; existing ones keep running |
concurrencyPolicy | Allow (default), Forbid (skip if one is active), Replace (kill the active one) |
successfulJobsHistoryLimit | Finished Jobs to keep (default 3) |
failedJobsHistoryLimit | Failed Jobs to keep (default 1) |
Change any of them in place:
kubectl patch cronjob cleanup -p '{"spec":{"suspend":true}}'