Kubernetes:28---pod託管(Job:任務型pod)

江南、董少發表於2020-12-28

一、執行執行單個任務的pod

  • 到目前為止,我們只談論了需要持續執行的pod。你會遇到只想執行完成工作後就終止任務的情況。ReplicationController、ReplicaSet和DaemonSet會持續執行任務,永遠達不到完成態。這些pod中的程式在退出時會重新啟動
  • 假設你想要一個可完成的任務,其程式終止後,不應該再重新啟動,此時你可以使用Job來完成這些工作

二、介紹Job資源

  • Kubernetes通過Job資源提供了對此的支援,它允許你執行一種pod,該pod在內部程式成功結束時,不重啟容器。一旦任務完成,pod就被認為處於完成狀態
  • 在發生節點故障時,該節點上由Job管理的pod將按照ReplicaSet的pod的方式,重新安排到其他節點如果程式本身異常退出(程式返回錯誤退出程式碼時),可以將Job配置為重新啟動容器
  • 如下圖所示:
    • 下圖顯示瞭如果一個Job所建立的pod,在最初被排程節點上異常退出後,被重新安排到一個新節點上的情況
    • 該圖還顯示了託管的 pod(未重新安排)和由ReplicaSet管理的pod(被重新安排)

  • Job對於臨時任務很有用,關鍵是任務要以正確的方式結束。可以在未託管的pod中執行任務並等待它完成,但是如果發生節點異常或pod在執行任務時被從節點中逐出,則需要手動重新建立該任務。手動做這件事並不合理——特別是如果任務需要幾個小時才能完 成
  • 這樣的任務的一個例子是,如果有資料儲存在某個地方,需要轉換並將其匯出到某個地方。你將通過執行構建在busybox映象上的容器映象來模擬此操作,該容器將呼叫sleep命令兩分鐘,容器的Dockerfile如下所示:
FROM busybox
ENTRYPOINT echo "$(date) Batch job starting"; sleep 120; echo "$(date) Finished succesfully"

三、定義Job資源

  • 定義如下名為exporter.yaml的配置檔案,用來建立Job manifest:

apiVersion: batch/v1
kind: Job
metadata:
  name: batch-job
spec:
  template:
    metadata:
      labels:
        app: batch-job
    spec:
      restartPolicy: OnFailure
      containers:
      - name: main
        image: luksa/batch-job
  • Job是batch API組v1 API版本的一部分。YAML定義了一個Job型別的資源,它將執行luksa/batch-job映象(就是上面我們的Dockerfile),該映象呼叫一個執行120秒的程式,然後退出
  • restartPolicy屬性:
    • 在一個pod的定義中,可以指定在容器中執行的程式結束時,Kubernetes會做什麼。這是通過pod配置的屬性restartPolicy完成的,預設為Always
    • Job pod不能使用預設策略,因為它們不是要無限期地執行。 因此,需要明確地將重啟策略設定為OnFailure或Never,此設定防止容器在完成任務時重新啟動(pod被Job管理時並不是這樣的)

四、使用Job執行一個pod

  • 根據上面的YAML檔案,呼叫kubectl create命令建立一個Job,然後檢視job,命令如下:

  • 兩分鐘過後,pod將不再出現在pod列表中,工作將被標記為已完成。需要使用--show-all(或-a)選項來檢視所有的pod(預設情況下,已完成的pod不會顯示在其中):

  • 完成後pod未被刪除的原因是允許你查閱其日誌。例如:

  • pod可以被直接刪除,也可以再刪除Job的同時一起被刪除
  • 在你刪除它之前,讓我們再看一下Job資源:

  • 作業顯示已成功完成。但為什麼這樣的資訊顯示為一個數字而不是yes或true?DESIRED列表示什麼意思?請見下面分析

五、在Job中執行多個pod例項

  • 作業可以配置為建立多個pod例項,並以並行或序列方式執行它們。這是通過在Job配置中設定completions和parallelism屬性來完成的

順序執行Job pod

  • 如果你需要一個Job執行多次,則可以將completions設為你希望作業的pod執行多少次
  • 如下名為multi-completion-batchjob.yaml的配置檔案所示:

apiVersion: batch/v1
kind: Job
metadata:
  name: multi-completion-batch-job
spec:
  completions: 5
  template:
    metadata:
      labels:
        app: batch-job
    spec:
      restartPolicy: OnFailure
      containers:
      - name: main
        image: luksa/batch-job
  • Job將一個接一個地執行五個pod。它最初建立一個pod,當pod的容器執行完成時,它建立第二個pod,以此類推,直到五個pod成功完成
  • 如果其中一個pod發生故障,工作會建立一個新的pod,所以Job總共可以建立五個以上的pod

並行執行Job pod

  • 不必一個接一個地執行單個Job pod,也可以讓該Job並行執行多個pod。可以通過parallelism Job配置屬性,指定允許多少個pod並行執行
  • 如下名為multi-completion-parallel-batchjob.yaml的配置檔案所示:

apiVersion: batch/v1
kind: Job
metadata:
  name: multi-completion-batch-job
spec:
  completions: 5
  parallelism: 2
  template:
    metadata:
      labels:
        app: batch-job
    spec:
      restartPolicy: OnFailure
      containers:
      - name: main
        image: luksa/batch-job
  • 上面將parallelism設定為2,Job將建立兩個pod並行執行它們:

  • 只要其中一個pod完成任務,工作將執行下一個pod,直到五個pod都成功完成任務

Job的縮放

  • 你甚至可以在Job執行時更改Job的parallelism屬性
  • 這與縮放ReplicaSet或ReplicationController類似,可以使用kubectl scale命令完成:

  • 由於你將parallelism從2增加到3,另一個pod立即啟動,因此現在有三個pod在執行

六、限制Job pod完成任務的時間

  • 關於Job我們需要討論最後一件事。Job要等待一個pod多久來完成 任務?如果pod卡住並且根本無法完成(或者無法足夠快完成),該怎麼辦?
  • 通過在pod配置中設定activeDeadlineSeconds屬性,可以限制pod的時間。如果pod執行時間超過此時間,系統將嘗試終止pod,並將Job標記為失敗
  • 注意:通過指定Job manifest中的spec.backoffLimit欄位,可以配置Job在被標記為失敗之前可以重試的次數。如果你沒有明確指定它, 則預設為6

相關文章