A CronJob creates jobs on a repetitive schedule.
CronJob is designed to perform regular scheduled actions, such as backups, reporting, etc. A CronJob object is like a line from a crontab file (cron table) on a Unix system. Runs a job periodically on a certain schedule, written in Cron format.
CronJobs have limitations and idiosyncrasies. For example, under certain circumstances, a single CronJob can create multiple simultaneous jobs. See limitations below.
When the control plane creates new Jobs and (indirectly) Pods for a CronJob, the .metadata.name of the CronJob is part of the basis for naming those Pods. The name of a CronJob must be a valid DNS subdomain value, but this can produce unexpected results for Pod host names. For best compatibility, the name should follow the most restrictive rules for a DNS label. Even when the name is a DNS subdomain, the name must be no longer than 52 characters. This is because the CronJob driver will automatically add 11 characters to the name you provide and there is a restriction that the length of a job name be no more than 63 characters.
This CronJob sample manifest
prints the current time and a hello message every minute:
(Running automated tasks with a CronJob takes you through this example in more detail.)
Write a CronJob specification
The .spec.schedule field is required. The value of that field follows the Cron syntax:
# ┌────────────── minute (0 – 59) # │ ┌────────────── hour (0 – 23) # │ │ ┌─────────────── Day of the Month (1 – 31) # │ │ │ │ ─ �� │ ┌───────────── month (1 – 12) # │ │ │ │ │ ┌────────────── weekday (0 – 6) (Sunday to Saturday; # │ │ │ │ │ │ │ │ 7 is also Sunday in some systems) # │ │ │ │ │ │ │ │ │ │ Mon, Tue, Wed, Thu, Fri, Sat# │ │ │ │ │ # * * For example, 0 0 13
* 5 states that the task should start every Friday at midnight, as well as on the 13th of each month at midnight.
The format also includes “Vixie cron” extended step values. As explained in the FreeBSD manual:
Step values can be used in conjunction with ranges. After a range with /<number> specifies hops of the number value through the range. For example, 0-23/2 can be used in the time field to specify the execution of commands every two hours (the alternative in the V7 standard is 0,2,4,6,8,10,12,14,16,18,20,22). Steps are also allowed after an asterisk, so if you want to say “every two hours”, just use */2.
In addition to the standard syntax, you can also use some macros as @monthly:
EntryDescriptionEquivalent to@yearly (or @annually)Run once a year at midnight on January 10 0 1 1 *@monthlyRun once a month at midnight on the first day of the month0 0 1 * *@weeklyRun once a week at midnight on Sunday morning0 0 * * 0@daily (or @midnight)Run once a day at midnight0 0 * * *@hourlyRun once an hour at the beginning of the hour0 * * * *
To generate CronJob programming expressions, You can also use web tools like crontab.guru.
spec.jobTemplate defines a template for jobs that CronJob creates and is required. It has exactly the same schema as a job, except that it is nested and does not have an apiVersion or kind. You can specify common metadata for templated jobs, such as tags or annotations. For information about writing a job .spec file, see Writing a Job Specification.
Deadline to delay job start
The .spec.startingDeadlineSeconds field is optional. This field defines a deadline (in whole seconds) to start the job, if that job misses its scheduled time for any reason.
After missing the deadline, CronJob skips that instance of the job (future occurrences are still scheduled). For example, if you have a backup job that runs twice a day, you can allow it to start up to 8 hours late, but not later, because a backup done later would not be useful: instead, you would prefer to wait for the next scheduled run.
that don’t meet your set deadline, Kubernetes treats them as failed jobs. If you do not specify startingDeadlineSeconds for a CronJob, job occurrences have no deadline.
If the .
spec.startingDeadlineSeconds field is set (no null), the CronJob handler measures the time between when a job is expected to be created and now. If the difference is greater than that limit, it will skip this execution.
For example, if set to 200
, allows you to create a job up to 200 seconds after the actual schedule.
The .spec.concurrencyPolicy field is also optional. Specifies how to handle concurrent executions of a job created by this CronJob. The specification can specify only one of the following concurrency policies
😛 ermitir (default): CronJob allows concurrent execution of jobs Prohibit: CronJob does not allow concurrent executions; if it is time to run a new job and the execution of the previous job has not yet finished
- of the previous job is not yet finished
- CronJob replaces the execution of the currently running job with a new job run
skips the new job run Replace: If it is time to run a new job and the execution
Note that the concurrency policy only applies to jobs created by the same cron job. If there are multiple CronJobs, their respective jobs can always run simultaneously.
You can suspend job execution for a CronJob by setting the optional .spec.suspend field to true. The default value of the field is false.
This setting does not affect jobs that CronJob has already started.
If you set that field to true, all subsequent executions are suspended (remain scheduled, but the CronJob handler does not start jobs to run the tasks) until you unsuspend CronJob.
Job history limits
and .spec.failedJobsHistoryLimit fields are optional. These fields specify how many completed and failed jobs should be retained. By default, they are set to 3 and 1 respectively. Setting a limit to 0 corresponds to not keeping any of the corresponding job types after they are finished.
For another way to clean up jobs automatically, see Clean up automatically completed jobs.
For CronJobs with no time zone specified, the kube-controller-manager interprets the schedules relative to your local time zone.
You can specify a time zone
for a CronJob by setting .spec.timeZone to the name of a valid time zone. For example, setting .spec.timeZone: “Etc/UTC” instructs Kubernetes to interpret the schedule relative to Coordinated Universal Time.
A time zone database
from the Go standard library is included in binaries and used as a fallback in case an external database is unavailable on the system
CronJob limitations Unsupported
specification The implementation of the CronJob API in Kubernetes 1.27 allows you to set the .spec.schedule field to include a time zone; for example: CRON_TZ=
UTC * * * * * or TZ=UTC * * * * *.
Specifying a time zone that way is not officially supported (and never has been).
If you try to set a schedule that includes TZ or CRON_TZ time zone specification, Kubernetes reports a warning to the customer. Future versions of Kubernetes will avoid setting the unofficial time zone mechanism entirely.
By design, a CronJob contains a template for new jobs. If you modify an existing CronJob, the changes you make are applied to new jobs that start running after the modification is complete. The jobs (and their Pods) that have already started continue to run unchanged. That is, CronJob does not update existing jobs, even if they remain running.
A CronJob object creates a Job object approximately once per hour of execution of its schedule. The schedule is approximate because there are certain circumstances in which two jobs can be created or no job can be created at all. Kubernetes tries to avoid those situations, but it doesn’t prevent them completely. Therefore, the jobs you define must be idempotent.
If startingDeadlineSeconds is set to a large value or left unset (default) and if concurrencyPolicy is set to Allow, jobs will always run at least once.
For each CronJob, the CronJob Controller checks how many schedules you missed in duration from your last scheduled hour until now. If there are more than 100 missed schedules, then it does not start the job and logs the error.
Unable to determine whether the job needs to be started. Too many missed start times (> 100). Set or decrease .spec.startingDeadlineSeconds or check the clock bias.
It is important to note that if the startingDeadlineSeconds field is set (not nil), the handler counts how many lost jobs occurred from the startingDeadlineSeconds value so far instead of from the last scheduled time so far. For example, if startingDeadlineSeconds is 200, the controller counts how many lost jobs occurred in the last 200 seconds.
A CronJob is counted as lost if it could not be created at the scheduled time. For example, if concurrencyPolicy is set to Forbid and an attempt was made to schedule a CronJob when a previous schedule was still running, it would count as lost.
For example, suppose a CronJob is configured to schedule a new job every minute starting at 08:30:00 and its startingDeadlineSeconds field is not set. If the CronJob controller is down from 08:29:00 to 10:21:00, the job will not start as the number of lost jobs that missed their schedule is greater than 100.
To further illustrate this concept, suppose a CronJob is set to schedule a new job every minute starting at 08:30:00, and its startingDeadlineSeconds is set to 200 seconds. If the CronJob handler is inactive for the same period as the previous example (08:29:00 to 10:21:00), the job will continue to start at 10:22:00. This happens when the controller now checks how many missed schedules occurred in the last 200 seconds (i.e. 3 missed schedules), rather than from the last scheduled time until now.
The CronJob is only responsible for creating jobs that match your schedule, and the job in turn is responsible for managing the pods it represents.
Learn about Pods and Jobs,
- two concepts on which CronJobs is based
- spec.schedule fields
- For instructions on how to create and work with CronJobs, and for an example of a CronJob manifest, see Running Automated Tasks with CronJobs. CronJob
- is part of the Kubernetes REST API. Read the CronJob API reference for more details.
. Read about the detailed formatting of CronJob’s .