iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 10
0
Software Development

K8S - 30天從擦槍到提槍上陣學習筆記。系列 第 10

day 10 Pod(3)-生命週期, 容器探測

Pod 生命週期

參考官網

Pod 從創建到退出的過程稱為Pod生命週期, 這段過程Pod會處於多種狀態以及執行一些行為, 包含創建主容器(main container), 及其他像是初始化容器(init container), 容器啟動後鉤子(post start hook), 容器存活性探測(liveness probe), 容器就續性探測(readiness probe), 容器終止前鉤子(pre stop hook), 其它這幾項操作是否執行會取決於Pod的定義。
https://ithelp.ithome.com.tw/upload/images/20200915/20129656Yce1X5CkXi.png

圖片參考書:【Kubernetes 進階實踐】

  • init container(初始化容器):
    在Pod Spec中使用的字段為spec.initContainers, 是以列表的方式設定的。
    init container 和 Pod要運行的應用是兩個不同的container, init container指的是在容器開始運作之前要預先完成的工作, 初始化容器完成之前, Pod的狀態都會是Initializing。 如果定義多個初始化容器, 它們會依照定義的順序一一執行, 且必須等到前一個執行成功後, 下一個才會開始做,過程中任何一個初始化容器執行失敗就會再度啟動所有初始化容器重新執行工作, 除非把 restartPolicy設定為Never

    • restartPolicy 重啟策略
      容器的應用程序發生錯誤或容器申請超出限制的資源都可能導致Pod終止, 此時會根據 restartPolicy 來決定是否該重建Pod。

      restartPolicy有三種設定:

      1. Always: Pod終止就重啟, 此為default設定。
      2. OnFailure: Pod發生錯誤時才重啟。
      3. Never: 從不重啟。
  • lifecycle hook (生命週期鉤子):
    hook 在Pod Spec中使用的字段為spec.lifecycle,它會隨時檢測Pod的生命週期中發生的事件, 當對應的時間點來臨時會依照用戶指定的程序運行。

    K8s提供兩個hook:

    1. postStart: 容器創建後立刻運行。
    2. preStop: 容器終止之前運行, 在它完成之前會阻塞刪除容器的操作, 等他執行完容器才會刪除。
  • container probe (容器探測):
    用來定期確認容器健康狀態的設計, 是由kubelet定期呼叫container中定義的handler來診斷container目前是否正常運作, 透過自我檢測與修復來避免把流量導到不健康的Pod。

    K8s支持三種用在Pod探測的處理器:

    1. ExecAction: 在容器內執行命命, 再根據其回傳的狀態進行診斷, 回傳0表示成功, 其餘皆為失敗。
    2. TCPSocketAction: 透過對容器上的TCP端口進行檢查, 其端口有打開表示成功, 否則為失敗。
    3. HTTPGetAction: 透過對容器IP地址上的指定端口發起http GET 請求進行診斷, 如果回應狀態大於等於200且小於400, 則為成功, 其餘皆為失敗。

    kubelet 可以執行三種探測:

    1. livenessProbe (存活性探測): 顯示容器是否正常運作, 如果探測失敗kubelet會終止容器, 容器會依照重啟策略進行下一個動作; 如果容器不支援存活性探測, 則默認狀態為 Success
    2. readinessProbe (就緒性探測): 顯示容器是否準備好提供服務, 如果探測失敗Endpoint Controller 會從匹配的所有Service Endpoint list 刪除Pod IP; 如果容器不支援就緒性探測, 則默認狀態為 Success
    3. startupProbe (啟動探測): 顯示容器中的應用是否已經啟動, 如果啟動startupProbe則其他探測都會被禁用,直到startupProbe成功為; 如果探測失敗kubelet會終止容器, 容器會依照重啟策略進行下一個動作; 如果容器不支援存活性探測, 則默認狀態為 Success

    每次探測的回傳結果可能有下列三種:

    1. Success - 只有這個狀態表示成功
    2. Failure - 失敗
    3. Unknown - 失敗

Pod 創建過程

https://ithelp.ithome.com.tw/upload/images/20200913/20129656XdwQzeTUJb.png

圖片參考書:【Kubernetes 進階實踐】

對照上圖理解創建過程:

  1. 用戶提交Pod Spec給API Server
  2. API Server 將Pod相關訊息存入 etcd, 寫入成功就會返回訊息給用戶
  3. API Server 開始根據etcd中資訊變化
  4. K8s上的組件都會使用watch機制來追蹤檢查API Server的狀態變化
  5. kube-scheduler 透過 watcher 發現API Server創建新的Pod, 但尚未調度到工作節點
  6. kube-scheduler 將Pod綁定到工作節點上並通知API Server
  7. 調度結果由API Server 更新到 etcd儲存, 接著API Server 開始反應Pod調度結果
  8. 接收Pod調度的工作節點上的kubelet開始在節點上調用docker 啟用容器, 並把容器的啟用結果回送給API Server
  9. API Server將Pod的狀態寫到 etcd
  10. 在etcd回傳寫入成功後, API Server會把成功訊息送到kubelet上, 整個事件就完成了

Pod 終止過程

https://ithelp.ithome.com.tw/upload/images/20200914/20129656CjGOpqAhog.png

圖片參考書:【Kubernetes 進階實踐】

對照上圖理解終止過程:

  1. 用戶提交刪除Pod指令, 預設的寬限期(grace period)是 30s
  2. API Server中的Pod被更新, 如果再寬限期內未完成, API Server內的Pod狀態會被更新為dead
  3. 同步執行
    • 將Pod標記為 terminating
    • kubelet 偵測到 Pod terminating, 啟動Pod關閉流程
    • Endpoint Controller 監控到 Pod terminating , 從 Service 的 endpoint list 中移除Pod
    • 如果Pod有定義 preStop hook handler, 則在標記 terminating 就會執行, 若是在寬限期過後preStop仍未執行為, 則流程會從第二步驟重新進行一次。
  4. Pod Container 收到TERM信號
  5. 寬限期過後, 會向Pod中還在運作的process發送 SIGKILL。
  6. kubelet 請求API Server將Pod的寬限期設置為0, 此時Pod的刪除已完成, 在API Server中已消息。

預設的寬限期為30s, 可以透過kubectl delete --grace-period=<seconds>改變預設值, 若是要設定為0則要搭配 --force, 設定0表示直接強制刪除指定的Pod。

Pod phase

查看 pods 列表所使用的kubectl get pod 會列出一個STATUS欄位, 他表示目前Pod的狀態, Pod的狀態變化參考:
https://ithelp.ithome.com.tw/upload/images/20200914/201296567Rlkuhxj86.png

圖片來源

  • Pending: API Server 創建Pod對象並已存入etcd, 但尚未完成調度或仍處於下載image的過程。
  • Running: Pod已被調度到工作節點, 且Pod裡面的所有容器都已被kubelet創建完成。
  • Succeeded: Pod中所有容器都已被成功終止並且不會被重啟。
  • Failed: 至少有一個容器終止失敗並將其狀態回傳出來。
  • Unknown: 無法獲取Pod狀態, 通常是因為Node有問題。

今日小結

每天花一點時間啃一點K8s, 把它當成維生素每天補充一點, 你就會越來越強壯的。
第10天, 對自己說點打氣的話, 然後繼續回去看書吧!


上一篇
day 9 Pod(2)-Labels, Selector, Annotation
下一篇
day 11 Pod Controller(1) - ReplicaSet
系列文
K8S - 30天從擦槍到提槍上陣學習筆記。30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言