保持 pod 健康 P84
只要 pod 排程到某個節點,該節點上的 Kubelet 就會執行 pod 的容器,從此只要該 pod 存在,就會保持執行。如果容器的主程式奔潰, Kubelet 就會自動重啟容器;如果應用程式奔潰, Kubelet 就會自動重啟應用程式。 P84
應用程式也可能因為無限迴圈或死鎖等情況而停止響應。為確保應用在這種情況下可以重新啟動,必須從外部檢查應用程式的執行狀況,而不是依賴於應用的內部檢測。 P84
介紹存活探測器 P84
Kubernetes 可以通過存活探測器 (liveness probe) 檢查容器是否還在執行。可以為 pod 中的每個容器單獨指定存活探測器。 Kubernetes 將定期執行探測器,如果探測失敗,就會自動重啟容器。 P84
注意:Kubernetes 還支援就緒探測器 (readiness probe) ,兩者適用於兩種不同的場景。 P84
Kubernetes 有三種探測容器的機制: P84
HTTP GET
探測器:對容器的 IP 地址(指定的埠和路徑)執行HTTP GET
請求。如果探測器收到響應,並且響應狀態碼不代表錯誤(狀態碼為 2xx 或 3xx ),則認為探測成功。如果伺服器返回錯誤響應狀態碼或者沒有響應,那麼探測就被認為是失敗的,容器將被重啟。TCP Socket
探測器:嘗試與容器指定埠建立 TCP 連線。如果連線成功建立,則探測成功。否則,容器將被重啟。Exec
探測器:在容器內執行任意命令,並檢查命令的退出狀態碼。如果狀態碼是 0 ,則探測成功。所有其他狀態碼都被認為失敗,容器將被重啟。
建立基於 HTTP 的存活探測器 P85
為了讓 HTTP GET
探測器探測失敗,我們需要修改 kubia 原始碼,使得其從第五次訪問之後開始一直返回 500 狀態碼 (Internal Server Error) 。 P85
然後我們可以通過以下描述檔案 kubia-liveness-probe.yaml
建立一個包含 HTTP GET
存活探測器的 pod 。 P85
# 遵循 v1 版本的 Kubernetes API
apiVersion: v1
# 資源型別為 Pod
kind: Pod
metadata:
# pod 的名稱
name: kubia-liveness
spec:
containers:
# 建立容器所使用的映象
- image: idealism/kubia-unhealthy
# 容器的名稱
name: kubia
ports:
# 應用監聽的埠
- containerPort: 8080
protocol: TCP
# 開啟一個存活探測器
livenessProbe:
# 存活探測器的型別為 HTTP GET
httpGet:
# 探測器連線的網路埠
port: 8080
# 探測器請求的路徑
path: /
使用存活探測器 P86
使用 kubectl create -f kubia-liveness-probe.yaml
建立完 pod 後,等待一段時間後,容器將會重啟。可以通過 kubectl get pod kubia-liveness
看到容器會重啟,並且無限迴圈下去: 86
NAME READY STATUS RESTARTS AGE
kubia-liveness 1/1 Running 2 4m9s
kubectl logs kubia-liveness --previous
: 檢視前一個容器的日誌,可以瞭解前一個容器停止的原因。 P86
kubectl describe pod kubia-liveness
: 檢視 pod 詳情。可以發現在 Containers 和 Events 裡面有終止的相關資訊。 P86
...
Containers:
kubia:
...
State: Running # 容器目前正常執行
Started: Sun, 07 Jun 2020 17:59:35 +0800
Last State: Terminated # 前一個容器由於錯誤被終止,錯誤碼是 137
Reason: Error
Exit Code: 137
Started: Sun, 07 Jun 2020 17:57:44 +0800
Finished: Sun, 07 Jun 2020 17:59:27 +0800
Ready: True
Restart Count: 2 # 該容器已被重啟 2 次
Liveness: http-get http://:8080/ delay=0s timeout=1s period=10s #success=1 #failure=3
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled <unknown> default-scheduler Successfully assigned default/kubia-liveness to minikube-m02
Warning Unhealthy 48s (x6 over 2m58s) kubelet, minikube-m02 Liveness probe failed: HTTP probe failed with statuscode: 500 # 發現容器不健康
Normal Killing 48s (x2 over 2m38s) kubelet, minikube-m02 Container kubia failed liveness probe, will be restarted # 終止該容器
...
錯誤碼 137 是兩個數字的總和: 128 + x , x 是終止程式的訊號編號。 P86
- x=9 表示是
SIGKILL
的訊號編號,意味著這個程式被強行終止,這個訊號不能被捕獲或忽略,並且在接收過程中不能執行任何清理在接收到該訊號 - x=15 表示是
SIGTERM
的訊號編號,意味著這個程式被終止,先進行詢問程式終止,讓其清理檔案和關閉,可以被捕獲和解釋或忽略
底部列出的事件顯示了 Kubernetes 發現容器不健康,所以終止並重新建立。 P86
注意:當容器被強行終止時,會建立一個全新的容器,而不是重啟原來的容器。 P86
配置存活探測器的附加屬性 P87
可以使用 kubectl explain pod.spec.containers.livenessProbe
檢視存活探測器能使用的自定義附加引數。
基於 kubia-liveness-probe.yaml
建立一個新的描述檔案 kubia-liveness-probe-initial-delay.yaml
,並新增 pod.spec.containers.livenessProbe.initialDelaySeconds
屬性,值為 15 ,表示在第一次探測器等待 15 秒。
...
spec:
containers:
# 建立容器所使用的映象
- image: idealism/kubia-unhealthy
...
# 開啟一個存活探測器
livenessProbe:
...
# 第一次探測前等待 15 秒
initialDelaySeconds: 15
這樣可以在應用程式準備好之後再進行探測,以免應用程式啟動時間過長導致一直探測失敗而無限重啟。
建立有效的存活探測器 P88
- 存活探測器應該檢查什麼:簡易的存活探測器可以僅檢查伺服器是否響應,但為了更好地進行存活檢查,需要將探測器配置為請求特定的 URL 路徑(如
/health
),並讓應用從內部對內部執行的所有重要元件執行狀態檢查,以確保它們都沒有終止或停止響應。P88
- 確保
/health
不需要認證,否則探測會一直失敗,導致容器無限重啟 - 檢查應用的內部,檢查結果不能受任何外部因素的影響。例如資料庫連不上時,存活探測器不應該返回失敗,如果問題在資料庫,那麼重啟容器不會解決問題。
- 確保
- 保持探測器輕量
P89
- 不應消耗太多計算資源
- 執行不應花太長時間。預設情況下,探測器執行的頻率相對較高,必須在一秒之內執行完畢
- 無須在探測器中實現重試:探測器的失敗閾值是可配置的,並且通常在容器被終止之前探測器必須失敗多次
P89
- 存活探測器小結:存活探測由 pod 上的 Kubelet 執行, Kubernetes 控制皮膚不會參與。因此節點奔潰時,控制皮膚會為所有隨節點停止執行的 pod 建立替代者,但不會為直接建立的 pod 建立替代者,因為這些 pod 只被節點上的 Kubelet 管理。為了避免這種情況發生,我們應該使用控制器或類似機制管理 pod 。
P89
瞭解 Deployment
P89
注:本節中提到的 pod 受 Deployment
管理等說法為簡化說法,實際上 pod 由受 Deployment
管理建立的 ReplicaSet
進行管理建立。
Deployment
是一種 Kubernetes 資源,可確保它的 pod 始終保持執行狀態。如果 pod 因為任何原因消失(例如節點從叢集中消失或由於該 pod 已從節點中逐出),則 Deployment
會注意到缺少了 pod 並建立替代者。 P89
上圖的節點 1 有兩個節點, Pod A 是被直接建立的,而 Pod B 由 Deployment
管理。節點異常退出後, Deployment
會建立一個新的 Pod B2 來替換減少的 Pod B ,而 Pod A 由於沒有東西負責重建而完全丟失。 P89
Deployment
的操作 P90
Deployment
會持續監控正在執行的 pod 列表,並保證匹配標籤選擇器(03. pod: 執行於 Kubernetes 中的容器 中介紹過標籤選擇器及使用方式)的 pod 數目與期望相符。 P90
介紹控制器的協調流程 P91
Deployment
的工作是確保 pod 數量始終與其標籤選擇器匹配。 P91
瞭解 Deployment 的三部分 P91
- 標籤選擇器 (label selector) :用於確定
Deployment
作用域中有哪些 pod - 副本個數 (replica count) :指定應執行的 pod 數量
- pod 模版 (pod template) :用於建立新的 pod 副本
Deployment
的副本個數、標籤選擇器和 pod 模版都可以隨時修改,但只有副本數目但變更會影響現有的 pod 。 P92
更改控制器的標籤選擇器或 pod 模版的效果 P92
更改標籤選擇器和 pod 模版對現有的 pod 沒有影響。更改標籤選擇器會使現有的 pod 脫離 Deployment
的範圍,因此控制器會停止關注它們。更改模版僅影響由此 Deployment
建立的新 pod 。 P92
使用 Deployment
的好處 P92
- 確保 pod 持續執行:在現有 pod 丟失時啟動一個新 pod
- 叢集節點發生故障時,為故障節點上執行的受
Deployment
管理的所有 pod 建立替代副本 - 輕鬆實現 pod 水平伸縮——手動和自動都可以
注意: pod 例項永遠不會重新安置到另一個節點。 Deployment
會建立一個全新的 pod 例項,它與正在替換的例項無關。 P92
建立一個 Deployment
P92
我們可以通過以下描述檔案 kubia-deployment.yaml
建立一個 Deployment
,它確保符合標籤選擇器 app=kubia
的 pod 例項始終是三個。
# 遵循 v1 版本的 Kubernetes API
apiVersion: apps/v1
# 資源型別為 Deployment
kind: Deployment
metadata:
# Deployment 的名稱
name: kubia
spec:
# 指定與標籤選擇器匹配的 pod 數目為 3
replicas: 3
# 指定 Deployment 操作物件
selector:
# 需要匹配以下指定的標籤
matchLabels:
app: kubia
# 啟動 pod 使用的模版(可以發現模版內容與 kubia-manual.yaml 對應部分一致)
template:
metadata:
# 指定標籤為 app=kubia
labels:
app: kubia
spec:
containers:
# 容器的名稱
- name: kubia
# 建立容器所使用的映象
image: idealism/kubia
# 應用監聽的埠
ports:
- containerPort: 8080
protocol: TCP
模版中的 pod 標籤必須和 Deployment
的標籤選擇器匹配, API 伺服器會校驗 Deployment
的定義,不會接受錯誤配置。 P93
若不指定選擇器,它會自動根據 pod 模版中的標籤自動配置,這樣可以讓描述檔案更簡潔。 P93
使用 Deployment
P94
kubectl create -f kubia-deployment.yaml
會建立一個名為 kubia 的 Deployment
,它會根據 pod 模版啟動三個新 pod 。 P94
kubectl get pods
可以檢視當前建立的所有 pod :
NAME READY STATUS RESTARTS AGE
kubia-9495d9bf5-5dwj7 1/1 Running 0 3m53s
kubia-9495d9bf5-5j6zr 1/1 Running 0 3m53s
kubia-9495d9bf5-w98f6 1/1 Running 0 3m53s
檢視 Deployment
對已刪除的 pod 的響應 P94
kubectl delete pod kubia-9495d9bf5-5dwj7
會刪除一個 pod ,然後再次檢視當前所有 pod ,可以發現會有 4 個 pod ,因為刪除的 pod 正在終止,並且正在建立一個新的 pod : P94
NAME READY STATUS RESTARTS AGE
kubia-9495d9bf5-5dwj7 1/1 Terminating 0 24m
kubia-9495d9bf5-5j6zr 1/1 Running 0 24m
kubia-9495d9bf5-kxcw5 0/1 ContainerCreating 0 9s
kubia-9495d9bf5-w98f6 1/1 Running 0 24m
控制器如何建立新的 pod P95
控制器通過建立一個新的替代 pod 來響應 pod 的刪除操作。但它並沒有對刪除本身作出反應,而是針對由此產生對狀態—— pod 數量不足作出反應。 P95
應對節點故障 P96
接下來我們將關閉一個節點的網路介面來模擬節點故障。 P96
minikube ssh --node='m02'
: 進入節點內部sudo ifconfig eth0 down
: 關閉該節點的網路介面kubectl get nodes
: 發現節點minikube-m02
的狀態為未就緒 (NotReady
)kubectl get pods
: 可能仍然會看到與之前相同的三個 pod ,因為 Kubernetes 在重新排程 pod 之前會等待一段時間(如果節點因臨時網路故障或 Kubelet 重啟而無法訪問)。如果節點在幾分鐘內無法訪問,Deployment
會立即啟動一個新的 pod 。
將 pod 移入/移出 Deployment
的作用域 P97
由 Deployment
建立的 pod 並不是繫結到 Deployment
。在任何時刻, Deployment
管理與標籤選擇器匹配的 pod 。通過更改 pod 的標籤,可以將它從 Deployment
的作用域中新增或刪除。 P97
儘管一個 pod 沒有繫結到一個 Deployment
擁有的 ReplicaSet
,但該 pod 在 metadata.ownerReferences
中儲存它屬於哪一個 ReplicaSet
。 P98
給 Deployment
管理的 pod 加標籤 P98
kubectl label pod kubia-9495d9bf5-5mmhb type=special
: 給 pod 新增其他標籤不會影響 Deployment
的管理範圍,它只關心該 pod 是否具有標籤選擇器中引用的所有標籤。 P98
更改已託管的 pod 的標籤 P98
kubectl label pod kubia-9495d9bf5-5mmhb app=foo --overwrite
: 更改其中一個 pod 的標籤將使其不再與 Deployment
的標籤選擇器相匹配,並不再由 Deployment
管理,只剩下兩個匹配的 pod 。因此, Deployment
會啟動一個新的 pod ,將數目恢復為三。 P98
更改 Deployment
的標籤選擇器 P100
更改 Deployment
的標籤選擇器會讓所有的 pod 脫離 Deployment
的管理,導致它建立三個新的 pod 。你永遠不會修改控制器的標籤選擇器,但會時不時地更改它的 pod 模版。 P100
修改 pod 模版 P100
Deployment
的 pod 模版可以隨時修改,可以使用 kubectl edit deployment kubia
編輯 Deployment
。更改後會重新建立一個新的 ReplocaSet
,並使原有的 ReplocaSet
的副本數變為 0 。因此,使用 kubectl get pods
將發現有 6 個 pod ,pod 的字首是對應的 ReplocaSet
的名稱。
NAME READY STATUS RESTARTS AGE
kubia-9495d9bf5-kxcw5 1/1 Terminating 0 78m
kubia-9495d9bf5-w98f6 1/1 Terminating 0 102m
kubia-9495d9bf5-xn67d 1/1 Terminating 0 29m
kubia-bc974964b-bp4l2 1/1 Running 0 22s
kubia-bc974964b-r29j2 1/1 Running 0 39s
kubia-bc974964b-xl677 1/1 Running 0 14s
若通過 kubectl edit replicaset kubia-bc974964b
直接修改 Deployment
擁有的 ReplicaSet
例項。這樣效果和直接修改 Deployment
類似,也會建立一個新的 ReplicaSet
,並使原有的 ReplocaSet
的副本數變為 0 。這樣修改不會將新的 pod 模版同步回原有的 Deployment
,但刪除 Deployment
時仍然會刪除所有相關的 ReplocaSet
及其管理的 pod 。
水平縮放 pod P101
kubectl scale deployment kubia --replicas=10
: 可以修改 Deployment
需要保持的 pod 例項的數量(02. 開始使用 Kubernetes 和 Docker中介紹過使用該命令進行伸縮)。 P101
也可以通過 kubectl edit deployment kubia
修改 spec.replicas
的數量,從而更改需要保持的 pod 例項的數量。 P102
刪除一個 Deployment
當通過 kubectl delete deployment kubia
刪除 Deployment
時,對應的 ReplicaSet
和 pod 都會被刪除。
而通過 kubectl delete replicaset kubia-bc974964b
刪除 ReplicaSet
時,對應的 pod 會被刪除,但由於 Deployment
會重新建立一個 Replicaset
,所以又會自動建立對應數量的 pod 。
當通過 kubectl delete deployment kubia --cascade=false
刪除 Deployment
時,會保留對應的 ReplicaSet
和 pod ,這樣ReplicaSet
不再受管理,但是 pod 仍然受 ReplicaSet
管理。當重新建立符合要求的 Deployment
時, ReplicaSet
又會受到管理。
同樣地,通過 kubectl delete replicaset kubia-bc974964b --cascade=false
刪除 ReplicaSet
時,也會保留對應的 pod 。這樣 pod 不再受管理。當建立符合要求的 ReplicaSet
時,這些 pod 又會受到管理。
使用 ReplicaSet
P104
注:書中原本上一節講得是 ReplicationController
,但我直接使用 Deployment
進行實踐,並依照現在的結果進行了修改。目前推薦使用 Deployment
,並且 ReplicaSet
是受 Deployment
管理的,所以不再詳細實踐本節內容。
使用更富有表達力的標籤選擇器 P106
基於 kubia-deployment.yaml
建立一個新的描述檔案 kubia-deployment-matchexpressions.yaml
,並將 spec.selector.matchLabels
屬性替換為 spec.selector.matchExpressions
: P107
...
spec:
...
# 指定 Deployment 操作物件
selector:
# 需要匹配滿足以下要求的標籤
matchExpressions:
# 標籤名為 app 的值在 ["kubia"] 中
- app: app
operator: In
values:
- kubia
...
matchExpressions
執行給選擇器新增額外的表示式。每個表示式都必須包含一個 key 、一個 operator ,並且可能還有一個 values 的列表(取決於 operator )。共有四個有效的運算子: P107
In
: 標籤的值必須與其中一個指定的 values 匹配NotIn
: 標籤的值與任何指定的 values 都不匹配Exists
: pod 必須包含一個指定名稱的標籤(不關心值)。使用此運算子時,不應指定 values 欄位DoesNotExist
: pod 不得包含指定名稱的標籤。使用此運算子時,不應指定 values 欄位
如果指定了多個表示式,則所有這些表示式都必須為 true 才能使選擇器與 pod 匹配。如果同時指定 matchLabels
和 matchExpressions
,則所有標籤都必須匹配,且所有表示式都必須為 true 才能使選擇器與 pod 匹配。 P107
使用 DaemonSet
在每個節點上執行一個 pod P107
DaemonSet
可以讓 pod 在叢集中的每個節點上執行,並且每個節點正好有一個執行的 pod 例項。 P107
使用 DaemonSet
在每個節點上執行一個 pod P108
DaemonSet
沒有副本數的概念,它確保建立足夠的 pod ,並在每一個節點上部署一個 pod 。如果節點下線, DaemonSet
不會重新建立 pod ;但新節點新增到叢集中,它會立刻部署一個新的 pod 例項到該節點。 P108
使用 DaemonSet
只在特定的節點上執行 pod P109
DaemonSet
將 pod 部署到叢集的所有節點上,除非通過 pod 模版中的 spec.nodeSelector
屬性指定這些 pod 只在部分節點上執行。 P109
注意:節點可以被設定為不可排程,防止 pod 被部署到節點上。但 DaemonSet
會將 pod 部署到這些節點上,因為無法排程但屬性只會被排程器使用,而 DaemonSet
的目的是執行系統服務,即使在不可排程的節點上,系統服務通常也需要執行。 P109
用一個例子來解釋 DaemonSet
P109
假設有一個名為 ssd-monitor
的守護程式,它需要在包含 SSD 的所有節點上執行。包含 SSD 的節點已被新增了 disk=ssd
標籤,所以我們需要建立一個 DaemonSet
,它只在擁有上述標籤的節點上執行守護程式。 P109
建立一個 DaemonSet
描述檔案 P110
為了模擬 ssd-monitor
的監控程式,我們將使用以下 Dockerfile
建立一個每 5 秒中列印 SSD OK
的映象。
FROM busybox
ENTRYPOINT while true; do echo 'SSD OK'; sleep 5; done
為了將 ssd-monitor
部署到符合要求的每個節點上,我們還需要使用以下 ssd-monitor-daemonset.yaml
描述檔案進行部署。
# 遵循 apps/v1 版本的 Kubernetes API
apiVersion: apps/v1
# 資源型別為 DaemonSet
kind: DaemonSet
metadata:
# DaemonSet 的名稱
name: ssd-monitor
spec:
# 指定 DaemonSet 操作物件
selector:
# 需要匹配以下指定的標籤
matchLabels:
app: ssd-monitor
# 啟動 pod 使用的模版
template:
metadata:
# 指定標籤為 app=ssd-monitor
labels:
app: ssd-monitor
spec:
# 指定選擇具有 disk=ssd 標籤的節點部署
nodeSelector:
disk: ssd
containers:
# 容器的名稱
- name: main
# 建立容器所使用的映象
image: idealism/ssd-monitor
實踐 P110
kubectl create -f ssd-monitor-daemonset.yaml
: 按照指定的描述檔案建立一個DaemonSet
kubectl get daemonsets
: 可以發現所有的值都是 0 ,因為目前還沒有節點擁有disk=ssd
標籤kubectl get pods
: 可以發現目前還沒有 podkubectl label node minikube-m03 disk=ssd
: 給節點minikube-m03
打上標籤disk=ssd
kubectl get pods
: 可以發現剛剛啟動了一個 podNAME READY STATUS RESTARTS AGE ssd-monitor-bbqbp 0/1 ContainerCreating 0 2s
kubectl label node minikube-m03 disk=hdd --overwrite
: 將節點minikube-m03
的標籤disk=ssd
修改為disk=hdd
kubectl get pods
: 可以發現剛剛啟動的 pod 正在終止NAME READY STATUS RESTARTS AGE ssd-monitor-bbqbp 1/1 Terminating 0 2m37s
執行執行單個任務的 pod P112
介紹 Job
資源 P112
Kubernetes 通過 Job
資源支援執行一種 pod ,該 pod 子啊內部程式成功結束時,不重啟容器。一旦任務完成, pod 就被認為處於完成狀態。 P112
在節點發生故障時,該節點上由 Job
管理的 pod 將被重新安排到其他節點。如果程式本身異常退出(程式返回錯誤退出碼時),可以將 Job
配置為重新啟動容器。 P112
定義 Job
資源 P113
為了模擬耗時的任務,我們將使用以下 Dockerfile
建立一個呼叫 sleep 120
命令的映象。
FROM busybox
ENTRYPOINT echo "$(date) Batch job starting"; sleep 120; echo "$(date) Finished succesfully"
為了管理部署 batch-job
,我們還需要使用以下 batch-job.yaml
描述檔案進行部署。
# 遵循 batch/v1 版本的 Kubernetes API
apiVersion: batch/v1
# 資源型別為 Job
kind: Job
metadata:
# Job 的名稱
name: batch-job
spec:
# 啟動 pod 使用的模版
template:
metadata:
# 指定標籤為 app=batch-job
labels:
app: batch-job
spec:
# Job 不能使用 Always 為預設的重啟策略
restartPolicy: OnFailure
containers:
# 容器的名稱
- name: main
# 建立容器所使用的映象
image: idealism/batch-job
設定 Job
的重啟策略為 OnFailure
或 Never
可以防止容器在完成任務時重新啟動。 P114
Job
執行一個 pod P114
kubectl create -f batch-job.yaml
: 根據描述檔案建立指定的Job
kubectl get jobs
: 檢視 job ,可以發現剛剛建立的Job
NAME COMPLETIONS DURATION AGE batch-job 0/1 5s 5s
kubectl get pods
: 檢視 pod ,可以發現Job
建立的 pod 正在執行NAME READY STATUS RESTARTS AGE batch-job-d59js 1/1 Running 0 10s
kubectl get pods
: 等兩分鐘後再檢視 pod ,可以發現Job
建立的 pod 狀態已經變為Completed
,即任務已經完成。 pod 未被刪除,所以我們可以檢視 pod 的日誌NAME READY STATUS RESTARTS AGE batch-job-d59js 0/1 Completed 0 2m56s
kubectl logs pod batch-job-d59js
: 檢視 pod 的日誌Sun Jun 7 22:36:04 UTC 2020 Batch job starting Sun Jun 7 22:38:04 UTC 2020 Finished succesfully
kubectl get jobs
: 再次檢視 job ,可以發現需要執行的 1 個 pod 已經完成NAME COMPLETIONS DURATION AGE batch-job 1/1 2m45s 6m25s
在 Job
中執行多個 pod 例項 P114
在 Job
配置中設定 spec.completions
和 spec.parallelism
可以讓 Job
建立多個 pod 例項,並允許以並行的方式執行它們。 P114
基於 batch-job.yaml
建立一個新的描述檔案 multi-completion-parallel-batch-job.yaml
,並新增 spec.completions
和 spec.parallelism
屬性,指定需要成功執行完成 5 個 pod ,最多 2 個 pod 並行執行 : P115
...
spec:
# 必須確保 5 個 pod 執行完成
completions: 5
# 最多 2 個 pod 可以並行執行
parallelism: 2
...
-
kubectl create -f multi-completion-parallel-batch-job.yaml
: 根據描述檔案建立指定的Job
-
kubectl get pods
: 檢視執行的 pod ,可以發現共有兩個 pod 正在執行。只要一個 pod 執行完成,Job
將執行下一個 pod ,直至 5 個 pod 都成功完成NAME READY STATUS RESTARTS AGE multi-completion-parallel-batch-job-fpwv5 1/1 Running 0 37s multi-completion-parallel-batch-job-m4cqw 1/1 Running 0 37s
限制 Job
pod 完成任務的時間 P116
Pod.spec.activeDeadlineSeconds
: 可以指定一個 pod 最長存活時間,超時則終止 pod 並標記Job
失敗,可以用來限制 pod 完成任務的時間Job.spec.backoffLimit
: 可以配置一個Job
在被標記為失敗前最多嘗試的次數,預設為 6 次
安排 Job
定期執行或在將來執行一次 P116
建立一個 CronJob
P116
為了每 15 分鐘執行一次前面的任務,我們需要建立以下 cronjob.yaml
描述檔案:
# 遵循 batch/v1beta1 版本的 Kubernetes API
apiVersion: batch/v1beta1
# 資源型別為 CronJob
kind: CronJob
metadata:
# Job 的名稱
name: batch-job-every-fifteen-minutes
spec:
# Cron 表示式表明當前任務在每天每小時的 0, 15, 30, 45 分執行
schedule: "0,15,30,45 * * * *"
# 指定最遲必須在預定時間後 15 秒內開始執行,否則就標記為一次失敗的 `Job`
startingDeadlineSeconds: 15
# 建立 Job 使用的模版(可以發現和 batch-job.yaml 的 spec 部分基本一致)
jobTemplate:
spec:
# 啟動 pod 使用的模版
template:
metadata:
# 指定標籤為 app=periodic-batch-job
labels:
app: periodic-batch-job
spec:
# Job 不能使用 Always 為預設的重啟策略
restartPolicy: OnFailure
containers:
# 容器的名稱
- name: main
# 建立容器所使用的映象
image: idealism/batch-job
kubectl get cronjobs
: 可以檢視所有的 CronJob
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
batch-job-every-fifteen-minutes 0,15,30,45 * * * * False 0 <none> 8s
CronJob
總是為計劃中配置的每個執行建立一個 Job
,但可能會有以下兩種問題:
- 同時建立兩個
Job
:保證任務是冪等的 - 沒有建立
Job
:保證下一個任務能執行完成錯過的任何工作
本文首發於公眾號:滿賦諸機(點選檢視原文) 開源在 GitHub :reading-notes/kubernetes-in-action