k8s運行容器之Job(四)--技術流ken
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