|
| 1 | + |
1 | 2 | <!-- BEGIN MUNGE: UNVERSIONED_WARNING -->
|
2 | 3 |
|
3 | 4 | <!-- BEGIN STRIP_FOR_RELEASE -->
|
@@ -32,216 +33,7 @@ Documentation for other releases can be found at
|
32 | 33 |
|
33 | 34 | <!-- END MUNGE: UNVERSIONED_WARNING -->
|
34 | 35 |
|
35 |
| -# Example: Multiple Job Objects from Template Expansion |
36 |
| - |
37 |
| -In this example, we will run multiple Kubernetes Jobs created from |
38 |
| -a common template. You may want to be familiar with the basic, |
39 |
| -non-parallel, use of [Job](../../../docs/user-guide/jobs.md) first. |
40 |
| - |
41 |
| -## Basic Template Expansion |
42 |
| - |
43 |
| -First, create a template of a Job object: |
44 |
| - |
45 |
| -<!-- BEGIN MUNGE: EXAMPLE job.yaml.txt --> |
46 |
| - |
47 |
| -``` |
48 |
| -apiVersion: batch/v1 |
49 |
| -kind: Job |
50 |
| -metadata: |
51 |
| - name: process-item-$ITEM |
52 |
| - labels: |
53 |
| - jobgroup: jobexample |
54 |
| -spec: |
55 |
| - template: |
56 |
| - metadata: |
57 |
| - name: jobexample |
58 |
| - labels: |
59 |
| - jobgroup: jobexample |
60 |
| - spec: |
61 |
| - containers: |
62 |
| - - name: c |
63 |
| - image: busybox |
64 |
| - command: ["sh", "-c", "echo Processing item $ITEM && sleep 5"] |
65 |
| - restartPolicy: Never |
66 |
| -``` |
67 |
| - |
68 |
| -[Download example](job.yaml.txt?raw=true) |
69 |
| -<!-- END MUNGE: EXAMPLE job.yaml.txt --> |
70 |
| - |
71 |
| -Unlike a *pod template*, our *job template* is not a Kubernetes API type. It is just |
72 |
| -a yaml representation of a Job object that has some placeholders that need to be filled |
73 |
| -in before it can be used. The `$ITEM` syntax is not meaningful to Kubernetes. |
74 |
| - |
75 |
| -In this example, the only processing the container does is to `echo` a string and sleep for a bit. |
76 |
| -In a real use case, the processing would be some substantial computation, such as rendering a frame |
77 |
| -of a movie, or processing a range of rows in a database. The "$ITEM" parameter would specify for |
78 |
| -example, the frame number or the row range. |
79 |
| - |
80 |
| -This Job and its Pod template have a label: `jobgroup=jobexample`. There is nothing special |
81 |
| -to the system about this label. This label |
82 |
| -makes it convenient to operate on all the jobs in this group at once. |
83 |
| -We also put the same label on the pod template so that we can check on all Pods of these Jobs |
84 |
| -with a single command. |
85 |
| -After the job is created, the system will add more labels that distinguish one Job's pods |
86 |
| -from another Job's pods. |
87 |
| -Note that the label key `jobgroup` is not special to Kubernetes. you can pick your own label scheme. |
88 |
| - |
89 |
| -Next, expand the template into multiple files, one for each item to be processed. |
90 |
| - |
91 |
| -```console |
92 |
| -# Expand files into a temporary directory |
93 |
| -$ mkdir ./jobs |
94 |
| -$ for i in apple banana cherry |
95 |
| -do |
96 |
| - cat job.yaml.txt | sed "s/\$ITEM/$i/" > ./jobs/job-$i.yaml |
97 |
| -done |
98 |
| -$ ls jobs/ |
99 |
| -job-apple.yaml |
100 |
| -job-banana.yaml |
101 |
| -job-cherry.yaml |
102 |
| -``` |
103 |
| - |
104 |
| -Here, we used `sed` to replace the string `$ITEM` with the the loop variable. |
105 |
| -You could use any type of template language (jinja2, erb) or write a program |
106 |
| -to generate the Job objects. |
107 |
| - |
108 |
| -Next, create all the jobs with one kubectl command: |
109 |
| - |
110 |
| -```console |
111 |
| -$ kubectl create -f ./jobs |
112 |
| -job "process-item-apple" created |
113 |
| -job "process-item-banana" created |
114 |
| -job "process-item-cherry" created |
115 |
| -``` |
116 |
| - |
117 |
| -Now, check on the jobs: |
118 |
| - |
119 |
| -```console |
120 |
| -$ kubectl get jobs -l app=jobexample |
121 |
| -JOB CONTAINER(S) IMAGE(S) SELECTOR SUCCESSFUL |
122 |
| -process-item-apple c busybox app in (jobexample),item in (apple) 1 |
123 |
| -process-item-banana c busybox app in (jobexample),item in (banana) 1 |
124 |
| -process-item-cherry c busybox app in (jobexample),item in (cherry) 1 |
125 |
| -``` |
126 |
| - |
127 |
| -Here we use the `-l` option to select all jobs that are part of this |
128 |
| -group of jobs. (There might be other unrelated jobs in the system that we |
129 |
| -do not care to see.) |
130 |
| - |
131 |
| -We can check on the pods as well using the same label selector: |
132 |
| - |
133 |
| -```console |
134 |
| -$ kubectl get pods -l app=jobexample |
135 |
| -NAME READY STATUS RESTARTS AGE |
136 |
| -process-item-apple-kixwv 0/1 Completed 0 4m |
137 |
| -process-item-banana-wrsf7 0/1 Completed 0 4m |
138 |
| -process-item-cherry-dnfu9 0/1 Completed 0 4m |
139 |
| -``` |
140 |
| - |
141 |
| -There is not a single command to check on the output of all jobs at once, |
142 |
| -but looping over all the pods is pretty easy: |
143 |
| - |
144 |
| -```console |
145 |
| -$ for p in $(kubectl get pods -l app=jobexample -o name) |
146 |
| -do |
147 |
| - kubectl logs $p |
148 |
| -done |
149 |
| -Processing item apple |
150 |
| -Processing item banana |
151 |
| -Processing item cherry |
152 |
| -``` |
153 |
| - |
154 |
| -## Multiple Template Parameters |
155 |
| - |
156 |
| -In the first example, each instance of the template had one parameter, and that parameter was also |
157 |
| -used as a label. However label keys are limited in [what characters they can |
158 |
| -contain](labels.md#syntax-and-character-set). |
159 |
| - |
160 |
| -This slightly more complex example uses a the jinja2 template language to generate our objects. |
161 |
| -We will use a one-line python script to convert the template to a file. |
162 |
| - |
163 |
| -First, download or paste the following template file to a file called `job.yaml.jinja2`: |
164 |
| - |
165 |
| -<!-- BEGIN MUNGE: EXAMPLE job.yaml.jinja2 --> |
166 |
| - |
167 |
| -``` |
168 |
| -{%- set params = [{ "name": "apple", "url": "http://www.orangepippin.com/apples", }, |
169 |
| - { "name": "banana", "url": "https://en.wikipedia.org/wiki/Banana", }, |
170 |
| - { "name": "raspberry", "url": "https://www.raspberrypi.org/" }] |
171 |
| -%} |
172 |
| -{%- for p in params %} |
173 |
| -{%- set name = p["name"] %} |
174 |
| -{%- set url = p["url"] %} |
175 |
| -apiVersion: batch/v1 |
176 |
| -kind: Job |
177 |
| -metadata: |
178 |
| - name: jobexample-{{ name }} |
179 |
| - labels: |
180 |
| - jobgroup: jobexample |
181 |
| -spec: |
182 |
| - template: |
183 |
| - name: jobexample |
184 |
| - labels: |
185 |
| - jobgroup: jobexample |
186 |
| - spec: |
187 |
| - containers: |
188 |
| - - name: c |
189 |
| - image: busybox |
190 |
| - command: ["sh", "-c", "echo Processing URL {{ url }} && sleep 5"] |
191 |
| - restartPolicy: Never |
192 |
| ---- |
193 |
| -{%- endfor %} |
194 |
| -``` |
195 |
| - |
196 |
| -[Download example](job.yaml.jinja2?raw=true) |
197 |
| -<!-- END MUNGE: EXAMPLE job.yaml.jinja2 --> |
198 |
| - |
199 |
| -The above template defines parameters for each job object using a list of |
200 |
| -python dicts (lines 1-4). Then a for loop emits one job yaml object |
201 |
| -for each set of parameters (remaining lines). |
202 |
| -We take advantage of the fact that multiple yaml documents can be concatenated |
203 |
| -with the `---` separator (second to last line). |
204 |
| -.) We can pipe the output directly to kubectl to |
205 |
| -create the objects. |
206 |
| - |
207 |
| -You will need the jinja2 package if you do not already have it: `pip install --user jinja2`. |
208 |
| -Now, use this one-line python program to expand the template: |
209 |
| - |
210 |
| -``` |
211 |
| -$ alias render_template='python -c "from jinja2 import Template; import sys; print(Template(sys.stdin.read()).render());"' |
212 |
| -``` |
213 |
| - |
214 |
| - |
215 |
| - |
216 |
| -The output can be saved to a file, like this: |
217 |
| - |
218 |
| -``` |
219 |
| -$ cat job.yaml.jinja2 | render_template > jobs.yaml |
220 |
| -``` |
221 |
| - |
222 |
| -or sent directly to kubectl, like this: |
223 |
| - |
224 |
| -``` |
225 |
| -$ cat job.yaml.jinja2 | render_template | kubectl create -f - |
226 |
| -``` |
227 |
| - |
228 |
| -## Alternatives |
229 |
| - |
230 |
| -If you have a large number of job objects, you may find that: |
231 |
| - |
232 |
| -- even using labels, managing so many Job objects is cumbersome. |
233 |
| -- you exceed resource quota when creating all the Jobs at once, |
234 |
| - and do not want to wait to create them incrementally. |
235 |
| -- you need a way to easily scale the number of pods running |
236 |
| - concurrently. One reason would be to avoid using too many |
237 |
| - compute resources. Another would be to limit the number of |
238 |
| - concurrent requests to a shared resource, such as a database, |
239 |
| - used by all the pods in the job. |
240 |
| -- very large numbers of jobs created at once overload the |
241 |
| - kubernetes apiserver, controller, or scheduler. |
242 |
| - |
243 |
| -In this case, you can consider one of the |
244 |
| -other [job patterns](../../../docs/user-guide/jobs.md#job-patterns). |
| 36 | +This file has moved to: http://kubernetes.io/docs/user-guide/jobs/ |
245 | 37 |
|
246 | 38 |
|
247 | 39 | <!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
|
|
0 commit comments