使用靜態工作分配進行平行處理的索引化任務
Kubernetes v1.24 [stable]
在此範例中,您將執行一個 Kubernetes 任務,該任務使用多個平行工作程序。每個工作程序都是在其自己的 Pod 中執行的不同容器。Pod 具有索引編號,控制平面會自動設定該編號,這允許每個 Pod 識別要處理的整體任務的哪個部分。
Pod 索引在 註解 batch.kubernetes.io/job-completion-index
中以字串形式表示其十進位值。為了讓容器化任務程序取得此索引,您可以使用向下 API 機制發佈註解的值。為了方便起見,控制平面會自動設定向下 API 以在 JOB_COMPLETION_INDEX
環境變數中公開索引。
以下是此範例中步驟的概述
- 使用索引完成定義任務資訊清單。向下 API 允許您將 Pod 索引註解作為環境變數或檔案傳遞到容器。
- 根據該資訊清單啟動
Indexed
任務.
開始之前
您應該已經熟悉 任務 的基本、非平行使用方式。
您需要有一個 Kubernetes 叢集,並且必須設定 kubectl 命令列工具以與您的叢集通訊。建議在至少兩個非作為控制平面主機的節點的叢集上執行本教學課程。如果您還沒有叢集,可以使用 minikube 建立一個,或者您可以使用以下 Kubernetes Playground 之一
您的 Kubernetes 伺服器必須為 v1.21 或更新版本。若要檢查版本,請輸入kubectl version
。選擇一種方法
若要從工作程序存取工作項目,您有幾個選項
- 讀取
JOB_COMPLETION_INDEX
環境變數。任務 控制器 會自動將此變數連結到包含完成索引的註解。 - 讀取包含完成索引的檔案。
- 假設您無法修改程式,您可以使用腳本包裝它,該腳本使用上述任何方法讀取索引,並將其轉換為程式可以使用的輸入。
在此範例中,假設您選擇了選項 3,並且想要執行 rev 工具。這個程式接受檔案作為參數,並列印其反轉的內容。
rev data.txt
您將使用來自 busybox
容器映像檔的 rev
工具。
因為這只是一個範例,每個 Pod 只執行一小部分工作(反轉一個短字串)。在實際的工作負載中,您可能會建立一個 Job,代表根據場景資料產生 60 秒影片的任務。影片渲染 Job 中的每個工作項目都是渲染該影片片段的特定影格。索引完成表示 Job 中的每個 Pod 都知道要渲染和發布哪個影格,方法是從片段的開頭開始計數影格。
定義索引 Job
這是一個範例 Job 資訊清單,使用 Indexed
完成模式
apiVersion: batch/v1
kind: Job
metadata:
name: 'indexed-job'
spec:
completions: 5
parallelism: 3
completionMode: Indexed
template:
spec:
restartPolicy: Never
initContainers:
- name: 'input'
image: 'docker.io/library/bash'
command:
- "bash"
- "-c"
- |
items=(foo bar baz qux xyz)
echo ${items[$JOB_COMPLETION_INDEX]} > /input/data.txt
volumeMounts:
- mountPath: /input
name: input
containers:
- name: 'worker'
image: 'docker.io/library/busybox'
command:
- "rev"
- "/input/data.txt"
volumeMounts:
- mountPath: /input
name: input
volumes:
- name: input
emptyDir: {}
在上面的範例中,您使用 Job 控制器為所有容器設定的內建 JOB_COMPLETION_INDEX
環境變數。 初始化容器 將索引對應到靜態值,並將其寫入檔案,該檔案透過 emptyDir 卷 與執行工作程式的容器共用。 或者,您可以透過向下 API 定義自己的環境變數,以將索引發布到容器。 您也可以選擇從 ConfigMap 作為環境變數或檔案載入值清單。
或者,您可以直接使用向下 API 將註解值作為卷檔案傳遞,如下列範例所示
apiVersion: batch/v1
kind: Job
metadata:
name: 'indexed-job'
spec:
completions: 5
parallelism: 3
completionMode: Indexed
template:
spec:
restartPolicy: Never
containers:
- name: 'worker'
image: 'docker.io/library/busybox'
command:
- "rev"
- "/input/data.txt"
volumeMounts:
- mountPath: /input
name: input
volumes:
- name: input
downwardAPI:
items:
- path: "data.txt"
fieldRef:
fieldPath: metadata.annotations['batch.kubernetes.io/job-completion-index']
執行 Job
現在執行 Job
# This uses the first approach (relying on $JOB_COMPLETION_INDEX)
kubectl apply -f https://kubernetes.dev.org.tw/examples/application/job/indexed-job.yaml
當您建立此 Job 時,控制平面會為您指定的每個索引建立一系列 Pod。 .spec.parallelism
的值決定可以同時執行的數量,而 .spec.completions
決定 Job 總共建立多少個 Pod。
因為 .spec.parallelism
小於 .spec.completions
,所以控制平面會等待前幾個 Pod 完成後,再啟動更多 Pod。
您可以等待 Job 成功,並設定逾時
# The check for condition name is case insensitive
kubectl wait --for=condition=complete --timeout=300s job/indexed-job
現在,描述 Job 並檢查它是否成功。
kubectl describe jobs/indexed-job
輸出類似於
Name: indexed-job
Namespace: default
Selector: controller-uid=bf865e04-0b67-483b-9a90-74cfc4c3e756
Labels: controller-uid=bf865e04-0b67-483b-9a90-74cfc4c3e756
job-name=indexed-job
Annotations: <none>
Parallelism: 3
Completions: 5
Start Time: Thu, 11 Mar 2021 15:47:34 +0000
Pods Statuses: 2 Running / 3 Succeeded / 0 Failed
Completed Indexes: 0-2
Pod Template:
Labels: controller-uid=bf865e04-0b67-483b-9a90-74cfc4c3e756
job-name=indexed-job
Init Containers:
input:
Image: docker.io/library/bash
Port: <none>
Host Port: <none>
Command:
bash
-c
items=(foo bar baz qux xyz)
echo ${items[$JOB_COMPLETION_INDEX]} > /input/data.txt
Environment: <none>
Mounts:
/input from input (rw)
Containers:
worker:
Image: docker.io/library/busybox
Port: <none>
Host Port: <none>
Command:
rev
/input/data.txt
Environment: <none>
Mounts:
/input from input (rw)
Volumes:
input:
Type: EmptyDir (a temporary directory that shares a pod's lifetime)
Medium:
SizeLimit: <unset>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 4s job-controller Created pod: indexed-job-njkjj
Normal SuccessfulCreate 4s job-controller Created pod: indexed-job-9kd4h
Normal SuccessfulCreate 4s job-controller Created pod: indexed-job-qjwsz
Normal SuccessfulCreate 1s job-controller Created pod: indexed-job-fdhq5
Normal SuccessfulCreate 1s job-controller Created pod: indexed-job-ncslj
在此範例中,您使用每個索引的自訂值執行 Job。 您可以檢查其中一個 Pod 的輸出
kubectl logs indexed-job-fdhq5 # Change this to match the name of a Pod from that Job
輸出類似於
xuq