保持 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: 按照指定的描述文件創建一個DaemonSetkubectl get daemonsets: 可以發現所有的值都是 0 ,因為目前還沒有節點擁有disk=ssd標簽kubectl get pods: 可以發現目前還沒有 podkubectl label node minikube-m03 disk=ssd: 給節點minikube-m03打上標簽disk=ssdkubectl get pods: 可以發現剛剛啟動了一個 podNAME READY STATUS RESTARTS AGE ssd-monitor-bbqbp 0/1 ContainerCreating 0 2skubectl label node minikube-m03 disk=hdd --overwrite: 將節點minikube-m03的標簽disk=ssd修改為disk=hddkubectl 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: 根據描述文件創建指定的Jobkubectl get jobs: 查看 job ,可以發現剛剛創建的JobNAME COMPLETIONS DURATION AGE batch-job 0/1 5s 5skubectl get pods: 查看 pod ,可以發現Job創建的 pod 正在運行NAME READY STATUS RESTARTS AGE batch-job-d59js 1/1 Running 0 10skubectl get pods: 等兩分鍾后再查看 pod ,可以發現Job創建的 pod 狀態已經變為Completed,即任務已經完成。 pod 未被刪除,所以我們可以查看 pod 的日志NAME READY STATUS RESTARTS AGE batch-job-d59js 0/1 Completed 0 2m56skubectl 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 succesfullykubectl 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

