K8S脈絡整理(009)-Job、ConJob


Job

容器按照持續運行的時間可分為兩類:服務類容器和工作類容器。

服務類容器通常持續提供服務,需要一直運行,比如 http server,daemon 等。

工作類容器則是一次性任務,比如批處理程序,完成后容器就退出。

Kubernetes 的 Deployment、ReplicaSet 和 DaemonSet 都用於管理服務類容器

對於工作類容器,我們用 Job

先看一個簡單的 Job 配置文件 myjob.yml:

apiVersion: batch/v1
kind: Job
metadata:
  name: myjob
spec:
  template:
    metadata:
      name: myjob
    spec:
      containers:
      - name: hello
        image: busybox
        command: ["echo", "hello k8s job! "]
      restartPolicy: Never

① batch/v1 是當前 Job 的 apiVersion。kubectl api-versions查看可用apiVersion

② 指明當前資源的類型為 Job

③ restartPolicy 指定什么情況下需要重啟容器。對於 Job,只能設置為 Never 或者 OnFailure

對於其他 controller(比如 Deployment)可以設置為 Always 。

通過 kubectl apply -f myjob.yml 啟動 Job。並kubectl get job 查看 Job 的狀態:

daweij@master:~/stady01/nginx$  kubectl apply -f myjob.yml 
job "myjob" created
daweij@master:~/stady01/nginx$ kubectl get job
NAME      DESIRED   SUCCESSFUL   AGE
myjob     1         1            2m
daweij@master:~/stady01/nginx$ kubectl get pod --show-all
NAME                                   READY     STATUS      RESTARTS   AGE
myjob-72j2r                            0/1       Completed   0          3m

DESIRED 和 SUCCESSFUL 都為 1,表示按照預期啟動了一個 Pod,並且已經成功執行。kubectl get pod 查看 Pod 的狀態:

因為 Pod 執行完畢后容器已經退出,需要用 --show-all 才能查看 Completed 狀態的 Pod。

kubectl logs 可以查看 Pod 的標准輸出:

daweij@master:~/stady01/nginx$ kubectl logs myjob-72j2r
hello k8s job! 

 

以上是 Pod 成功執行的情況。

如果 Pod 失敗了會怎么樣呢?

修改 myjob.yml,故意引入一個錯誤。

如果將 restartPolicy 設置為 OnFailure 會怎么樣?下面我們實踐一下,修改 myjob.yml 后重新啟動。

運行新的 Job 並查看狀態,當前 SUCCESSFUL 的 Pod 數量為 0,查看 Pod 的狀態.

可以看到有多個 Pod,狀態均不正常。kubectl describe pod 查看某個 Pod 的啟動日志:

650.png

日志顯示沒有可執行程序,符合我們的預期。

為什么 kubectl get pod 會看到這么多個失敗的 Pod?

原因是:當第一個 Pod 啟動時,容器失敗退出,根據 restartPolicy: Never,此失敗容器不會被重啟,但 Job DESIRED 的 Pod 是 1,目前 SUCCESSFUL 為 0,不滿足.

所以 Job controller 會啟動新的 Pod,直到 SUCCESSFUL 為 1

對於我們這個例子,SUCCESSFUL 永遠也到不了 1,所以 Job controller 會一直創建新的 Pod。為了終止這個行為,只能刪除 Job。

 

如果將 restartPolicy 設置為 OnFailure 會怎么樣?下面我們實踐一下,修改 myjob.yml 后重新啟動。

Job 的 SUCCESSFUL Pod 數量還是為 0,看看 Pod 的情況。

里只有一個 Pod,不過 RESTARTS 為 3,而且不斷增加,說明 OnFailure 生效,容器失敗后會自動重啟

有時,我們希望能同時運行多個 Pod,提高 Job 的執行效率。這個可以通過 parallelism 設置。

這里我們將並行的 Pod 數量設置為 2,實踐一下:

Job 一共啟動了兩個 Pod,而且 AGE 相同,可見是並行運行的。

我們還可以通過 completions 設置 Job 成功完成 Pod 的總數

上面配置的含義是:每次運行兩個 Pod,直到總共有 6 個 Pod 成功完成。實踐一下:

DESIRED 和 SUCCESSFUL 均為 6,符合預期。如果不指定 completions 和 parallelism,默認值均為 1

上面的例子只是為了演示 Job 的並行特性,實際用途不大。

不過現實中確實存在很多需要並行處理的場景。

比如批處理程序,每個副本(Pod)都會從任務池中讀取任務並執行,副本越多,執行時間就越短,效率就越高。這種類似的場景都可以用 Job 來實現。

 

如何定時執行 Job。

Linux 中有 cron 程序定時執行任務,Kubernetes 的 CronJob 提供了類似的功能,可以定時執行 Job。CronJob 配置文件示例如下:

① batch/v2alpha1 是當前 CronJob 的 apiVersion

② 指明當前資源的類型為 CronJob

③ schedule 指定什么時候運行 Job,其格式與 Linux cron 一致。這里 */1 * * * * 的含義是每一分鍾啟動一次。

④ jobTemplate 定義 Job 的模板,格式與前面 Job 一致。

接下來通過 kubectl apply 創建 CronJob。

失敗了。這是因為 Kubernetes 默認沒有 enable CronJob 功能,需要在 kube-apiserver 中加入這個功能。方法很簡單,修改 kube-apiserver 的配置文件 /etc/kubernetes/manifests/kube-apiserver.yaml:

kube-apiserver 本身也是個 Pod,在啟動參數中加上 --runtime-config=batch/v2alpha1=true 即可。

然后重啟 kubelet 服務:

systemctl restart kubelet.service

kubelet 會重啟 kube-apiserver Pod。通過 kubectl api-versions 確認 kube-apiserver 現在已經支持 batch/v2alpha1

再次創建CronJob:

這次成功了。通過 kubectl get cronjob 查看 CronJob 的狀態:

等待幾分鍾,然后通過 kubectl get jobs 查看 Job 的執行情況:

可以看到每隔一分鍾就會啟動一個 Job。執行 kubectl logs 可查看某個 Job 的運行日志:

小結

運行容器化應用是 Kubernetes 最重要的核心功能。

為滿足不同的業務需要,Kubernetes 提供了多種 Controller,包括 Deployment、DaemonSet、Job、CronJob 等。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM