Skip to content

Commit 83d7d4e

Browse files
authored
Merge pull request #38312 from cjc7373/cronjob-improve
CronJob topics improvement
2 parents 4fba599 + 988505d commit 83d7d4e

File tree

2 files changed

+130
-164
lines changed

2 files changed

+130
-164
lines changed

content/en/docs/concepts/workloads/controllers/cron-jobs.md

Lines changed: 129 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,13 @@ weight: 80
1414

1515
A _CronJob_ creates {{< glossary_tooltip term_id="job" text="Jobs" >}} on a repeating schedule.
1616

17-
One CronJob object is like one line of a _crontab_ (cron table) file. It runs a job periodically
18-
on a given schedule, written in [Cron](https://en.wikipedia.org/wiki/Cron) format.
17+
CronJob is meant for performing regular scheduled actions such as backups, report generation,
18+
and so on. One CronJob object is like one line of a _crontab_ (cron table) file on a
19+
Unix system. It runs a job periodically on a given schedule, written in
20+
[Cron](https://en.wikipedia.org/wiki/Cron) format.
1921

20-
{{< caution >}}
21-
All **CronJob** `schedule:` times are based on the timezone of the
22-
{{< glossary_tooltip term_id="kube-controller-manager" text="kube-controller-manager" >}}.
23-
24-
If your control plane runs the kube-controller-manager in Pods or bare
25-
containers, the timezone set for the kube-controller-manager container determines the timezone
26-
that the cron job controller uses.
27-
{{< /caution >}}
28-
29-
{{< caution >}}
30-
The [v1 CronJob API](/docs/reference/kubernetes-api/workload-resources/cron-job-v1/)
31-
does not officially support setting timezone as explained above.
32-
33-
Setting variables such as `CRON_TZ` or `TZ` is not officially supported by the Kubernetes project.
34-
`CRON_TZ` or `TZ` is an implementation detail of the internal library being used
35-
for parsing and calculating the next Job creation time. Any usage of it is not
36-
recommended in a production cluster.
37-
{{< /caution >}}
22+
CronJobs have limitations and idiosyncrasies.
23+
For example, in certain circumstances, a single CronJob can create multiple concurrent Jobs. See the [limitations](#cron-job-limitations) below.
3824

3925
When the control plane creates new Jobs and (indirectly) Pods for a CronJob, the `.metadata.name`
4026
of the CronJob is part of the basis for naming those Pods. The name of a CronJob must be a valid
@@ -48,15 +34,7 @@ characters. This is because the CronJob controller will automatically append
4834
length of a Job name is no more than 63 characters.
4935

5036
<!-- body -->
51-
52-
## CronJob
53-
54-
CronJobs are meant for performing regular scheduled actions such as backups,
55-
report generation, and so on. Each of those tasks should be configured to recur
56-
indefinitely (for example: once a day / week / month); you can define the point
57-
in time within that interval when the job should start.
58-
59-
### Example
37+
## Example
6038

6139
This example CronJob manifest prints the current time and a hello message every minute:
6240

@@ -65,7 +43,9 @@ This example CronJob manifest prints the current time and a hello message every
6543
([Running Automated Tasks with a CronJob](/docs/tasks/job/automated-tasks-with-cron-jobs/)
6644
takes you through this example in more detail).
6745

68-
### Cron schedule syntax
46+
## Writing a CronJob spec
47+
### Schedule syntax
48+
The `.spec.schedule` field is required. The value of that field follows the [Cron](https://en.wikipedia.org/wiki/Cron) syntax:
6949

7050
```
7151
# ┌───────────── minute (0 - 59)
@@ -79,6 +59,24 @@ takes you through this example in more detail).
7959
# * * * * *
8060
```
8161

62+
For example, `0 0 13 * 5` states that the task must be started every Friday at midnight, as well as on the 13th of each month at midnight.
63+
64+
The format also includes extended "Vixie cron" step values. As explained in the
65+
[FreeBSD manual](https://www.freebsd.org/cgi/man.cgi?crontab%285%29):
66+
67+
> Step values can be used in conjunction with ranges. Following a range
68+
> with `/<number>` specifies skips of the number's value through the
69+
> range. For example, `0-23/2` can be used in the hours field to specify
70+
> command execution every other hour (the alternative in the V7 standard is
71+
> `0,2,4,6,8,10,12,14,16,18,20,22`). Steps are also permitted after an
72+
> asterisk, so if you want to say "every two hours", just use `*/2`.
73+
74+
{{< note >}}
75+
A question mark (`?`) in the schedule has the same meaning as an asterisk `*`, that is,
76+
it stands for any of available value for a given field.
77+
{{< /note >}}
78+
79+
Other than the standard syntax, some macros like `@monthly` can also be used:
8280

8381
| Entry | Description | Equivalent to |
8482
| ------------- | ------------- |------------- |
@@ -88,17 +86,83 @@ takes you through this example in more detail).
8886
| @daily (or @midnight) | Run once a day at midnight | 0 0 * * * |
8987
| @hourly | Run once an hour at the beginning of the hour | 0 * * * * |
9088

89+
To generate CronJob schedule expressions, you can also use web tools like [crontab.guru](https://crontab.guru/).
90+
91+
### Job template
9192

93+
The `.spec.jobTemplate` defines a template for the Jobs that the CronJob creates, and it is required.
94+
It has exactly the same schema as a [Job](/docs/concepts/workloads/controllers/job/), except that
95+
it is nested and does not have an `apiVersion` or `kind`.
96+
You can specify common metadata for the templated Jobs, such as
97+
{{< glossary_tooltip text="labels" term_id="label" >}} or
98+
{{< glossary_tooltip text="annotations" term_id="annotation" >}}.
99+
For information about writing a Job `.spec`, see [Writing a Job Spec](/docs/concepts/workloads/controllers/job/#writing-a-job-spec).
92100

93-
For example, the line below states that the task must be started every Friday at midnight, as well as on the 13th of each month at midnight:
101+
### Deadline for delayed job start {#starting-deadline}
94102

95-
`0 0 13 * 5`
103+
The `.spec.startingDeadlineSeconds` field is optional.
104+
This field defines a deadline (in whole seconds) for starting the Job, if that Job misses its scheduled time
105+
for any reason.
96106

97-
To generate CronJob schedule expressions, you can also use web tools like [crontab.guru](https://crontab.guru/).
107+
After missing the deadline, the CronJob skips that instance of the Job (future occurrences are still scheduled).
108+
For example, if you have a backup job that runs twice a day, you might allow it to start up to 8 hours late,
109+
but no later, because a backup taken any later wouldn't be useful: you would instead prefer to wait for
110+
the next scheduled run.
111+
112+
For Jobs that miss their configured deadline, Kubernetes treats them as failed Jobs.
113+
If you don't specify `startingDeadlineSeconds` for a CronJob, the Job occurrences have no deadline.
114+
115+
If the `.spec.startingDeadlineSeconds` field is set (not null), the CronJob
116+
controller measures the time between when a job is expected to be created and
117+
now. If the difference is higher than that limit, it will skip this execution.
118+
119+
For example, if it is set to `200`, it allows a job to be created for up to 200
120+
seconds after the actual schedule.
121+
122+
### Concurrency policy
123+
124+
The `.spec.concurrencyPolicy` field is also optional.
125+
It specifies how to treat concurrent executions of a job that is created by this CronJob.
126+
The spec may specify only one of the following concurrency policies:
127+
128+
* `Allow` (default): The CronJob allows concurrently running jobs
129+
* `Forbid`: The CronJob does not allow concurrent runs; if it is time for a new job run and the
130+
previous job run hasn't finished yet, the CronJob skips the new job run
131+
* `Replace`: If it is time for a new job run and the previous job run hasn't finished yet, the
132+
CronJob replaces the currently running job run with a new job run
133+
134+
Note that concurrency policy only applies to the jobs created by the same cron job.
135+
If there are multiple CronJobs, their respective jobs are always allowed to run concurrently.
98136

99-
## Time zones
137+
### Schedule suspension
100138

101-
For CronJobs with no time zone specified, the kube-controller-manager interprets schedules relative to its local time zone.
139+
You can suspend execution of Jobs for a CronJob, by setting the optional `.spec.suspend` field
140+
to true. The field defaults to false.
141+
142+
This setting does _not_ affect Jobs that the CronJob has already started.
143+
144+
If you do set that field to true, all subsequent executions are suspended (they remain
145+
scheduled, but the CronJob controller does not start the Jobs to run the tasks) until
146+
you unsuspend the CronJob.
147+
148+
{{< caution >}}
149+
Executions that are suspended during their scheduled time count as missed jobs.
150+
When `.spec.suspend` changes from `true` to `false` on an existing CronJob without a
151+
[starting deadline](#starting-deadline), the missed jobs are scheduled immediately.
152+
{{< /caution >}}
153+
154+
### Jobs history limits
155+
156+
The `.spec.successfulJobsHistoryLimit` and `.spec.failedJobsHistoryLimit` fields are optional.
157+
These fields specify how many completed and failed jobs should be kept.
158+
By default, they are set to 3 and 1 respectively. Setting a limit to `0` corresponds to keeping
159+
none of the corresponding kind of jobs after they finish.
160+
161+
For another way to clean up jobs automatically, see [Clean up finished jobs automatically](/docs/concepts/workloads/controllers/job/#clean-up-finished-jobs-automatically).
162+
163+
### Time zones
164+
165+
For CronJobs with no time zone specified, the {{< glossary_tooltip term_id="kube-controller-manager" text="kube-controller-manager" >}} interprets schedules relative to its local time zone.
102166

103167
{{< feature-state for_k8s_version="v1.25" state="beta" >}}
104168

@@ -107,16 +171,39 @@ you can specify a time zone for a CronJob (if you don't enable that feature gate
107171
Kubernetes that does not have experimental time zone support, all CronJobs in your cluster have an unspecified
108172
timezone).
109173

110-
When you have the feature enabled, you can set `spec.timeZone` to the name of a valid [time zone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). For example, setting
111-
`spec.timeZone: "Etc/UTC"` instructs Kubernetes to interpret the schedule relative to Coordinated Universal Time.
174+
When you have the feature enabled, you can set `.spec.timeZone` to the name of a valid [time zone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). For example, setting
175+
`.spec.timeZone: "Etc/UTC"` instructs Kubernetes to interpret the schedule relative to Coordinated Universal Time.
176+
177+
{{< caution >}}
178+
The implementation of the CronJob API in Kubernetes {{< skew currentVersion >}} lets you set
179+
the `.spec.schedule` field to include a timezone; for example: `CRON_TZ=UTC * * * * *`
180+
or `TZ=UTC * * * * *`.
181+
182+
Specifying a timezone that way is **not officially supported** (and never has been).
183+
184+
If you try to set a schedule that includes `TZ` or `CRON_TZ` timezone specification,
185+
Kubernetes reports a [warning](/blog/2020/09/03/warnings/) to the client.
186+
Future versions of Kubernetes might not implement that unofficial timezone mechanism at all.
187+
{{< /caution >}}
112188

113189
A time zone database from the Go standard library is included in the binaries and used as a fallback in case an external database is not available on the system.
114190

115191
## CronJob limitations {#cron-job-limitations}
116192

117-
A cron job creates a job object _about_ once per execution time of its schedule. We say "about" because there
118-
are certain circumstances where two jobs might be created, or no job might be created. We attempt to make these rare,
119-
but do not completely prevent them. Therefore, jobs should be _idempotent_.
193+
### Modifying a CronJob
194+
By design, a CronJob contains a template for _new_ Jobs.
195+
If you modify an existing CronJob, the changes you make will apply to new Jobs that
196+
start to run after your modification is complete. Jobs (and their Pods) that have already
197+
started continue to run without changes.
198+
That is, the CronJob does _not_ update existing Jobs, even if those remain running.
199+
200+
### Job creation
201+
202+
A CronJob creates a Job object approximately once per execution time of its schedule.
203+
The scheduling is approximate because there
204+
are certain circumstances where two Jobs might be created, or no Job might be created.
205+
Kubernetes tries to avoid those situations, but do not completely prevent them. Therefore,
206+
the Jobs that you define should be _idempotent_.
120207

121208
If `startingDeadlineSeconds` is set to a large value or left unset (the default)
122209
and if `concurrencyPolicy` is set to `Allow`, the jobs will always run
@@ -148,32 +235,16 @@ be down for the same period as the previous example (`08:29:00` to `10:21:00`,)
148235
The CronJob is only responsible for creating Jobs that match its schedule, and
149236
the Job in turn is responsible for the management of the Pods it represents.
150237

151-
## Controller version {#new-controller}
152-
153-
Starting with Kubernetes v1.21 the second version of the CronJob controller
154-
is the default implementation. To disable the default CronJob controller
155-
and use the original CronJob controller instead, pass the `CronJobControllerV2`
156-
[feature gate](/docs/reference/command-line-tools-reference/feature-gates/)
157-
flag to the {{< glossary_tooltip term_id="kube-controller-manager" text="kube-controller-manager" >}},
158-
and set this flag to `false`. For example:
159-
160-
```
161-
--feature-gates="CronJobControllerV2=false"
162-
```
163-
164-
165238
## {{% heading "whatsnext" %}}
166239

167240
* Learn about [Pods](/docs/concepts/workloads/pods/) and
168241
[Jobs](/docs/concepts/workloads/controllers/job/), two concepts
169242
that CronJobs rely upon.
170-
* Read about the [format](https://pkg.go.dev/github.com/robfig/cron/v3#hdr-CRON_Expression_Format)
243+
* Read about the detailed [format](https://pkg.go.dev/github.com/robfig/cron/v3#hdr-CRON_Expression_Format)
171244
of CronJob `.spec.schedule` fields.
172245
* For instructions on creating and working with CronJobs, and for an example
173246
of a CronJob manifest,
174247
see [Running automated tasks with CronJobs](/docs/tasks/job/automated-tasks-with-cron-jobs/).
175-
* For instructions to clean up failed or completed jobs automatically,
176-
see [Clean up Jobs automatically](/docs/concepts/workloads/controllers/job/#clean-up-finished-jobs-automatically)
177248
* `CronJob` is part of the Kubernetes REST API.
178249
Read the {{< api-reference page="workload-resources/cron-job-v1" >}}
179-
object definition to understand the API for Kubernetes cron jobs.
250+
API reference for more details.

content/en/docs/tasks/job/automated-tasks-with-cron-jobs.md

Lines changed: 1 addition & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,7 @@ weight: 10
99

1010
<!-- overview -->
1111

12-
You can use a {{< glossary_tooltip text="CronJob" term_id="cronjob" >}} to run {{< glossary_tooltip text="Jobs" term_id="job" >}}
13-
on a time-based schedule.
14-
These automated jobs run like [Cron](https://en.wikipedia.org/wiki/Cron) tasks on a Linux or UNIX system.
15-
16-
Cron jobs are useful for creating periodic and recurring tasks, like running backups or sending emails.
17-
Cron jobs can also schedule individual tasks for a specific time, such as if you want to schedule a job for a low activity period.
18-
19-
Cron jobs have limitations and idiosyncrasies.
20-
For example, in certain circumstances, a single cron job can create multiple jobs.
21-
Therefore, jobs should be idempotent.
22-
23-
For more limitations, see [CronJobs](/docs/concepts/workloads/controllers/cron-jobs).
12+
This page shows how to run automated tasks using Kubernetes {{< glossary_tooltip text="CronJob" term_id="cronjob" >}} object.
2413

2514
## {{% heading "prerequisites" %}}
2615

@@ -123,97 +112,3 @@ kubectl delete cronjob hello
123112

124113
Deleting the cron job removes all the jobs and pods it created and stops it from creating additional jobs.
125114
You can read more about removing jobs in [garbage collection](/docs/concepts/architecture/garbage-collection/).
126-
127-
## Writing a CronJob Spec {#writing-a-cron-job-spec}
128-
129-
As with all other Kubernetes objects, a CronJob must have `apiVersion`, `kind`, and `metadata` fields.
130-
For more information about working with Kubernetes objects and their
131-
{{< glossary_tooltip text="manifests" term_id="manifest" >}}, see the
132-
[managing resources](/docs/concepts/cluster-administration/manage-deployment/),
133-
and [using kubectl to manage resources](/docs/concepts/overview/working-with-objects/object-management/) documents.
134-
135-
Each manifest for a CronJob also needs a [`.spec`](/docs/concepts/overview/working-with-objects/kubernetes-objects/#object-spec-and-status) section.
136-
137-
{{< note >}}
138-
If you modify a CronJob, the changes you make will apply to new jobs that start to run after your modification
139-
is complete. Jobs (and their Pods) that have already started continue to run without changes.
140-
That is, the CronJob does _not_ update existing jobs, even if those remain running.
141-
{{< /note >}}
142-
143-
### Schedule
144-
145-
The `.spec.schedule` is a required field of the `.spec`.
146-
It takes a [Cron](https://en.wikipedia.org/wiki/Cron) format string, such as `0 * * * *` or `@hourly`,
147-
as schedule time of its jobs to be created and executed.
148-
149-
The format also includes extended "Vixie cron" step values. As explained in the
150-
[FreeBSD manual](https://www.freebsd.org/cgi/man.cgi?crontab%285%29):
151-
152-
> Step values can be used in conjunction with ranges. Following a range
153-
> with `/<number>` specifies skips of the number's value through the
154-
> range. For example, `0-23/2` can be used in the hours field to specify
155-
> command execution every other hour (the alternative in the V7 standard is
156-
> `0,2,4,6,8,10,12,14,16,18,20,22`). Steps are also permitted after an
157-
> asterisk, so if you want to say "every two hours", just use `*/2`.
158-
159-
{{< note >}}
160-
A question mark (`?`) in the schedule has the same meaning as an asterisk `*`, that is,
161-
it stands for any of available value for a given field.
162-
{{< /note >}}
163-
164-
### Job Template
165-
166-
The `.spec.jobTemplate` is the template for the job, and it is required.
167-
It has exactly the same schema as a [Job](/docs/concepts/workloads/controllers/job/), except that
168-
it is nested and does not have an `apiVersion` or `kind`.
169-
For information about writing a job `.spec`, see [Writing a Job Spec](/docs/concepts/workloads/controllers/job/#writing-a-job-spec).
170-
171-
### Starting Deadline
172-
173-
The `.spec.startingDeadlineSeconds` field is optional.
174-
It stands for the deadline in seconds for starting the job if it misses its scheduled time for any reason.
175-
After the deadline, the cron job does not start the job.
176-
Jobs that do not meet their deadline in this way count as failed jobs.
177-
If this field is not specified, the jobs have no deadline.
178-
179-
If the `.spec.startingDeadlineSeconds` field is set (not null), the CronJob
180-
controller measures the time between when a job is expected to be created and
181-
now. If the difference is higher than that limit, it will skip this execution.
182-
183-
For example, if it is set to `200`, it allows a job to be created for up to 200
184-
seconds after the actual schedule.
185-
186-
### Concurrency Policy
187-
188-
The `.spec.concurrencyPolicy` field is also optional.
189-
It specifies how to treat concurrent executions of a job that is created by this cron job.
190-
The spec may specify only one of the following concurrency policies:
191-
192-
* `Allow` (default): The cron job allows concurrently running jobs
193-
* `Forbid`: The cron job does not allow concurrent runs; if it is time for a new job run and the
194-
previous job run hasn't finished yet, the cron job skips the new job run
195-
* `Replace`: If it is time for a new job run and the previous job run hasn't finished yet, the
196-
cron job replaces the currently running job run with a new job run
197-
198-
Note that concurrency policy only applies to the jobs created by the same cron job.
199-
If there are multiple cron jobs, their respective jobs are always allowed to run concurrently.
200-
201-
### Suspend
202-
203-
The `.spec.suspend` field is also optional.
204-
If it is set to `true`, all subsequent executions are suspended.
205-
This setting does not apply to already started executions.
206-
Defaults to false.
207-
208-
{{< caution >}}
209-
Executions that are suspended during their scheduled time count as missed jobs.
210-
When `.spec.suspend` changes from `true` to `false` on an existing cron job without a
211-
[starting deadline](#starting-deadline), the missed jobs are scheduled immediately.
212-
{{< /caution >}}
213-
214-
### Jobs History Limits
215-
216-
The `.spec.successfulJobsHistoryLimit` and `.spec.failedJobsHistoryLimit` fields are optional.
217-
These fields specify how many completed and failed jobs should be kept.
218-
By default, they are set to 3 and 1 respectively. Setting a limit to `0` corresponds to keeping
219-
none of the corresponding kind of jobs after they finish.

0 commit comments

Comments
 (0)