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。

 

過段時間查看pod

 

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

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

 


免責聲明!

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



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