Kubernetes CronJob schedules
Five fields in .spec.schedule, parsed by the Go library robfig/cron. It looks like Unix cron and mostly is. The differences live at the edges.
At 03:00, on Mondays.
Next 10 runs
Clock changes
In your config
In the other dialects
“Same schedule” means the same clock times. Schedulers still treat a clock change differently, as the table on the home page shows.
Keyboard: / edit the expression, 1 to 6 change dialect, t time zone, n next clock change, c copy the link, Esc leave a field.
Fields
| Field | Values | Special characters |
|---|---|---|
| Minute | 0–59 | * , - / ? |
| Hour | 0–23 | * , - / ? |
| Day of month | 1–31 | * , - / ? |
| Month | 1–12 or jan–dec | * , - / ? |
| Day of week | 0–6, Sunday to Saturday, or sun–sat | * , - / ? |
Special characters
?- The same as
*. /- Steps over a range or star:
0-23/2,*/2. The parser also accepts5/15, meaning 5 through the top of the field. @hourly- Macros:
@yearly,@annually,@monthly,@weekly,@daily,@midnight,@hourly.@every 1h30mis accepted by the library but not listed in the Kubernetes docs.
The two day fields
If either day field is a star, both must match, which in practice means only the other one counts. If both are restricted, either can match. A stepped star such as */2 counts as restricted when the step is above 1, unlike Vixie cron.
Time zones
With no .spec.timeZone, the kube-controller-manager’s local zone. Set .spec.timeZone to an IANA name such as Etc/UTC; this has been stable since v1.27.
Clock changes
The Kubernetes docs do not cover this, so the behaviour comes from robfig/cron, whose docs warn that jobs in a leap-ahead transition do not run. Its tests confirm the rest: a time in the repeated hour runs twice. This tool ports the library’s Next loop and compares it with the real thing, which also reproduces a quirk: in Australia/Lord_Howe, whose clocks move by 30 minutes, a daily midnight job loses the midnight after the fall-back.
Gotchas
- No
7for Sunday. The range stops at 6. - Backwards ranges such as
5-1are rejected. CRON_TZandTZinside.spec.schedulefail validation. Use.spec.timeZone.- A Job is created roughly once per schedule. Kubernetes says there can be two or none, so Jobs should be idempotent.
- If more than 100 schedules were missed since the last run, the CronJob does not start the Job and logs
too many missed start times. Setting.spec.startingDeadlineSecondschanges the window that is counted. - A
startingDeadlineSecondsunder 10 can mean the CronJob is never scheduled, because the controller only checks every 10 seconds. concurrencyPolicy: Forbidskips a run while the previous one is still going. Skipped runs count as missed.- The library gives up if nothing matches in five years, so
0 0 31 2 *has no next run at all.
Examples to try
- 0 3 * * 1Mondays at 03:00, the docs’ exampleAt 03:00, on Mondays
- */10 * * * *Every 10 minutesEvery 10 minutes
- 0 0 13 * 513th of the month, or any FridayAt 00:00, on the 13th of the month, or on Fridays
- 0-23/2 * * * *Every other minute for the first 24 minutesAt minutes 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 and 22
- @dailyMidnight every dayAt 00:00