Kubernetes探針原理詳解

[topic]

前言:

分散式系統和微服務體系結構的挑戰之一是自動檢測不正常的應用程式,並將請求(request)重新路由到其他可用系統,恢復損壞的組件。健康檢查是應對該挑戰的一種可靠方法。使用 Kubernetes,可以通過探針配置運行狀況檢查,以確定每個 Pod 的狀態。
.

摘要:Kubernetes 版本小於 v1.15 時支援 Readiness 和 Liveness 探針,在 v1.16 中添加了 startup 探針作為 Alpha 功能,並在 v1.18 中升級為 Beta。

.

一、探針類型介紹:

(1)、K8s中存在三種類型的探針:liveness probe、readiness probe和startup 探針。每類探針都支援三種探測方法

  • liveness探針:影響的是單個容器,如果檢查失敗,將殺死容器,根據pod的restartPolicy來操作。
  • readiness探針:影響的是整個pod,即如果pod中有多個容器,只要有一個容器的readiness探針診斷失敗,那麼整個pod都會處於unready狀態。
  • startup探針:指示容器中的應用是否已經啟動。如果提供了啟動探針(startup probe),則禁用所有其他探針,直到它成功為止。如果啟動探針失敗,kubelet 將殺死容器,容器服從其重啟策略進行重啟。如果容器沒有提供啟動探針,則默認狀態為成功Success。

(2)、這三種探針均具有以下參數:

  • initialDelaySeconds:容器啟動後第一次執行探測是需要等待多少秒。
  • periodSeconds:執行探測的頻率。默認是10秒,最小1秒。
  • timeoutSeconds:探測超時時間。默認1秒,最小1秒。
  • successThreshold:探測失敗後,最少連續探測成功多少次才被認定為成功。默認是1。對於liveness必須是1。最小值是1。
  • failureThreshold:探測成功後,最少連續探測失敗多少次才被認定為失敗。默認是3。最小值是1。

(3)、探針探測的結果有以下三者之一:

  • Success:Container通過了檢查。
  • Failure:Container未通過檢查。
  • Unknown:未能執行檢查,因此不採取任何措施。

1、liveness probe(存活探針)

必要性:

在一個服務中,是存在進程在運行,但服務其實已經掛掉了,表現為埠監聽失敗、http請求失敗等。所以需要存活探針

運行原理:

用於判斷容器是否存活,即Pod是否為running狀態,如果LivenessProbe探針探測到容器不健康,則kubelet將kill掉容器,並根據容器的重啟策略是否重啟。
如果一個容器不包含LivenessProbe探針,則Kubelet認為容器的LivenessProbe探針的返回值永遠成功。
image

有時應用程式可能因為某些原因(後端服務故障等)導致暫時無法對外提供服務,但應用軟體沒有終止,導致K8S無法隔離有故障的pod,調用者可能會訪問到有故障的pod,導致業務不穩定。
K8S提供livenessProbe來檢測應用程式是否正常運行,並且對相應狀況進行相應的補救措施。

注意,liveness探測失敗並一定不會重啟pod,pod是否會重啟由你的restart policy 控制。

2、readiness probe(就緒探針)

運行原理:

用於判斷容器是否啟動完成,即容器的Ready是否為True,可以接收請求,如果ReadinessProbe探測失敗,
則容器的Ready將為False,控制器將此Pod的Endpoint從對應的service的Endpoint列表中移除,從此不再將任何請求調度此Pod上,直到下次探測成功。
通過使用Readiness探針,Kubernetes能夠等待應用程式完全啟動,然後才允許服務將流量發送到新副本。
image

關於 Readiness 探針有一點很重要,它會在容器的整個生命周期中運行。這意味著 Readiness 探針不僅會在啟動時運行,而且還會在 Pod 運行期間反覆運行。這是為了處理應用程式暫時不可用的情況(比如載入大量數據、等待外部連接時)。在這種情況下,我們不一定要殺死應用程式,可以等待它恢復。Readiness 探針可用於檢測這種情況,並在 Pod 再次通過 Readiness 檢查後,將流量發送到這些 Pod。

3、Startup probe(啟動探針)

運行原理:

startup 探針與 Readiness 探針類似,但它僅在啟動時執行,能針對啟動緩慢的容器或在初始化過程中有不可預測行為的應用程式進行優化。藉助 Readiness 探針,我們可以配置 initialDelaySeconds 來確定 Readiness 探測在準備就緒前要等待多長時間。

二、探針探測方法介紹:

  • exec通過執行shell命令的方式,判斷退出狀態碼是否是0,針對複雜檢測或無HTTP介面的服務,命令返回值為0則表示容器健康。
  • tcpSocket:通過容器的IP和Port執行TCP檢查,kubelet嘗試打開容器上的某個埠,如果能夠建立TCP連接,則表明容器健康。
  • httpGet通過發送http請求檢查服務是否正常,每進行一次HTTP健康檢查都會curl訪問一次指定的URL,返回200-399狀態碼則表明容器健康,否則認為容器運轉不正常。

1、HTTP

kubelet 將 HTTP GET 請求發送到 endpoint,並檢查 2xx 或 3xx 響應。我們可以重複使用現有的 HTTP endpoint 或設置輕量級 HTTP 伺服器以進行探測(例如,具有 /healthz endpoint 的 Express server)。HTTP 探針包含其他額外參數:

  • host:要連接的主機名(默認值:pod 的 IP)。
  • scheme:HTTP(默認)或 HTTPS。
  • path:HTTP/S 伺服器上的路徑 。
  • httpHeaders:自定義標頭(如果需要標頭用於身份驗證、CORS 設置等) 。
  • port:訪問伺服器的埠名稱或埠號。
livenessProbe:
   httpGet:
     path: /
	 port: 8080

2、TCP

如果僅需要檢查是否可以建立 TCP 連接,則可以指定 TCP 探針。如果建立 TCP 連接,則將 Pod 標記為運行狀況良好。對於不適合使用 HTTP 探針的 gRPC 或 FTP 伺服器,TCP 探針可能會有用。

readinessProbe:
   tcpSocket:
     port: 20

3、Command

可以將探針配置為運行 shell 命令。如果命令返回的退出程式碼為 0,則檢查通過,否則 Pod 將被標記為不健康。如果不希望公開 HTTP 伺服器與埠,或者希望通過命令檢查初始化步驟(例如,檢查是否已創建配置文件、運行 CLI 命令),這種類型的探針會很有用。

readinessProbe:
   exec:
     command: ["/bin/sh", "-ec", "vault status -tls-skip-verify"]

三、用法實例:

點擊查看程式碼
          readinessProbe:
            httpGet:
              path: {{ .Values.probe.readiness }}
              port: {{ .Values.insInsuranceApi.service.targetPort }}
              scheme: HTTP
            failureThreshold: 3
            initialDelaySeconds: 90
            periodSeconds: 10
            successThreshold: 3
            timeoutSeconds: 1
          livenessProbe:
            httpGet:
              path: {{ .Values.probe.liveness }}
              port: {{ .Values.insInsuranceApi.service.targetPort }}
              scheme: HTTP
            failureThreshold: 3
            initialDelaySeconds: 180
            periodSeconds: 10
            timeoutSeconds: 120