Pod的生命週期包括初始化容器,容器啓動之後鈎子函數,就緒探測,存活探測,容器關閉前Hook函數,對應的流程圖如下:

kubernetes preStop_Pod

Pod週期的過程如下5步:
1.初始化容器階段初始化pod中每一個容器,他們是串行執行的,執行完成後就退出了
2.啓動主容器main container
3.在main container剛剛啓動之後可以執行post start命令
4.在整個main container執行的過程中可以做兩類探測:liveness probe(存活探測)和readiness probe(就緒探測)
5.在main container結束前可以執行pre stop命令

kubernetes preStop_初始化_02

在 Pod 完整的生命週期中,存在着 5 種不同的階段:

  • Pending:創建 Pod 對象後的初始化階段。會一直持續到 Pod 被分配給某個工作節點,鏡像被拉取到本地並啓動
  • Succeeded:對於不打算無限期運行的 Pod,其容器部署完成後的狀態
  • Running:Pod 中至少一個容器處於運行狀態
  • Failed:對於不打算無限期運行的 Pod,其容器中至少有一個由於錯誤終止
  • Unknown:由於 Kubelet 與 API Server 的通信中斷,Pod 的狀態未知。可能是工作節點掛掉或斷網

可以使用 kubectl describe 命令,查看Pod狀態

$ kubectl describe po kubia | grep Status:
Status:       Running

kubernetes preStop_kubernetes preStop_03

健康檢查探針

健康探針類型分為

  1. livenessProbe
    探活。Kubernetes 會在容器的進程終止時重啓容器,以保證應用的健康。但應用實際上有可能在進程不終止的情況下無響應,比如一個 Java 應用報出 OutOfMemoryError 錯誤,而 JVM 進程仍在運行中。
    理想情況下,Kubernetes 需要能夠檢測到此類錯誤並重啓容器。
    當然,應用自身也可以捕獲這類錯誤並令進程立即終止。但假如應用因為進入無限循環或死鎖導致無響應,又或者應用本身無法檢測到錯誤存在呢?為了確保容器能夠在這些複雜情況下重啓,應該提供一種從外部檢查應用狀態的機制。
    Kubernetes 可以通過配置 liveness probe 來檢查某個應用是否能夠正常響應,Pod 中的每個容器都可以分別配置 liveness probe。一旦應用無響應或有錯誤發生,容器就會被認為是不健康的並被終止掉。之後容器被 Kubernetes 重新啓動。
apiVersion: v1
kind: Pod
metadata :
 name: liveness
 namespace: default
spec:
 containers:
 - name: livenesscontainers image: nginx imagePullPolicy: IfNotPresent ports: - name:http containersPort:8080 command: ["/bin/bash","-c","touch /tmp/health;sleep 60;rm -rf /tmp/health;sleep 3600;"] livenessProbe: httpGet: path: /healthz port: http initialDelaySeconds: 3 periodSeconds: 3
  1. readinessProve
    就緒狀態檢查。有時,應用程序暫時無法對外部流量提供服務。 例如,應用程序可能需要在啓動期間加載大量數據或配置文件。 在這種情況下,你不想殺死應用程序,但你也不想發送請求。 Kubernetes提供了readiness probe來檢測和減輕這些情況。 Pod中的容器可以報告自己還沒有準備,不能處理Kubernetes服務發送過來的流量,此時狀態會被標記為NotReady。與livenessProbe不同的是,kubelet不會對readinessProbe的探測情況有重啓操作。
  2. startup probe
    指示容器中的應用是否已經啓動。默認的 liveness probe 配置會給應用 20 到 30s 的時間啓動,如果應用需要更長的時間才能啓動完成,容器會永遠達不到 liveness probe 檢測成功的狀態,從而進入了無限重啓的循環。
    為了防止上述情況發生,可以增大 initialDelaySeconds、periodSeconds 或 failureThreshold 的值,但也會有一定的副作用。periodSeconds * failureThreshold 的值越大,當應用不健康時重啓的時間就越長。
    Kubernetes 還提供了一種 startup probe。當容器配置了 startup probe 時,容器啓動時只有 startup probe 會執行。startup probe 可以按照應用的啓動時間配置,檢測成功之後 Kubernetes 會切換到使用 liveness probe 檢測。
    比如 Node.js 應用需要 1 分鐘以上的時間啓動,當啓動成功以後若應用狀態不正常,則在 10s 以內重啓。

如果提供了啓動探針(startup probe),則禁用所有其他探針,直到它成功為止。如果啓動探針失敗,kubelet 將殺死容器,容器服從其重啓策略進行重啓。如果容器沒有提供啓動探針,則默認狀態為成功Success。

探針有很多配置字段,可以使用這些字段精確的控制存活和就緒檢測的行為:

  • initialDelaySeconds:容器啓動後要等待多少秒後存活和就緒探測器才被初始化,默認是 0 秒,最小值是 0。
  • periodSeconds:執行探測的時間間隔(單位是秒)。默認是 10 秒。最小值是 1。
  • timeoutSeconds:探測的超時後等待多少秒。默認值是 1 秒。最小值是 1。
  • successThreshold:探測器在失敗後,被視為成功的最小連續成功數。默認值是 1。存活探測的這個值必須是 1。最小值是 1。
  • failureThreshold:當 Pod 啓動了並且探測到失敗,Kubernetes 的重試次數。存活探測情況下的放棄就意味着重新啓動容器。就緒探測情況下的放棄 Pod 會被打上未就緒的標籤。默認值是 3。最小值是 1。

Kubernetes 支持以下三種 probe 機制:

  • HTTP GET probe:會發送 GET 請求到容器的 IP 地址、端口號和 URL 路徑。如果 probe 收到正常的響應(2xx 或 3xx),該 probe 就被認定是成功的。如果服務返回了一個錯誤的響應碼,或者沒有在規定的時間內響應,則該 probe 被認定是失敗的。
  • TCP Socket probe:會嘗試打開一個 TCP 連接到容器的特定端口。若連接成功,probe 就被認定是成功的;否則失敗。
  • Exec probe:會在容器內部執行一個命令並檢查該命令的退出碼。若退出碼為 0,則 probe 被認定是成功的;否則失敗。

在容器啓動或關閉時觸發動作

可以向容器中添加 lifecycle hooks。Kubernetes 目前支持兩種類型的hook:

  • Post-start hooks:在容器啓動後執行
    post-start lifecycle hook 會在容器創建完成之後立即觸發。可以使用 exec 類型的鈎子在主進程啓動的同時執行一個額外的程序,或者 httpGet 類型的鈎子向容器中運行的應用發送 HTTP 請求,以完成初始化或預熱操作。
  • Pre-stop hooks:在容器停止前執行
    Nginx 服務在收到 TERM 信號後會立即關閉所有打開的連接並終止進程,這並不是理想的操作,不會等待正在處理的客户端請求徹底完成。
    可以使用 pre-stop hook 執行 nginx -s quit 命令舒緩地關閉 Nginx 服務。

kubernetes preStop_初始化_04

參考:
Kubernetes in Action - 管理 Pod 的生命週期pod的生命週期管理探活指針