Kubernetes 設計模式筆記 —— Health Probe

Health Probe 模式主要關注 Kubernetes 如何獲取某個應用的健康狀態。爲了實現完全自動化,一個雲原生應用必須是高度可觀測的,從而 Kubernetes 能夠推斷應用的狀態,檢測應用是否已經啓動,是否已經準備好接收請求。
這些觀測結果會影響 Pod 的生命週期管理,以及網絡流量被路由到應用的具體路徑。

Kubernetes 會定期檢測容器中進程的狀態,如果有錯誤發生,就立即重啓該容器。然而在實踐中,通過檢查進程狀態來確定應用是否健康,並不總是有效。
很多情況下應用提供的服務中斷了,但進程仍舊在運行。比如 Java 應用有可能拋出 OutOfMemoryError 同時 JVM 進程仍在運行。此外,應用還有可能因爲無限循環、死鎖或者緩存異常等原因凍結。
因此 Kubernetes 需要一種可靠的方式來檢查應用的健康狀態,不關注應用的內部工作流程,而是通過某些指標,衡量應用能否對外提供服務。

軟件行業已經接受了這樣一個事實,即寫出完全沒有 bug 的軟件是不現實的。因此當面對 failures 時,可以把關注點從避免 bug 轉移到如何快速檢測到失效並自動恢復。
但錯誤檢測並不是一個簡單的對所有應用通用的任務,存在很多不同的對於錯誤的定義,並且不同類型的錯誤也需要不同的應對方式。

Process Health Checks

process health check 是最簡單的一種 health check 方式,由 Kubelet 持續對容器進程進行檢測。若容器進程沒有處於運行狀態,即對其進行重啓。
如果應用本身能夠檢測到任意類型的錯誤並自行終止,憑藉 process health check 就足夠完成健康檢查任務。

Liveness Probes

假如應用會進入某種死鎖狀態,進程並未停止運行,因而從 process health check 的角度看應用仍然是健康的。Kubernetes 可以通過 liveness probes 來檢測此類錯誤。
能夠從應用外部執行健康檢測,而不是僅僅依靠應用本身,這一點是非常重要的。因爲有些錯誤有可能會阻止應用本身的 watchdog 對外報告異常。
liveness probes 看上去和 process health check 非常相似,它們都會在檢測到異常時重啓容器。但前者提供了更多的靈活性:

  • HTTP probe:向容器的 IP 地址發起 HTTP GET 請求,期待獲取一個成功的 HTTP 響應碼(200 - 399)
  • TCP Socket probe:測試是否能完成完整的 TCP 連接
  • Exec probe:在容器內部執行任意的命令,期待獲取一個成功的退出碼(0)

基於 HTTP 的 liveness probe 示例:

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-liveness-check
spec:
  containers:
  - image: k8spatterns/random-generator:1.0
    name: random-generator
    env:
    - name: DELAY_STARTUP
      value: "20"
    ports:
    - containerPort: 8080
    protocol: TCP
    livenessProbe:
      httpGet:
        path: /actuator/health
        port: 8080
      initialDelaySeconds: 30

其中 httpGet 中的 path 項用於配置 HTTP probe 執行健康檢測時請求的端點;initialDelaySeconds 用於配置執行第一次檢測前等待的時間,以等待應用啓動後完成 warm up。

需要注意的是,未通過 liveness probe 檢查的後果就是容器被重啓,若容器重啓對於解決問題沒有任何效果,則 liveness probe 本身也不會再有任何其他作用。

Readiness Probes

Liveness 檢查通過殺掉不健康的容器並將它們替換爲新的容器實例,來確保應用處於健康狀態。但有些時候容器遇到問題,重啓它們並不會令其恢復健康。最常見的情況就是容器正處於啓動過程中,還沒有準備好處理任何請求。或者有可能容器負載過高導致延遲極度增長。

在上述場景下,Kubernetes 提供了 readiness probe 特性。Readiness 檢查和 Liveness 檢查提供的檢測方法是一樣的(都是 HTTP、TCP 和 Exec),只有觸發的操作不同。
失敗的 Readiness 檢查會將容器從 Service 端點移除,確保其不再對外提供任何服務。它關注的重點在於容器是否已經準備好,有些容器在啓動時需要一定的 warm up 時間才能處理請求。
Readiness probe 在容器啓動後依然會定期運行,從而將不能對外提供服務的容器屏蔽掉,保證未準備好的容器不會接收到外部的請求。

即 Liveness probe 觸發的操作是重啓容器,目的是不健康的容器儘可能恢復服務;Readiness probe 觸發的操作是將容器從 Service 移除,目的是確保不健康的容器不會對外提供服務,用戶的請求只會轉發到健康的容器。
當然在容器重啓時,Kubernetes 也會盡力確保該容器不會再收到用戶請求,不管 Readiness probe 是否通過。

Readiness probe 示例:

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-readiness-check
spec:
  containers:
  - image: k8spatterns/random-generator:1.0
    name: random-generator
    readinessProbe:
      exec:
        command: [ "stat", "/var/run/random-generator-ready" ]

Process health check 和 liveness probe 的目的都是通過重啓容器來使應用能從錯誤中自動恢復。Readiness probe 則力求爲處於恢復中的容器爭取足夠的時間。

總結

容器技術爲打包和運行應用實現了一系列統一的接口,從而可以將應用作爲黑盒(black box)看待。
然而任何致力於成爲雲原生應用的容器,必須爲運行時環境提供一系列必要的 API,對容器的健康狀態進行統一的觀測,並執行對應的操作。這是容器能統一地實現自動化升級和生命週期管理的基礎需求,從而提高系統的穩定性和用戶體驗。
這意味着容器化應用必須爲多種不同的健康檢測(liveness 和 readiness)提供需要的 API。
甚至更優異的應用還必須爲管理平臺提供其他手段,以方便更好地觀測容器化應用的狀態,比如與 Prometheus 進行整合。將應用視爲一種黑盒,同時實現必須的 API 接口,方便平臺對其進行監控和管理。

參考資料

Kubernetes Patterns

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章