Rename ScheduledJob to CronJobs

This commit is contained in:
Maciej Szulik 2017-02-08 13:12:44 +01:00
parent 09ef55a496
commit c333b744eb
1 changed files with 51 additions and 51 deletions

View File

@ -1,8 +1,8 @@
# ScheduledJob Controller # CronJob Controller (previously ScheduledJob)
## Abstract ## Abstract
A proposal for implementing a new controller - ScheduledJob controller - which A proposal for implementing a new controller - CronJob controller - which
will be responsible for managing time based jobs, namely: will be responsible for managing time based jobs, namely:
* once at a specified point in time, * once at a specified point in time,
* repeatedly at a specified point in time. * repeatedly at a specified point in time.
@ -23,20 +23,20 @@ There are also similar solutions available, already:
## Motivation ## Motivation
ScheduledJobs are needed for performing all time-related actions, namely backups, CronJobs are needed for performing all time-related actions, namely backups,
report generation and the like. Each of these tasks should be allowed to run report generation and the like. Each of these tasks should be allowed to run
repeatedly (once a day/month, etc.) or once at a given point in time. repeatedly (once a day/month, etc.) or once at a given point in time.
## Design Overview ## Design Overview
Users create a ScheduledJob object. One ScheduledJob object Users create a CronJob object. One CronJob object
is like one line of a crontab file. It has a schedule of when to run, is like one line of a crontab file. It has a schedule of when to run,
in [Cron](https://en.wikipedia.org/wiki/Cron) format. in [Cron](https://en.wikipedia.org/wiki/Cron) format.
The ScheduledJob controller creates a Job object [Job](job.md) The CronJob controller creates a Job object [Job](job.md)
about once per execution time of the scheduled (e.g. once per about once per execution time of the schedule (e.g. once per
day for a daily schedule.) We say "about" because there are certain day for a daily schedule.) We say "about" because there are certain
circumstances where two jobs might be created, or no job might be circumstances where two jobs might be created, or no job might be
created. We attempt to make these rare, but do not completely prevent created. We attempt to make these rare, but do not completely prevent
@ -44,45 +44,45 @@ them. Therefore, Jobs should be idempotent.
The Job object is responsible for any retrying of Pods, and any parallelism The Job object is responsible for any retrying of Pods, and any parallelism
among pods it creates, and determining the success or failure of the set of among pods it creates, and determining the success or failure of the set of
pods. The ScheduledJob does not examine pods at all. pods. The CronJob does not examine pods at all.
### ScheduledJob resource ### CronJob resource
The new `ScheduledJob` object will have the following contents: The new `CronJob` object will have the following contents:
```go ```go
// ScheduledJob represents the configuration of a single scheduled job. // CronJob represents the configuration of a single cron job.
type ScheduledJob struct { type CronJob struct {
TypeMeta TypeMeta
ObjectMeta ObjectMeta
// Spec is a structure defining the expected behavior of a job, including the schedule. // Spec is a structure defining the expected behavior of a job, including the schedule.
Spec ScheduledJobSpec Spec CronJobSpec
// Status is a structure describing current status of a job. // Status is a structure describing current status of a job.
Status ScheduledJobStatus Status CronJobStatus
} }
// ScheduledJobList is a collection of scheduled jobs. // CronJobList is a collection of cron jobs.
type ScheduledJobList struct { type CronJobList struct {
TypeMeta TypeMeta
ListMeta ListMeta
Items []ScheduledJob Items []CronJob
} }
``` ```
The `ScheduledJobSpec` structure is defined to contain all the information how the actual The `CronJobSpec` structure is defined to contain all the information how the actual
job execution will look like, including the `JobSpec` from [Job API](job.md) job execution will look like, including the `JobSpec` from [Job API](job.md)
and the schedule in [Cron](https://en.wikipedia.org/wiki/Cron) format. This implies and the schedule in [Cron](https://en.wikipedia.org/wiki/Cron) format. This implies
that each ScheduledJob execution will be created from the JobSpec actual at a point that each CronJob execution will be created from the JobSpec actual at a point
in time when the execution will be started. This also implies that any changes in time when the execution will be started. This also implies that any changes
to ScheduledJobSpec will be applied upon subsequent execution of a job. to CronJobSpec will be applied upon subsequent execution of a job.
```go ```go
// ScheduledJobSpec describes how the job execution will look like and when it will actually run. // CronJobSpec describes how the job execution will look like and when it will actually run.
type ScheduledJobSpec struct { type CronJobSpec struct {
// Schedule contains the schedule in Cron format, see https://en.wikipedia.org/wiki/Cron. // Schedule contains the schedule in Cron format, see https://en.wikipedia.org/wiki/Cron.
Schedule string Schedule string
@ -99,12 +99,12 @@ type ScheduledJobSpec struct {
Suspend bool Suspend bool
// JobTemplate is the object that describes the job that will be created when // JobTemplate is the object that describes the job that will be created when
// executing a ScheduledJob. // executing a CronJob.
JobTemplate *JobTemplateSpec JobTemplate *JobTemplateSpec
} }
// JobTemplateSpec describes of the Job that will be created when executing // JobTemplateSpec describes of the Job that will be created when executing
// a ScheduledJob, including its standard metadata. // a CronJob, including its standard metadata.
type JobTemplateSpec struct { type JobTemplateSpec struct {
ObjectMeta ObjectMeta
@ -119,7 +119,7 @@ type JobTemplateSpec struct {
type ConcurrencyPolicy string type ConcurrencyPolicy string
const ( const (
// AllowConcurrent allows ScheduledJobs to run concurrently. // AllowConcurrent allows CronJobs to run concurrently.
AllowConcurrent ConcurrencyPolicy = "Allow" AllowConcurrent ConcurrencyPolicy = "Allow"
// ForbidConcurrent forbids concurrent runs, skipping next run if previous // ForbidConcurrent forbids concurrent runs, skipping next run if previous
@ -131,13 +131,13 @@ const (
) )
``` ```
`ScheduledJobStatus` structure is defined to contain information about scheduled `CronJobStatus` structure is defined to contain information about cron
job executions. The structure holds a list of currently running job instances job executions. The structure holds a list of currently running job instances
and additional information about overall successful and unsuccessful job executions. and additional information about overall successful and unsuccessful job executions.
```go ```go
// ScheduledJobStatus represents the current state of a Job. // CronJobStatus represents the current state of a Job.
type ScheduledJobStatus struct { type CronJobStatus struct {
// Active holds pointers to currently running jobs. // Active holds pointers to currently running jobs.
Active []ObjectReference Active []ObjectReference
@ -159,7 +159,7 @@ Users must use a generated selector for the job.
TODO for beta: forbid manual selector since that could cause confusing between TODO for beta: forbid manual selector since that could cause confusing between
subsequent jobs. subsequent jobs.
### Running ScheduledJobs using kubectl ### Running CronJobs using kubectl
A user should be able to easily start a Scheduled Job using `kubectl` (similarly A user should be able to easily start a Scheduled Job using `kubectl` (similarly
to running regular jobs). For example to run a job with a specified schedule, to running regular jobs). For example to run a job with a specified schedule,
@ -178,21 +178,21 @@ In the above example:
## Fields Added to Job Template ## Fields Added to Job Template
When the controller creates a Job from the JobTemplateSpec in the ScheduledJob, it When the controller creates a Job from the JobTemplateSpec in the CronJob, it
adds the following fields to the Job: adds the following fields to the Job:
- a name, based on the ScheduledJob's name, but with a suffix to distinguish - a name, based on the CronJob's name, but with a suffix to distinguish
multiple executions, which may overlap. multiple executions, which may overlap.
- the standard created-by annotation on the Job, pointing to the SJ that created it - the standard created-by annotation on the Job, pointing to the SJ that created it
The standard key is `kubernetes.io/created-by`. The value is a serialized JSON object, like The standard key is `kubernetes.io/created-by`. The value is a serialized JSON object, like
`{ "kind":"SerializedReference","apiVersion":"v1","reference":{"kind":"ScheduledJob","namespace":"default",` `{ "kind":"SerializedReference","apiVersion":"v1","reference":{"kind":"CronJob","namespace":"default",`
`"name":"nightly-earnings-report","uid":"5ef034e0-1890-11e6-8935-42010af0003e","apiVersion":...` `"name":"nightly-earnings-report","uid":"5ef034e0-1890-11e6-8935-42010af0003e","apiVersion":...`
This serialization contains the UID of the parent. This is used to match the Job to the SJ that created This serialization contains the UID of the parent. This is used to match the Job to the SJ that created
it. it.
## Updates to ScheduledJobs ## Updates to CronJobs
If the schedule is updated on a ScheduledJob, it will: If the schedule is updated on a CronJob, it will:
- continue to use the Status.Active list of jobs to detect conflicts. - continue to use the Status.Active list of jobs to detect conflicts.
- try to fulfill all recently-passed times for the new schedule, by starting - try to fulfill all recently-passed times for the new schedule, by starting
new jobs. But it will not try to fulfill times prior to the new jobs. But it will not try to fulfill times prior to the
@ -202,16 +202,16 @@ If the schedule is updated on a ScheduledJob, it will:
- Example: If you have a schedule to run every hour, change that to 30-minutely, at 31 minutes past the hour, - Example: If you have a schedule to run every hour, change that to 30-minutely, at 31 minutes past the hour,
one run will be started immediately for the starting time that has just passed. one run will be started immediately for the starting time that has just passed.
If the job template of a ScheduledJob is updated, then future executions use the new template If the job template of a CronJob is updated, then future executions use the new template
but old ones still satisfy the schedule and are not re-run just because the template changed. but old ones still satisfy the schedule and are not re-run just because the template changed.
If you delete and replace a ScheduledJob with one of the same name, it will: If you delete and replace a CronJob with one of the same name, it will:
- not use any old Status.Active, and not consider any existing running or terminated jobs from the previous - not use any old Status.Active, and not consider any existing running or terminated jobs from the previous
ScheduledJob (with a different UID) at all when determining coflicts, what needs to be started, etc. CronJob (with a different UID) at all when determining coflicts, what needs to be started, etc.
- If there is an existing Job with the same time-based hash in its name (see below), then - If there is an existing Job with the same time-based hash in its name (see below), then
new instances of that job will not be able to be created. So, delete it if you want to re-run. new instances of that job will not be able to be created. So, delete it if you want to re-run.
with the same name as conflicts. with the same name as conflicts.
- not "re-run" jobs for "start times" before the creation time of the new ScheduledJobJob object. - not "re-run" jobs for "start times" before the creation time of the new CronJobJob object.
- not consider executions from the previous UID when making decisions about what executions to - not consider executions from the previous UID when making decisions about what executions to
start, or status, etc. start, or status, etc.
- lose the history of the old SJ. - lose the history of the old SJ.
@ -223,11 +223,11 @@ To preserve status, you can suspend the old one, and make one with a new name, o
### Starting Jobs in the face of controller failures ### Starting Jobs in the face of controller failures
If the process with the scheduledJob controller in it fails, If the process with the cronJob controller in it fails,
and takes a while to restart, the scheduledJob controller and takes a while to restart, the cronJob controller
may miss the time window and it is too late to start a job. may miss the time window and it is too late to start a job.
With a single scheduledJob controller process, we cannot give With a single cronJob controller process, we cannot give
very strong assurances about not missing starting jobs. very strong assurances about not missing starting jobs.
With a suggested HA configuration, there are multiple controller With a suggested HA configuration, there are multiple controller
@ -254,10 +254,10 @@ There are three problems here:
Multiple jobs might be created in the following sequence: Multiple jobs might be created in the following sequence:
1. scheduled job controller sends request to start Job J1 to fulfill start time T. 1. cron job controller sends request to start Job J1 to fulfill start time T.
1. the create request is accepted by the apiserver and enqueued but not yet written to etcd. 1. the create request is accepted by the apiserver and enqueued but not yet written to etcd.
1. scheduled job controller crashes 1. cron job controller crashes
1. new scheduled job controller starts, and lists the existing jobs, and does not see one created. 1. new cron job controller starts, and lists the existing jobs, and does not see one created.
1. it creates a new one. 1. it creates a new one.
1. the first one eventually gets written to etcd. 1. the first one eventually gets written to etcd.
1. there are now two jobs for the same start time. 1. there are now two jobs for the same start time.
@ -286,24 +286,24 @@ This is too hard to do for the alpha version. We will await user
feedback to see if the "at most once" property is needed in the beta version. feedback to see if the "at most once" property is needed in the beta version.
This is awkward but possible for a containerized application ensure on it own, as it needs This is awkward but possible for a containerized application ensure on it own, as it needs
to know what ScheduledJob name and Start Time it is from, and then record the attempt to know what CronJob name and Start Time it is from, and then record the attempt
in a shared storage system. We should ensure it could extract this data from its annotations in a shared storage system. We should ensure it could extract this data from its annotations
using the downward API. using the downward API.
## Name of Jobs ## Name of Jobs
A ScheduledJob creates one Job at each time when a Job should run. A CronJob creates one Job at each time when a Job should run.
Since there may be concurrent jobs, and since we might want to keep failed Since there may be concurrent jobs, and since we might want to keep failed
non-overlapping Jobs around as a debugging record, each Job created by the same ScheduledJob non-overlapping Jobs around as a debugging record, each Job created by the same CronJob
needs a distinct name. needs a distinct name.
To make the Jobs from the same ScheduledJob distinct, we could use a random string, To make the Jobs from the same CronJob distinct, we could use a random string,
in the way that pods have a `generateName`. For example, a scheduledJob named `nightly-earnings-report` in the way that pods have a `generateName`. For example, a cronJob named `nightly-earnings-report`
in namespace `ns1` might create a job `nightly-earnings-report-3m4d3`, and later create in namespace `ns1` might create a job `nightly-earnings-report-3m4d3`, and later create
a job called `nightly-earnings-report-6k7ts`. This is consistent with pods, but a job called `nightly-earnings-report-6k7ts`. This is consistent with pods, but
does not give the user much information. does not give the user much information.
Alternatively, we can use time as a uniquifier. For example, the same scheduledJob could Alternatively, we can use time as a uniquifier. For example, the same cronJob could
create a job called `nightly-earnings-report-2016-May-19`. create a job called `nightly-earnings-report-2016-May-19`.
However, for Jobs that run more than once per day, we would need to represent However, for Jobs that run more than once per day, we would need to represent
time as well as date. Standard date formats (e.g. RFC 3339) use colons for time. time as well as date. Standard date formats (e.g. RFC 3339) use colons for time.
@ -312,7 +312,7 @@ will annoy some users.
Also, date strings are much longer than random suffixes, which means that Also, date strings are much longer than random suffixes, which means that
the pods will also have long names, and that we are more likely to exceed the the pods will also have long names, and that we are more likely to exceed the
253 character name limit when combining the scheduled-job name, 253 character name limit when combining the cron-job name,
the time suffix, and pod random suffix. the time suffix, and pod random suffix.
One option would be to compute a hash of the nominal start time of the job, One option would be to compute a hash of the nominal start time of the job,
@ -331,5 +331,5 @@ Below are the possible future extensions to the Job controller:
types of resources. This relates to the work happening in [#18215](https://issues.k8s.io/18215). types of resources. This relates to the work happening in [#18215](https://issues.k8s.io/18215).
<!-- BEGIN MUNGE: GENERATED_ANALYTICS --> <!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/proposals/scheduledjob.md?pixel)]() [![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/proposals/cronjob.md?pixel)]()
<!-- END MUNGE: GENERATED_ANALYTICS --> <!-- END MUNGE: GENERATED_ANALYTICS -->