在這個例子裏,咱們將運行多個Kubernetes Jobs,配置文件從同一個模版展開,而後建立多個jobs任務。python
你須要首先了解 Jobs 的用法。git
首先,下載job的模版,文件名爲 job-tmpl.yaml
github
application/job/job-tmpl.yaml |
---|
apiVersion: batch/v1 kind: Job metadata: name: process-item-$ITEM labels: jobgroup: jobexample spec: template: metadata: name: jobexample labels: jobgroup: jobexample spec: containers: - name: c image: busybox command: ["sh", "-c", "echo Processing item $ITEM && sleep 5"] restartPolicy: Never |
與 pod template不一樣,咱們的 job template不是Kubernetes API 的樣子。這是 yaml格式的Job object 表明,同時裏面有一些佔位符,在後面進行填充,這裏的$ITEM
佔位符語法對 Kubernetes 來講是沒有意義的。web
這個例子中,容器惟一的處理只是 echo
一個字符串而後 sleep 一下子。在真實場景下,處理多是一個耗時的計算,如渲染一個電影或處理數據庫裏的一部分數據。這裏 $ITEM
參數可用於指示幀數或者數據的行列數。shell
該 Job 和它的 Pod 模版有一個label: jobgroup=jobexample
. 這對於系統沒有什麼特殊的意義,只是操做全部的job時做爲一個組更爲方便。咱們將該標籤放到全部的 pod template, 就可使用單個命令檢查全部與該job相關的Pods 。當job建立後,系統會加入更多的標籤,以將Job的pod與其它的區分開來。注意,這個 label key jobgroup
對 Kubernetes沒有特殊意義,你也可使用本身的標籤機制。數據庫
下一步,擴展template爲多個文件,每個 item 將被處理。以下所示:api
# Expand files into a temporary directory $ mkdir ./jobs $ for i in apple banana cherry do cat job-tmpl.yaml | sed "s/\$ITEM/$i/" > ./jobs/job-$i.yaml done
檢查一下結果:app
$ ls jobs/ job-apple.yaml job-banana.yaml job-cherry.yaml
這裏,咱們使用sed
替換了字符串 $ITEM,經過循環變量進行。
你可使用任何template 語言 (jinja2, erb) 或者寫一段代碼來建立這個Job對象。ui
下一步,使用kubectl 命令建立全部的jobs對象,以下:url
$ kubectl create -f ./jobs job "process-item-apple" created job "process-item-banana" created job "process-item-cherry" created
檢查全部的jobs狀態:
$ kubectl get jobs -l jobgroup=jobexample NAME DESIRED SUCCESSFUL AGE process-item-apple 1 1 31s process-item-banana 1 1 31s process-item-cherry 1 1 31s
使用 -l
選項來選中jobs組中的全部對象 (There might be other unrelated jobs in the system that we do not care to see.)
檢查同一組標籤的pods:
$ kubectl get pods -l jobgroup=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
沒有一個單個命令能夠看到全部jobs的輸出,經過循環來作也不難,以下:
$ for p in $(kubectl get pods -l jobgroup=jobexample -o name) do kubectl logs $p done Processing item apple Processing item banana Processing item cherry
在上面的例子中,模版使用了單一參數,並且做爲label。 可是 label keys 有必定的限制,參見 what characters they can contain.
稍微複雜一點的例子,使用 jinja2 template 語言來建立咱們的job objects。使用單行的python script轉換template到文件。
首先, 拷貝、粘貼下列Job object到文件名爲 job.yaml.jinja2
:
{%- set params = [{ "name": "apple", "url": "http://www.orangepippin.com/apples", }, { "name": "banana", "url": "https://en.wikipedia.org/wiki/Banana", }, { "name": "raspberry", "url": "https://www.raspberrypi.org/" }] %} {%- for p in params %} {%- set name = p["name"] %} {%- set url = p["url"] %} apiVersion: batch/v1 kind: Job metadata: name: jobexample-{{ name }} labels: jobgroup: jobexample spec: template: metadata: name: jobexample labels: jobgroup: jobexample spec: containers: - name: c image: busybox command: ["sh", "-c", "echo Processing URL {{ url }} && sleep 5"] restartPolicy: Never --- {%- endfor %}
上面的 template 定義了每個job objects的參數,使用python dicts 的 list (lines 1-4)。而後, 循環處理參數集合,產生job的yaml object。多個 yaml 能夠經過 ---
符號進行分隔,所以咱們將其內容輸出到一個job文件,用於kubectl 的後續操做。
你須要 jinja2 package,能夠經過命令安裝: pip install --user jinja2
。
如今,使用單行python 程序來擴充這個模版:
alias render_template='python -c "from jinja2 import Template; import sys; print(Template(sys.stdin.read()).render());"'
輸出被保存爲文件, 以下操做:
cat job.yaml.jinja2 | render_template > jobs.yaml
或者直接發送給kubectl, 以下:
cat job.yaml.jinja2 | render_template | kubectl create -f -
若是你有大量的job objects, 很快會發現:
這種狀況下,你應該考慮使用其它的 job patterns 了。