iT邦幫忙

2024 iThome 鐵人賽

0
Kubernetes

一起來看 Kubernetes 官方文件吧!系列 第 12

Day12 - 一起來看 Kubernetes 官方文件吧!- Pod lifecycle (上)

  • 分享至 

  • xImage
  •  

前言

Pod 是 k8s 中最重要的資源之一,今天就來看看 pod 的生命週期吧!

今日目標

  • 了解 pod 的生命週期
  • 了解 pods 與 container 的互動關係

Pod Lifecycle

簡單描述 pod 的生命週期:

  • Pending:開始階段,等待被排程到某個 node 上
  • Running:代表 pod 內至少一個 container 是正常的
  • Succeeded:pods 內所有的 containers 都是正常完成指令,且不會被重啟
  • Failed:取決於 pods 所有的 containers 都完成只領,且有紙少一個 container 失敗的情況 (non-zero status)
  • Unknown:通常是因為 pods 所屬的 node 無法連線導致

補充:當 pods 短時間內一直啟動失敗時,常會看見 **CrashLoopBackOff 的狀態,**但其實這並不是一種 pods 的生命週期,並且隨著失敗的次數變多,嘗試重啟的間隔也會越來越長。

Pod lifetime

當 pods 為 running 狀態時,kubelet 可以重啟 containers,並且會追蹤各種 container 的狀態來看如何讓有異常的 pods 恢復正常
k8s 有自己定義的 pods 狀態,若 APP 有特殊需求,也可以定義 APP 何為健康 (使用 Pod readiness,下面會提到)

同個 pods 的 lifetime 是只能被調度一次。每一個 pods 都有一個唯一的 uid (metadata.uid),因此即使有兩個相同 name 的 Pods,uid 也會不同。
也就是說,重新調度的行為其實是透過刪除/新建 pod 完成的。

Associated lifetimes

與 pods lifetime 相同的還有 volume (有唯一的 uid,重新掛載代表重建一個)
比如掛載在同個 Pods 裡面的 emptyDir,也是使用這個機制去處理 pods 重建的
https://ithelp.ithome.com.tw/upload/images/20241225/20168801xW0XRiVSUu.png

Container states

container 即為 pods 裡面真正執行的 process,有三種狀態:

  • Waiting:等待開啟,常見的例子就是正在拉取 container image
  • Running:正常運行,若是有設定 postStart hook 的話,Running 的 container 即代表已經通過此 hook
  • Terminated:container 被關閉或是工作完成,當 container 為此狀態時,可以透過 kubectl describe 檢查到 reason 與 exit code,方便診斷原因
    若 container 有設定 prestop hook,則會在 Terminated 前完成

How Pods handle problems with containers

在 pods 有個欄位為 restartPolicy (預設為 Always),可以決定當 pods 掛掉時,會怎麼處理內部的 containers
有以下幾個步驟:

  1. Initial crash:k8s 會根據 restartPolicy 定義立刻重啟。
  2. Repeated crashes:當 initial crash 短時間內太多次,將會把重啟時間拉長,以避免系統負荷過重
  3. CrashLoopBackOff state:代表已經套用延遲時間重啟,間隔會越來越長 (以指數型成長,10s → 20s → 40s,最長到 5 分鐘)
  4. Backoff reset:當 container 已經正常運作一段時間 (e.g. 10 分鐘),則重啟間隔時間就會被重置。

常見的 CrashLoopBackOff 原因有以下:

  • APP 本身的設定錯誤,導致啟動指令失敗
  • 設定錯誤,可能是變數設定錯誤或是有少設定檔案
  • 資源限制,container 沒有足夠的 CPU/memory 執行指令
  • Health checks 無法在預期的時間內完成,導致失敗重啟
  • Container liveness/startup probes 回傳 Failure 的 exit code,也會導致 container 被重啟

基於以上五點,排查的思路也有五點:

  1. 檢查 Logs,使用 kubectl logs <name-of-pods>
  2. 檢查 events,使用 kubectl describe pods <name-of-pods> 查看 event,或許可以看到一些提示。
  3. 檢查設定檔案:確保有載入正確變數,或者有掛載正確的設定檔。
  4. 檢查資源限制:若是 container 觸發到資源 limit,也會導致 container 重啟。
  5. debug APP:也有可能是 APP 本身的問題,例如 build image 時 entrypoint 寫錯等等。

Container restart policy

pods 的預設 restartPolicy 為 Always,該值會直接帶入 pods 內的 “正規” container 內 (除了 initcontainerSidecar container 會忽略 pod-level 的 restartPolicy 設定)

對應的三種設定為:

  • Always:就是會一直重開囉
  • OnFailure:當結束時為 non-zero exit status 時才重開
  • Never:不重開,通常是用於一次性的作業等

Pod conditions

在 pods 建立之後,會有五個布林值分別代表 pods 目前的狀態:

  • PodScheduled: pods 已經成功被排程到某個 node
  • PodReadyToStartContainers: (beta feature; enabled by default) pods 已經準備好建立 container (應該是指 pause container 已經準備好,也就是 k8s 內負責設定網路/PID 的 pause container)
  • ContainersReady:pods 內的所有 container 都是 Ready 狀態
  • Initialized: 所有 init conatiners 都正常完成了
  • Ready: Pods 已經準備好接受從 service 來的流量 (若沒有設定 readniness probe,則 pods 一進入 running 狀態就會開始接收流量)

補充:這五點的其中兩點 ContainersReadyReady 蠻容易混淆的,筆者是以 Ready 代表整個 pods 都啟動完畢來記,而 Containers Ready 則是 pods 內的 containers 都 Ready
其實我覺得… 似乎差不多?

這幾個欄位都可以透過 kubectl describe 指令查看,若是使用 kubectl get -o yaml 的話,則會是在最下面 status 的部分以 array 的方式呈現。

比如執行:

kubectl describe po -n kube-system etcd-k8s-master1
kubectl get po -n kube-system etcd-k8s-master1 -o yaml

https://ithelp.ithome.com.tw/upload/images/20241225/20168801xuvA3W9bPv.png
https://ithelp.ithome.com.tw/upload/images/20241225/20168801s2A5fj7tPM.png

在 status 欄位還可以看到最後檢查時間,若失敗還會有 reason, message 等欄位提供管理者閱讀。

今天就先到這邊,明天再來看看比較重要的 Probe 如何設定

結論

在平常操作 k8s 時,完全理解 pods Lifecycle 或許幫助不大,但當 Pods 出狀況時,就會必須要知道這些可能會出現的訊息,才有辦法快速的修復服務。

參考

https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle


上一篇
Day11 - 一起來看 Kubernetes 官方文件吧!- Node Shutdowns
下一篇
Day13 - 一起來看 Kubernetes 官方文件吧!- Pod lifecycle (下)
系列文
一起來看 Kubernetes 官方文件吧!19
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言