Migrations, batch processing and nightly reports need run-to-completion semantics, not always-on pods.
A Job creates pods until a given number finish successfully. Its pods use restartPolicy: OnFailure or Never.
completions: how many successful pods are needed (default 1).parallelism: how many run at once.completionMode: Indexed: each pod getsJOB_COMPLETION_INDEX, handy for splitting work into shards.backoffLimit: retries before the Job is marked failed (default 6, with exponential back-off).activeDeadlineSeconds: a hard time limit.ttlSecondsAfterFinished: delete the Job and its pods automatically after it ends.
A CronJob creates a Job on a schedule in cron syntax ("0 3 * * *"), with timeZone (e.g. "Europe/Berlin") supported. Important settings:
concurrencyPolicy:Allow,Forbid(skip if the previous run is still going) orReplace.startingDeadlineSeconds: how late a missed run may still start.successfulJobsHistoryLimit/failedJobsHistoryLimit.
Jobs can run more than once: a pod may be retried after doing part of its work, and a CronJob can occasionally create two Jobs for one slot. Make the work idempotent.
Trigger a CronJob by hand with kubectl create job --from=cronjob/report report-manual.
Example
apiVersion: batch/v1
kind: CronJob
metadata: {name: nightly-report}
spec:
schedule: "0 3 * * *"
timeZone: "Europe/Berlin"
concurrencyPolicy: Forbid
jobTemplate:
spec:
backoffLimit: 3
activeDeadlineSeconds: 1800
ttlSecondsAfterFinished: 86400
template:
spec:
restartPolicy: OnFailure
containers:
- name: report
image: ghcr.io/acme/report:1.2.0
args: ["--date", "yesterday"]
# kubectl create job --from=cronjob/nightly-report test-run
# kubectl get jobs -w # COMPLETIONS 1/1Remember
- Jobs retry up to backoffLimit and finish after completions succeed
- CronJobs: schedule, timeZone, concurrencyPolicy
- Make job work idempotent: it can run more than once
Watch out for
- Leaving restartPolicy at Always in a Job template: the API rejects it.