Cron jobs
Use cronJobs to run scheduled work on the same container model as deployments and jobs. Each key becomes a CronJob, named after the key and inheriting every global default (image.*, imagePullPolicy, configure.*, and the rest).
Minimal example
A bare key produces a working cron job that runs @daily with a single container named after the key:
cronJobs:
backup: # runs the default image @dailyMore often you set a schedule and a command:
cronJobs:
example-cronjob:
schedule: "1 * * * *"
command: ["echo", "Hello world!"]For a release named test, that renders CronJob/test-cronjob-example-cronjob. See Naming for how the cronjob- prefix and resource name are built.
Safe by default
Every cron job is generated to be safe unless you say otherwise:
| Field | Default | Meaning |
|---|---|---|
schedule | @daily | Standard cron syntax or an @ macro. |
concurrencyPolicy | Forbid | A run is skipped if the previous one is still going. |
backoffLimit | 0 | A failed job is not retried. |
restartPolicy | Never | A failed pod is not restarted in place. |
Override any of them per cron job:
cronJobs:
report:
schedule: "@weekly"
concurrencyPolicy: Replace # cancel the running job and start the new one
backoffLimit: 3 # retry a failed run up to three times
command: ["/app/bin", "generate-report"]Scheduling and job options
Beyond the defaults above, the CronJob and Job spec fields below are available, rendered only when you set them. The common case is timeZone: without it a schedule runs in the kube-controller-manager's zone (UTC in practice), so 30 2 * * * is not 02:30 where you work.
cronJobs:
report:
schedule: "30 2 * * *"
timeZone: Europe/Amsterdam # 02:30 local, follows DST
successfulJobsHistoryLimit: 3
ttlSecondsAfterFinished: 86400 # clean up finished jobs after a day
command: ["/app/bin", "generate-report"]| Field | Level | Meaning |
|---|---|---|
timeZone | CronJob | IANA zone the schedule runs in (e.g. Europe/Amsterdam). |
startingDeadlineSeconds | CronJob | Deadline to start a missed run before it counts as failed. |
suspend | CronJob | Pause scheduling without deleting the cron job. |
successfulJobsHistoryLimit | CronJob | How many completed jobs to keep. |
failedJobsHistoryLimit | CronJob | How many failed jobs to keep. |
parallelism | Job | Pods that may run at once. |
completions | Job | Successful pods needed for the job to finish. |
completionMode | Job | NonIndexed (default) or Indexed. |
activeDeadlineSeconds | Job | Wall-clock limit before the job is stopped. |
backoffLimitPerIndex | Job | Retry limit per index; requires completionMode: Indexed. |
maxFailedIndexes | Job | Failed indexes tolerated before the job fails (Indexed jobs). |
podFailurePolicy | Job | Rules matching pod failures, rendered verbatim. |
successPolicy | Job | When an Indexed job counts as succeeded, rendered verbatim; requires completionMode: Indexed. |
ttlSecondsAfterFinished | Job | Seconds to keep a finished job before it is cleaned up. |
podReplacementPolicy | Job | When a failed pod is replaced. |
Job-level fields render under jobTemplate.spec. Numeric fields render whenever the key is present, including at zero, so successfulJobsHistoryLimit: 0 keeps no completed jobs rather than falling back to a default.
The Kubernetes API rejects a Job that sets both backoffLimit and backoffLimitPerIndex. When you set backoffLimitPerIndex, the chart omits backoffLimit, including its usual 0 default, so the two never render together.
Containers and pod settings
A cron job carries the same pod and container fields as a deployment. The bare-key form is shorthand for a single container; declare containers explicitly when you need more than one, or to set container-level fields:
cronJobs:
sync:
schedule: "*/15 * * * *"
containers:
sync:
image: myorg/sync:latest
command: ["/app/bin", "sync"]
configure:
secrets: true # mount the release's Secret into this containerPod-level fields like volumes, volumeMounts, nodeSelector, and configure.* cascade to the containers exactly as they do for deployments. See Conventions for bare keys, cascading, and opting out with [] / {}.
Disabling a cron job
Set enabled: false to keep a cron job in values but skip rendering it, which is handy for per-environment overrides:
cronJobs:
nightly-import:
enabled: false # exists in values, renders nothing
schedule: "@daily"
command: ["/app/bin", "import"]One-off jobs
For work that runs once (migrations, install hooks) rather than on a schedule, use jobs instead. It follows the same container model. See Conventions for the bare-key form and the Helm hook annotations jobs supports.