Job

有些工作只需要執行一次,譬如升級。就適合使用 Job 這樣的物件來處理 Pod。

基本上 Job 物件會執行模板中的 Pod,直到成功才會結束(也就是回傳 0 )

一般的 Pod,不論它的回傳值是什麼,只要在結束的狀態,就會自動重新啟動。在 Pod 正確結束之前,若是意外中止,則 K8S 會重新建立一個 Pod,但是在重新建立的時候,會先考量目前的資源是否足夠,若是不足的情況下,會等待調度。

因此你有可能遇到 Pod (Job) 沒有執行的狀況。

Job 的模式

Job 的運作模式主要設定

類型 模式 用途
一次性 只執行一次 升級或是資料庫備份
平行處理 多個 Pod 同時工作 本生就設計成多執行序的程式

一次性 Job

有些單次的任務就可以透過 一次性 的特性來執行,像是資料庫的合併、升級或是備份。

下方的範例是透過一個 Job 來產生 3 把 SSH Key,使用 -i 參數 K8S 就不會進行背景執行,而會將 Pod 的輸出直接顯在終端機。--restart=OnFailure 就是在失敗的時候會自動重新啟動。
範例,產生 3 把 SSH Key;

kubectl run -i onshow \
--image=gcr.io/kuar-demo/kuard-amd64:1 \
--restart=OnFailure \
-- --keygen-enable \
   --keygen-exit-on-complete \
   --keygen-num-to-gen 3

Waiting for pod default/oneshot-ld6lh to be running, status is Pending, pod ready: false
Waiting for pod default/oneshot-ld6lh to be running, status is Pending, pod ready: false
If you don't see a command prompt, try pressing enter.
2019/03/26 22:23:00 (ID 0 1/3) Item done: SHA256:BQPna2bBjfutMF107GkWywGTmXowxWtnto9sLrWL5nw
2019/03/26 22:23:05 (ID 0 2/3) Item done: SHA256:WvHMgCYNMQL3SJvjkC2WA+FEQDq9P6F7ZSZtfwnVMIE
2019/03/26 22:23:08 (ID 0 3/3) Item done: SHA256:DhjPhFtqCO4i1HOV54w+R83NFvfcFJiFdnOc8bws0zo
2019/03/26 22:23:08 (ID 0) Workload exiting

這個 Pod 完成之後,會保留在系統中,所以你可以用 kubectl log 來查看輸出的日誌檔。但若你用 kubectl get pods 會發現看不到這個 Pod。

由於 K8S 預設會隱藏已完成的 Job,所以你必須要用 kubectl get pods -a 才能看到

[root@abc do-k8s]# dkube get pods -a
NAME                            READY     STATUS      RESTARTS   AGE
oneshot-ld6lh                   0/1       Completed   0          3m

當然若你用 get jobs 的 話可以看到此 Job:

[root@abc do-k8s]# dkube  get jobs
NAME      DESIRED   SUCCESSFUL   AGE
oneshot   1         1            3m

kubectl describe jobs 可以看到詳細的狀況:

[root@abc do-k8s]# dkube describe jobs oneshot
Name:           oneshot
Namespace:      default
Image(s):       gcr.io/kuar-demo/kuard-amd64:1
Selector:       controller-uid=b2f72406-5015-11e9-b03d-026f29626e39
Parallelism:    1
Completions:    1
Start Time:     Wed, 27 Mar 2019 06:22:54 +0800
Labels:         run=oneshot
Pods Statuses:  0 Running / 1 Succeeded / 0 Failed
No volumes.
Events:
  FirstSeen     LastSeen        Count   From                    SubObjectPath   Type            Reason                  Message
  ---------     --------        -----   ----                    -------------   --------        ------                  -------
  8m            8m              1       {job-controller }                       Normal          SuccessfulCreate        Created pod: oneshot-ld6lh

平行處理

你可以設定 completionsparallelism 來指定同時要執行的 Pod 數量。可以在同一個時間內執行多個平行工作的 Pod,記得你的程式要符合平行處裡的設計。

completions 代表的是總共要成功的 Pod 次數,而 parallelism 則是同一時間要執行的 Pod 數量。

GitHub 的 jobs-parallel.yaml

apiVersion: batch/v1
kind: Job
metadata:
  name: parallel
  labels:
    chapter: jobs
spec:
  parallelism: 5
  completions: 10
  template:
    metadata:
      labels:
        chapter: jobs
    spec:
      containers:
      - name: kuard
        image: gcr.io/kuar-demo/kuard-amd64:1
        imagePullPolicy: Always
        args:
        - "--keygen-enable"
        - "--keygen-exit-on-complete"
        - "--keygen-num-to-gen=3"
    restartPolicy: OnFailure

這個一個 Job 會產生 3 把 SSH Key,每次會跑 **5 個 Pod*,所以同時會產生 15 把 SSH Key,然後 Pod 成功執行 10 次之後,會生 30 把 SSH Key,就完成了 Job。

失敗的 Jobs

在 Jobs 失敗的情況下,若你設定了 --restart=OnFailure 則 K8S 會嘗試幫你再跑一個 Pod:
範例,在有錯誤發生的時候,會自動 restart。

apiVersion: batch/v1
kind: Job
metadata:
  name: oneshot
  labels:
    chapter: jobs
spec:
  template:
    metadata:
      labels:
        chapter: jobs
    spec:
      containers:
      - name: kuard
        image: gcr.io/kuar-demo/kuard-amd64:1
        imagePullPolicy: Always
        args:
        - "--keygen-enable"
        - "--keygen-exit-on-complete"
        - "--keygen-exit-code=1"
        - "--keygen-num-to-gen=3"
restartPolicy: OnFailure

你可以設定 restartPolicy 為 Never 則當 Pod 失敗的時候只會被標示為失敗,並不會重新執行。

文章資訊
slug:k8s-jobs
title:K8S 一次性工作 - Jobs
tags:k8s,Kubernetes,jobs,parallel,oneshot
categories:k8s
thumbnail:banner-1.jpg
最後修改日期: 2019-08-27

作者