iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 14
0
Software Development

K8S - 30天從擦槍到提槍上陣學習筆記。系列 第 14

day 14 Pod Controller(4) - Job , CronJob & PodDisruptionBudget

Job

負責執行一次性任務, 執行完畢會把Pod狀態設定為Completed, 如果過程發生錯誤會依照重啟策略進行下一步驟。
https://ithelp.ithome.com.tw/upload/images/20200918/2012965603T899cXMU.png

運行的情境有三種:

  • 只執行一次,Pod做完就收工, 每個Pod正常終止後, Job狀態會轉為Completed

  • 需要確定Pod運作達到預期數量時:
    設定工作數量: spec.parallellism(預設1), 設定預期數量: spec.comlpetions(預設1),當成功執行完的Pod數量達到spec.comlpetions, 這個Job狀態會轉為Completed

  • work queue 併行Job:
    不設定spec.completions, 預設spec.completions 等於 spec.parallelism, 一個Pod成功完成時, 其他的Pod也會停下來, 所有的Pod都會一起退出程序。

創建Job

Job Controller spec 必填字段只有template, 使用方式和Deployment一樣。Job會幫其Pod對象新增標籤job-name=JOB_NAMEcontroller-uid=UID, 並使用labelSelector完成controller-uid=UID的關聯,Job 位於API群組的batch/V1中。
另外, spec.restartPolicy 預設為 Always, 這並不適用Job, 需要另外設定為OnFailure or Never

  • 創建YAML範例

    -> % cat job-demo.yaml
    apiVersion: batch/v1
    kind: Job
    metadata:
      name: job-demo
    spec:
      template:
        spec:
          containers:
          - name: job-hello
            image: nginx:latest
            args:
            - /bin/sh
            - -c
            - echo test
          restartPolicy: Never
    
  • 查看job運行結果

    -> % kubectl get jobs job-demo
    	NAME       COMPLETIONS   DURATION   AGE
    	job-demo   0/1           3m40s      3m40s
    
  • 查看Job Pod

    	-> % kubectl get pods -L app
    	NAME                                READY   STATUS             RESTARTS   AGE     APP
    	job-demo-ljzfc                      1/1     Running            0          5m21s
    
  • 刪除Pod

  • Pod的狀態設為Completed之後就不再佔用資源, 用戶可以依照使用需求刪除或保留; 如果遇到設定 restartPolicy: OnFailure 且一直發生錯誤導致無法將狀態Completed或是其他無法正常終止的狀況, Pod可能會一直不停的循環重啟, 針對這樣的狀況, Job 提供兩個屬性可以避免佔用資源:

    • spec.activeDeadlineSeconds <integer>: 指定最長活動時間, 時間到就會將它終止
    • spec.backoffLimit <integer>: 用來標記失敗狀態之前的重試次數, 預設為6, 達到允許重試次數就會被終止
    spec:
      backoffLimit: 5
      activeDeadlineSeconds: 100
    

上面的設定表示如果Job失敗重啟超過5次或是執行超過100秒仍未完成, 那Job就會被系統終止。

CronJob

負責定時或週期性的執行任務, 用在管理Jobs的運行時間。CronJob類似Linux的crontab支援預約未來執行任務時間或是固定在某個週期重複執行任務。

創建 CronJob

CronJob spec支援以下字段:

  • jobTemplate : 必填, 用來產生job的模板
  • scheduler : 必填, 設定運行時間
  • concurrencyPolicy : 定義前次作業尚未完成時, 是否繼續運行下一次作業, 可用設定Allow,Forbid,Replace
    有些任務需要較長作業時間, 可能因為某些原因造成下次觸發時間點到了, 但是前次任務尚未執行完成,
    這時可依照任務的狀況分別設定以下選項:
    • Allow: 預設, 允許CronJob底下多個Job同時執行
    • Forbid: 禁止兩個Job同時執行, 前一個未執行完會跳過下一個
    • Replace: 禁止兩個Job同時執行, 前一個未執行完會終止前一個,啟動下一個來取代
  • failedJobHistoryLimit : 任務失敗時預計要保留的歷史紀錄數量, 預設1
  • successfulJobsHistoryLimit : 任務成功時預計要保留的歷史紀錄數量, 預設3
  • startingDeadlineSeconds : 運行時間到了卻沒有正常運行時,用來紀錄超時的數量
  • suspend : 一個任務執行中, 是否暫停後面的任務, 預設false

創建 CronJob

  • 創建YAML
    -> % cat job-demo-multi.yaml
    apiVersion: batch/v1beta1
    kind: CronJob
    metadata:
      name: cronjob-demo
      labels:
        app: cronjob-test
    spec:
      schedule: "*/2 * * * *"
      jobTemplate:
        metadata:
          labels:
            app: cronjob-jobs-lbi
        spec:
          parallelism: 2
          template:
            spec:
              containers:
              - name: job-multi-test
                image: apline
                args:
                - /bin/sh
                - -c
                - echo test
              restartPolicy: OnFailure
    
  • 查看 cronjob
    -> % kubectl get cronjobs
    NAME           SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
    cronjob-demo   */2 * * * *   False     0        <none>          8s
    
    • ACTIVE: 活動狀態的Job數量
    • SCHEDULE: 調度時間點
    • SUSPEND: 後續任務是否暫停
    • LAST SCHEDULE: 上次調度的時間長度

應用場景

  • Job 可以應用在升級後的服務檢測, 或是特定項目異動後檢查。
    例如: 我們有使用lua編寫會隨著需求增加的邏輯檔案, 只有在超出現有邏輯的狀況才需要新增lua檔案, 新增頻率不高, 通常只需要在新增後跑一遍全部測試就好, 此時就可以運用Job手動觸發測試程式檢查。

  • CronJob 適合用在服務定期重啟或定時檢測。
    例如: 在每週的固定維護更新後執行預想的User Story路徑檢查。

PodDisruptionBudget

K8s可以透過PodDisruptionBudget來限制可自願中斷的最高Pod數以及確保最少可用的Pod數, 藉此來維持服務高可用性。自願中斷像是人為刪除或是更新image造成的Pod重建, Deployment雖然可以確保Pod數量接近期望值, 但是無法保證在特定時段一定會存在指定數量或比例的Pod對象, 此時可以透過PodDisruptionBudget來解決。PodDisruptionBudget支援Deployment, ReplicaSet, StatefulSet...等, 主要用來保護LabelSelector關聯到的Pod對象可以精確的存活一定的比例。

PodDisruptionBudget spec 可以使用三個字段:

  • selector : PodDisruptionBudget 的label selector, 一般會與關聯的Pod相同
  • miniAvailable : Pod發生自願中斷時至少要保證可用的數量或比例, 如果要阻止任何Pod發生自願中段可以設定為 100%
  • maxUnavailable : Pod發生自願中斷時最多可轉換為不可用狀態的Pod數量或比例, 如果不允許任何Pod發生自願中段則設定0

miniAvailablemaxUnavailable 互斥, 一是只能選一個設定。

  • YAML配置

    -> % cat pdb-demo.yaml
    apiVersion: policy/v1beta1
    kind: PodDisruptionBudget
    metadata:
      name: pdb-example
    spec:
      minAvailable: 2
      selector:
        matchLabels:
          app: deploy-demo
    
  • 查看結果

    -> % kubectl get pdb
    NAME          MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
    pdb-example   2               N/A               0                     5s
    

今日小結

到今天大致上把Pod Controller 都走過一遍了, 應用時可以先釐清需求的情境, 依照不同的情境來選用不同的 Controller來實作, 接下來要前進到Service的部分了!


上一篇
day 13 Pod Controller(3) - DaemonSet
下一篇
day 15 Service and Ingress(1)- Service
系列文
K8S - 30天從擦槍到提槍上陣學習筆記。30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言