diff --git a/docs/user-guide/job.yaml b/docs/user-guide/job.yaml index c1c70082337..ece4512a8ac 100644 --- a/docs/user-guide/job.yaml +++ b/docs/user-guide/job.yaml @@ -1,16 +1,11 @@ -apiVersion: extensions/v1beta1 +apiVersion: batch/v1 kind: Job metadata: name: pi spec: - selector: - matchLabels: - app: pi template: metadata: name: pi - labels: - app: pi spec: containers: - name: pi diff --git a/docs/user-guide/jobs.md b/docs/user-guide/jobs.md index 5486acff8ec..41d7e630007 100644 --- a/docs/user-guide/jobs.md +++ b/docs/user-guide/jobs.md @@ -47,6 +47,8 @@ Documentation for other releases can be found at - [Controlling Parallelism](#controlling-parallelism) - [Handling Pod and Container Failures](#handling-pod-and-container-failures) - [Job Patterns](#job-patterns) + - [Advanced Usage](#advanced-usage) + - [Specifying your own pod selector](#specifying-your-own-pod-selector) - [Alternatives](#alternatives) - [Bare Pods](#bare-pods) - [Replication Controller](#replication-controller) @@ -76,19 +78,14 @@ It takes around 10s to complete. ```yaml -apiVersion: extensions/v1beta1 +apiVersion: batch/v1 kind: Job metadata: name: pi spec: - selector: - matchLabels: - app: pi template: metadata: name: pi - labels: - app: pi spec: containers: - name: pi @@ -170,21 +167,9 @@ Only a [`RestartPolicy`](pod-states.md) equal to `Never` or `OnFailure` are allo ### Pod Selector -The `.spec.selector` field is a label query over a set of pods. +The `.spec.selector` field is optional. In almost all cases you should not specify it. +See section [specifying your own pod selector](#specifying-your-own-pod-selector). -The `spec.selector` is an object consisting of two fields: -* `matchLabels` - works the same as the `.spec.selector` of a [ReplicationController](replication-controller.md) -* `matchExpressions` - allows to build more sophisticated selectors by specifying key, - list of values and an operator that relates the key and values. - -When the two are specified the result is ANDed. - -If `.spec.selector` is unspecified, `.spec.selector.matchLabels` will be defaulted to -`.spec.template.metadata.labels`. - -Also you should not normally create any pods whose labels match this selector, either directly, -via another Job, or via another controller such as ReplicationController. Otherwise, the Job will -think that those pods were created by it. Kubernetes will not stop you from doing this. ### Parallel Jobs @@ -323,6 +308,70 @@ Here, `W` is the number of work items. | Single Job with Static Work Assignment | W | any | +## Advanced Usage + +### Specifying your own pod selector + +Normally, when you create a job object, you do not specify `spec.selector`. +The system defaulting logic adds this field when the job is created. +It picks a selector value that will not overlap with any other jobs. + +However, in some cases, you might need to override this automatically set selector. +To do this, you can specify the `spec.selector` of the job. + +Be very careful when doing this. If you specify a label selector which is not +unique to the pods of that job, and which matches unrelated pods, then pods of the unrelated +job may be deleted, or this job may count other pods as completing it, or one or both +of the jobs may refuse to create pods or run to completion. If a non-unique selector is +chosen, then other controllers (e.g. ReplicationController) and their pods may behave +in unpredicatable ways too. Kubernetes will not stop you from making a mistake when +specifying `spec.selector`. + +Here is an example of a case when you might want to use this feature. + +Say job `old` is already running. You want existing pods +to keep running, but you want the rest of the pods it creates +to use a different pod template and for the job to have a new name. +You cannot update the job because these fields are not updatable. +Therefore, you delete job `old` but leave its pods +running, using `kubectl delete jobs/old-one --cascade=false`. +Before deleting it, you make a note of what selector it uses: + +``` +kind: Job +metadata: + name: old + ... +spec: + selector: + matchLabels: + job-uid: a8f3d00d-c6d2-11e5-9f87-42010af00002 + ... +``` + +Then you create a new job with name `new` and you explicitly specify the same selector. +Since the existing pods have label `job-uid=a8f3d00d-c6d2-11e5-9f87-42010af00002`, +they are controlled by job `new` as well. + +You need to specify `manualSelector: true` in the new job since you are not using +the selector that the system normally generates for you automatically. + +``` +kind: Job +metadata: + name: new + ... +spec: + manualSelector: true + selector: + matchLabels: + job-uid: a8f3d00d-c6d2-11e5-9f87-42010af00002 + ... +``` + +The new Job itself will have a different uid from `a8f3d00d-c6d2-11e5-9f87-42010af00002`. Setting +`manualSelector: true` tells the system to that you know what you are doing and to allow this +mismatch. ## Alternatives diff --git a/examples/job/expansions/README.md b/examples/job/expansions/README.md index 739755ccbf9..9b409080861 100644 --- a/examples/job/expansions/README.md +++ b/examples/job/expansions/README.md @@ -40,21 +40,18 @@ First, create a template of a Job object: ``` -apiVersion: extensions/v1beta1 +apiVersion: batch/v1 kind: Job metadata: name: process-item-$ITEM + labels: + jobgroup: jobexample spec: - selector: - matchLabels: - app: jobexample - item: $ITEM template: metadata: name: jobexample labels: - app: jobexample - item: $ITEM + jobgroup: jobexample spec: containers: - name: c @@ -75,12 +72,14 @@ In a real use case, the processing would be some substantial computation, such a of a movie, or processing a range of rows in a database. The "$ITEM" parameter would specify for example, the frame number or the row range. -This Job has two labels. The first label, `app=jobexample`, distinguishes this group of jobs from -other groups of jobs (these are not shown, but there might be other ones). This label -makes it convenient to operate on all the jobs in the group at once. The second label, with -key `item`, distinguishes individual jobs in the group. Each Job object needs to have -a unique label that no other job has. This is it. -Neither of these label keys are special to kubernetes -- you can pick your own label scheme. +This Job and its Pod template have a label: `jobgroup=jobexample`. There is nothing special +to the system about this label. This label +makes it convenient to operate on all the jobs in this group at once. +We also put the same label on the pod template so that we can check on all Pods of these Jobs +with a single command. +After the job is created, the system will add more labels that distinguish one Job's pods +from another Job's pods. +Note that the label key `jobgroup` is not special to Kubernetes. you can pick your own label scheme. Next, expand the template into multiple files, one for each item to be processed. @@ -113,27 +112,25 @@ job "process-item-cherry" created Now, check on the jobs: ```console -$ kubectl get jobs -l app=jobexample -L item -JOB CONTAINER(S) IMAGE(S) SELECTOR SUCCESSFUL ITEM -process-item-apple c busybox app in (jobexample),item in (apple) 1 apple -process-item-banana c busybox app in (jobexample),item in (banana) 1 banana -process-item-cherry c busybox app in (jobexample),item in (cherry) 1 cherry +$ kubectl get jobs -l app=jobexample +JOB CONTAINER(S) IMAGE(S) SELECTOR SUCCESSFUL +process-item-apple c busybox app in (jobexample),item in (apple) 1 +process-item-banana c busybox app in (jobexample),item in (banana) 1 +process-item-cherry c busybox app in (jobexample),item in (cherry) 1 ``` Here we use the `-l` option to select all jobs that are part of this group of jobs. (There might be other unrelated jobs in the system that we do not care to see.) -The `-L` option adds an extra column with just the `item` label value. - We can check on the pods as well using the same label selector: ```console -$ kubectl get pods -l app=jobexample -L item -NAME READY STATUS RESTARTS AGE ITEM -process-item-apple-kixwv 0/1 Completed 0 4m apple -process-item-banana-wrsf7 0/1 Completed 0 4m banana -process-item-cherry-dnfu9 0/1 Completed 0 4m cherry +$ kubectl get pods -l app=jobexample +NAME READY STATUS RESTARTS AGE +process-item-apple-kixwv 0/1 Completed 0 4m +process-item-banana-wrsf7 0/1 Completed 0 4m +process-item-cherry-dnfu9 0/1 Completed 0 4m ``` There is not a single command to check on the output of all jobs at once, @@ -170,21 +167,17 @@ First, download or paste the following template file to a file called `job.yaml. {%- for p in params %} {%- set name = p["name"] %} {%- set url = p["url"] %} -apiVersion: extensions/v1beta1 +apiVersion: batch/v1 kind: Job metadata: name: jobexample-{{ name }} + labels: + jobgroup: jobexample spec: - selector: - matchLabels: - app: jobexample - item: {{ name }} template: - metadata: name: jobexample labels: - app: jobexample - item: {{ name }} + jobgroup: jobexample spec: containers: - name: c diff --git a/examples/job/expansions/job.yaml.jinja2 b/examples/job/expansions/job.yaml.jinja2 index 962505a522a..0577238517a 100644 --- a/examples/job/expansions/job.yaml.jinja2 +++ b/examples/job/expansions/job.yaml.jinja2 @@ -5,21 +5,17 @@ {%- for p in params %} {%- set name = p["name"] %} {%- set url = p["url"] %} -apiVersion: extensions/v1beta1 +apiVersion: batch/v1 kind: Job metadata: name: jobexample-{{ name }} + labels: + jobgroup: jobexample spec: - selector: - matchLabels: - app: jobexample - item: {{ name }} template: - metadata: name: jobexample labels: - app: jobexample - item: {{ name }} + jobgroup: jobexample spec: containers: - name: c diff --git a/examples/job/expansions/job.yaml.txt b/examples/job/expansions/job.yaml.txt index 318c61b5996..790025b38b8 100644 --- a/examples/job/expansions/job.yaml.txt +++ b/examples/job/expansions/job.yaml.txt @@ -1,18 +1,15 @@ -apiVersion: extensions/v1beta1 +apiVersion: batch/v1 kind: Job metadata: name: process-item-$ITEM + labels: + jobgroup: jobexample spec: - selector: - matchLabels: - app: jobexample - item: $ITEM template: metadata: name: jobexample labels: - app: jobexample - item: $ITEM + jobgroup: jobexample spec: containers: - name: c diff --git a/examples/job/work-queue-1/README.md b/examples/job/work-queue-1/README.md index 57c71d667ea..5fab5b3fc3e 100644 --- a/examples/job/work-queue-1/README.md +++ b/examples/job/work-queue-1/README.md @@ -262,21 +262,16 @@ image to match the name you used, and call it `./job.yaml`. ```yaml -apiVersion: extensions/v1beta1 +apiVersion: batch/v1 kind: Job metadata: name: job-wq-1 spec: - selector: - matchLabels: - app: job-wq-1 completions: 8 parallelism: 2 template: metadata: name: job-wq-1 - labels: - app: job-wq-1 spec: containers: - name: c diff --git a/examples/job/work-queue-1/job.yaml b/examples/job/work-queue-1/job.yaml index 50c1730f398..d2696ed0222 100644 --- a/examples/job/work-queue-1/job.yaml +++ b/examples/job/work-queue-1/job.yaml @@ -1,18 +1,13 @@ -apiVersion: extensions/v1beta1 +apiVersion: batch/v1 kind: Job metadata: name: job-wq-1 spec: - selector: - matchLabels: - app: job-wq-1 completions: 8 parallelism: 2 template: metadata: name: job-wq-1 - labels: - app: job-wq-1 spec: containers: - name: c diff --git a/examples/job/work-queue-2/README.md b/examples/job/work-queue-2/README.md index ad5066312ab..31e1ad9049d 100644 --- a/examples/job/work-queue-2/README.md +++ b/examples/job/work-queue-2/README.md @@ -217,20 +217,15 @@ Here is the job definition: ```yaml -apiVersion: extensions/v1beta1 +apiVersion: batch/v1 kind: Job metadata: name: job-wq-2 spec: - selector: - matchLabels: - app: job-wq-2 parallelism: 2 template: metadata: name: job-wq-2 - labels: - app: job-wq-2 spec: containers: - name: c diff --git a/examples/job/work-queue-2/job.yaml b/examples/job/work-queue-2/job.yaml index 09a55ec4b61..ee7a06c7329 100644 --- a/examples/job/work-queue-2/job.yaml +++ b/examples/job/work-queue-2/job.yaml @@ -1,17 +1,12 @@ -apiVersion: extensions/v1beta1 +apiVersion: batch/v1 kind: Job metadata: name: job-wq-2 spec: - selector: - matchLabels: - app: job-wq-2 parallelism: 2 template: metadata: name: job-wq-2 - labels: - app: job-wq-2 spec: containers: - name: c