Jobs & CronJobs
Run batch tasks to completion with Jobs and schedule recurring work with CronJobs.
Why Not Deployments for Batch Work?
Deployments are designed to run forever β they maintain a desired state of continuously running Pods. If a container in a Deployment exits with code 0, the kubelet interprets this as a termination and the Deployment controller immediately restarts it to maintain replica count. This is wrong for a database migration or batch computation: you want the Pod to run once, complete its task, and stop.
Jobs and CronJobs are designed specifically for finite, run-to-completion workloads.
Job Architecture & Restart Policies
A Job ensures a specified number of Pods complete successfully (exit code 0).
Unlike Deployments, Jobs support two restart policies in their Pod templates:
Never: If the container fails (exits non-zero), the pod is not restarted. Instead, the Job controller spawns a completely new Pod on the cluster. This keeps the failed Pod and its logs intact for troubleshooting, but consumes IP/sandbox resources.OnFailure: If the container fails, the localkubeletrestarts the container inside the *same* Pod sandbox. This avoids scheduling overhead but does not create a clean new Pod.
The Job controller manages the retry logic up to backoffLimit times (default: 6). If the limit is reached, the Job is marked as failed.
Visualizing Job Controller Loop
[ CronJob Controller ] (Ticks on cron schedule)
β
βΌ (Creates Job object)
[ Job Object ] (Specifies completions, parallelism, backoffLimit)
β
βΌ (Job Controller observes Job in etcd)
[ Job Controller ] ββββββββββββββββββββββββββββββββββββββββββ
β β
βββΊ (Spawns N Pods up to parallelism limit) β
β β
βΌ β (Updates status)
βββββββββββββ βββββββββββββ βββββββββββββ β
β Pod 1 β β Pod 2 β β Pod N β β
β (Running) β β(Completed)β β (Failed) ββββ
βββββββ¬ββββββ βββββββ¬ββββββ βββββββ¬ββββββ
β β β
βΌ βΌ βΌ
Runs to exit Clean exit 0 RestartPolicy: Never/OnFailure
status (Success) Evicts/recreates up to backoffLimit
Key Job Fields
| Field | Description |
|---|---|
completions | Total number of successful Pod completions required to mark the Job complete. |
parallelism | Maximum number of Pods that are allowed to run concurrently at any given moment. |
backoffLimit | Maximum number of retries before marking the Job as failed (default: 6). |
activeDeadlineSeconds | Real-time execution limit for the Job. If exceeded, the Job is terminated. |
ttlSecondsAfterFinished | Time-to-live. Once finished, the Job and its Pods are garbage collected. |
spec: completions: 3 parallelism: 2 backoffLimit: 3 ttlSecondsAfterFinished: 120
CronJobs and Concurrency Policies
A CronJob manages Jobs on a schedule using standard Unix cron syntax:
ββββ minute (0-59) β ββββ hour (0-23) β β ββββ day of month (1-31) β β β ββββ month (1-12) β β β β ββββ day of week (0-7, 0 and 7 = Sunday) β β β β β * * * * *
"*/1 * * * *" = every minute. "0 2 * * *" = daily at 02:00.
concurrencyPolicy
| Value | Behaviour |
|---|---|
Allow | New Job starts even if previous is still running (default) |
Forbid | Skip new Job if previous is still running |
Replace | Cancel running Job and start a new one |
Use Cases
- Database migrations on deploy
- Nightly report generation
- Periodic data processing or backups
- Sending scheduled notifications