此篇分享是要說關於 POD 對象的生命週期,POD 對象從建立到終止退出為它們的一個生命週期。而在這之間可以透過 POD 的定義執行一些創建容器、初始化容器等操作。在 openshift
中提供該生命週期流程圖,如下所示
這邊使用 openshift
文章內容進行翻譯解釋其流程
infra
容器,以建立其它容器加入的名稱空間,依照此理解應該是指 pause
容器init
容器,可將其用於 POD 範圍內的初始化main
容器和 post-start hook
同時啟動,在範例中為4秒鐘liveness
和 readiness probes
pre-stop hook
,最後在寬限期後終止 main
容器不管 POD 是被手動建立、或是透過一些 POD 控制器建立,POD 應當處於以下幾個定相
Pending
Running
kubelet
創建Failed
Succeeded
Unknown
API Server
無法取得 POD 狀態,通常是與 kubelet
通訊時出錯POD 是 K8s 中的一個核心元件,理解其建立過程對於系統上的運行有一定的幫助。這邊將利用下圖說明建立過程
kubectl
或其它 API,客户端提交 POD
Spec
給 API Server
API Server
嘗試將 POD 對象相關訊息存入 etcd
中,待寫入操作執行完成,API Server
即回傳確認訊息至客户端API Server
開始反映 etcd
中的狀態變化Kubernetes
元件都使用 watch
機制来追蹤檢查 API Server
上相關的變化scheduler
透過其 watcher
觀察到 API Server
創建了新的 POD 對象,但尚未绑定至任何節點scheduler
幫 POD 對象選擇節點並將結果訊息更新至 API Server
API Server
更新至 etcd
,而 API Server
也會反映此 POD
對象的調度結果kubelet
嘗試在節點上調用 Docker
,並把容器結果狀態回傳至 API Server
API Server
將 POD
狀態訊息存入 etcd
中etcd
確認寫入操作成功完成後,API Server
將確認訊息發送至相關的kubelet
,事件將透過它被接受main
容器啟動之前要運行的容器,常用於為 main
容器執行一些預先操作。init
容器需要運行完成到結束,若 init
容器運行失敗,那 K8s
需要重啟它直到成功完成,若 restartPolicy
字段是 Never
,則該 init
容器運行失敗時,不會被重啟。這在像是等待其它關聯的元件、從一些倉庫獲取配置等。此字段在 spec
中以 initContainers
列表方式定義。
容器生命週期鉤子(lifecycle hook)使它能夠感知其自身生命周期管理中的事件,並在相應的時刻到来時運行由客戶端指定的處裡程序。K8s
提供兩種方式
hook
操作,不過 K8s
無法確保它一定會於容器中的ENTRYPOINT
之前運行hook
操作,它以同步的方式調用,因此在其完成之前會阻塞刪除容器的操作的調用上面兩種方式定義於 spec
中 lifecycle
字段。
容器探測(container probe)是 POD 生命周期中的一項任務,它是 kubelet
對容器周期性執行的健康狀態診斷,該操作由容器的處理器(handler)定義。K8s
定義了三種方式
這三種方式會回應以下三種狀態
kubelet
可在容器上執行下面兩種類型的檢測
kubelet
要每隔幾秒執行一次 liveness probe
kubelet
在第一次執行 probe
之前要的等待幾秒鐘restart Policy
決定未來此範例使用 exec
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness-exec
name: liveness-exec
spec:
containers:
- name: liveness-demo
image: busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 60; rm -rf /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- test
- -e
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
在這資源清單上,POD
中只有一個容器。periodSeconds
字段指定了 kubelet
應該每 5 秒執行一次存活探測(livenessProbe
字段)。 initialDelaySeconds
字段向 kubelet
在執行第一次探測前應該等待 5 秒。kubelet
在容器内執行 test -e /tmp/healthy
進行探测。如果執行成功且返回值為 0
,kubelet
會認為此容器是健康存活的。如果返回非 0
值,kubelet
會終止此容器並重新啟動。
$ kubectl describe pod/liveness-exec
....
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 21s default-scheduler Successfully assigned default/liveness-exec to gke-cluster-1-default-pool-7dc8b11b-cxs1
Normal Pulling 19s kubelet, gke-cluster-1-default-pool-7dc8b11b-cxs1 Pulling image "busybox"
Normal Pulled 19s kubelet, gke-cluster-1-default-pool-7dc8b11b-cxs1 Successfully pulled image "busybox"
Normal Created 19s kubelet, gke-cluster-1-default-pool-7dc8b11b-cxs1 Created container liveness-demo
Normal Started 19s kubelet, gke-cluster-1-default-pool-7dc8b11b-cxs1 Started container liveness-demo
30 秒後
$ kubectl describe pod/liveness-exec
....
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 73s default-scheduler Successfully assigned default/liveness-exec to gke-cluster-1-default-pool-7dc8b11b-cxs1
Normal Pulling 71s kubelet, gke-cluster-1-default-pool-7dc8b11b-cxs1 Pulling image "busybox"
Normal Pulled 71s kubelet, gke-cluster-1-default-pool-7dc8b11b-cxs1 Successfully pulled image "busybox"
Normal Created 71s kubelet, gke-cluster-1-default-pool-7dc8b11b-cxs1 Created container liveness-demo
Normal Started 71s kubelet, gke-cluster-1-default-pool-7dc8b11b-cxs1 Started container liveness-demo
Warning Unhealthy 3s (x2 over 8s) kubelet, gke-cluster-1-default-pool-7dc8b11b-cxs1 Liveness probe failed:
再 30 秒後
$ kubectl describe pod/liveness-exec
...
Restart Count: 1 # 被重啟一次
...
詳細可參考以下官方文章
此字段定義在 spec
中 restartPolicy
,POD
可能會發生故障,而對這故障的 POD
要做重啟或是不做任何策略都是藉由 restartPolicy
定義。
我們以下圖做說明
API Server
發送刪除 POD 的請求API Server
中的 POD 會隨著時間的推移而更新,在寬限期 30秒内(預設),POD 被視為 dead
Terminating
狀態kubelet
在監控到 POD 轉為 Terminating
狀態同時啟動 POD 關閉過程Service
資源的端點列表中移除preStop
,則在其標記為 terminating
後即會以同步的方式啟動運行,如果寬限期結束後,preStop
仍未執行完成,則第 2 步將被重新執行並額外取得一個 2 秒的寬限期TERM
訊號SIGKILL
訊號Kubelet
請求 API Server
將此 POD
資源的寬限期設置為 0 從而完成刪除作業