1. 程式人生 > >k8s運行容器之Job(四)--技術流ken

k8s運行容器之Job(四)--技術流ken

運行 event root process 通過 cront 顯示 mage failed

Job

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

服務類容器通常持續提供服務,需要一直運行,比如 http server,daemon 等。工作類容器則是一次性任務,比如批處理程序,完成後容器就退出。

Kubernetes 的 Deployment、ReplicaSet 和 DaemonSet 都用於管理服務類容器;對於工作類容器,我們用 Job。

第一步:

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

技術分享圖片

① batch/v1 是當前 Job 的 apiVersion。

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

③ restartPolicy 指定什麽情況下需要重啟容器。對於 Job,只能設置為 Never 或者 OnFailure。對於其他 controller(比如 Deployment)可以設置為 Always 。

第二步:通過 kubectl apply -f myjob.yml 啟動 Job。

[root@ken ~]# kubectl apply -f myjob.yml
job.batch/myjob created

第三步:查看job的狀態

[root@ken ~]# kubectl get job
NAME    COMPLETIONS   DURATION   AGE
myjob   1/1           4s         40s

第四步:查看pod的狀態

[root@ken ~]# kubectl get pod
NAME                                READY   STATUS      RESTARTS   AGE
myjob
-8hczg 0/1 Completed 0 83s

顯示completed已經完成

第五步:查看pod的標準輸出

[root@ken ~]# kubectl logs myjob-8hczg 
hello k8s job!

job失敗的情況

討論了job執行成功的情況,如果失敗了會怎麽樣呢?

第一步:修改 myjob.yml,故意引入一個錯誤:

技術分享圖片

第二步:刪除之前的job

[root@ken ~]# kubectl delete -f myjob.yml
job.batch 
"myjob" deleted [root@ken ~]# kubectl get job No resources found.

第三步:運行新的job並查看狀態

[root@ken ~]# kubectl apply -f myjob.yml
job.batch/myjob created
[root@ken ~]# kubectl get job
NAME    COMPLETIONS   DURATION   AGE
myjob   0/1           6s         6s

可以發現完成為0

第四步:查看pod狀態

[root@ken ~]# kubectl get pod
NAME                                READY   STATUS               RESTARTS   AGE
myjob-hc6ld                         0/1     ContainerCannotRun   0          64s
myjob-hfblk                         0/1     ContainerCannotRun   0          60s
myjob-t9f6v                         0/1     ContainerCreating    0          11s
myjob-v2g7s                         0/1     ContainerCannotRun   0          31s

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

第五步:查看pod的啟動日誌

[root@ken ~]# kubectl describe pod myjob-hc6ld
...
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type     Reason     Age    From               Message
  ----     ------     ----   ----               -------
  Normal   Scheduled  2m21s  default-scheduler  Successfully assigned default/myjob-hc6ld to host1
  Normal   Pulling    2m19s  kubelet, host1     pulling image "busybox"
  Normal   Pulled     2m18s  kubelet, host1     Successfully pulled image "busybox"
  Normal   Created    2m18s  kubelet, host1     Created container
  Warning  Failed     2m17s  kubelet, host1     Error: failed to start container "hello": Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "exec: \"invlain_commadn\": executable file not found in $PATH": unknown

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

下面解釋一個現象:為什麽 kubectl get pod 會看到這麽多個失敗的 Pod?

原因是:當第一個 Pod 啟動時,容器失敗退出,根據 restartPolicy: Never,此失敗容器不會被重啟,但 Job DESIRED 的 Pod 是 1,目前 SUCCESSFUL 為 0,不滿足,所以 Job controller 會啟動新的 Pod,直到 SUCCESSFUL 為 1。對於我們這個例子,SUCCESSFUL 永遠也到不了 1,所以 Job controller 會一直創建新的 Pod。為了終止這個行為,只能刪除 Job。

[root@ken ~]# kubectl delete -f myjob.yml
job.batch "myjob" deleted
[root@ken ~]# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE

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

[root@ken ~]# kubectl apply -f myjob.yml
job.batch/myjob created
[root@ken ~]# kubectl get job
NAME    COMPLETIONS   DURATION   AGE

完成依然為0

再來查看一下pod的狀態

[root@ken ~]# kubectl get pod
NAME          READY   STATUS             RESTARTS   AGE
myjob-5tbxw   0/1     CrashLoopBackOff   2          67s

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

定時執行job

Linux 中有 cron 程序定時執行任務,Kubernetes 的 CronJob 提供了類似的功能,可以定時執行 Job。

第一步:CronJob 配置文件示例如下:

[root@ken ~]# cat myjob1.yml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
         spec:
           containers:
             - name: hello
               image: busybox
               command: ["echo","hello k8s job!"]
           restartPolicy: OnFailure

① batch/v1beta1 是當前 CronJob 的 apiVersion。

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

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

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

第二步:接下來通過 kubectl apply 創建 CronJob。

[root@ken ~]# kubectl apply -f myjob1.yml
cronjob.batch/hello created

第三步:查看crontab的狀態

[root@ken ~]# kubectl get cronjob
NAME    SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
hello   */1 * * * *   False     1        22s             3m12s

第四步:等待幾分鐘查看jobs的執行情況

[root@ken ~]# kubectl get job
NAME               COMPLETIONS   DURATION   AGE
hello-1548766140   1/1           5s         2m24s
hello-1548766200   1/1           18s        83s
hello-1548766260   1/1           4s         23s

可以看到每隔一分鐘就會啟動一個 Job。

第五步:執行 kubectl logs 可查看某個 Job 的運行日誌:

[root@ken ~]# kubectl logs hello-1548766260-6s8lp
hello k8s job!

k8s運行容器之Job(四)--技術流ken