k8s中設置探針-存活探針和就緒探針


基礎概念

探針 是由 kubelet 對容器執行的定期診斷。

針對運行中的容器,kubelet 可以選擇是否執行以下三種探針,以及如何針對探測結果作出反應:

  • livenessProbe:指示容器是否正在運行。如果存活態探測失敗,則 kubelet 會殺死容器, 並且容器將根據其重啟策略決定未來。如果容器不提供存活探針, 則默認狀態為 Success。
  • readinessProbe:指示容器是否准備好為請求提供服務。如果就緒態探測失敗, 端點控制器將從與 Pod 匹配的所有服務的端點列表中刪除該 Pod 的 IP 地址。 初始延遲之前的就緒態的狀態值默認為 Failure。 如果容器不提供就緒態探針,則默認狀態為 Success。
  • startupProbe: 指示容器中的應用是否已經啟動。如果提供了啟動探針,則所有其他探針都會被 禁用,直到此探針成功為止。如果啟動探測失敗,kubelet 將殺死容器,而容器依其 重啟策略進行重啟。 如果容器沒有提供啟動探測,則默認狀態為 Success。

要執行診斷,kubelet 調用由容器實現的 Handler (處理程序)。有三種類型的處理程序:

  • ExecAction: 在容器內執行指定命令。如果命令退出時返回碼為 0 則認為診斷成功。
  • TCPSocketAction: 對容器的 IP 地址上的指定端口執行 TCP 檢查。如果端口打開,則診斷被認為是成功的。
  • HTTPGetAction: 對容器的 IP 地址上指定端口和路徑執行 HTTP Get 請求。如果響應的狀態碼大於等於 200 且小於 400,則診斷被認為是成功的。

每次探測都將獲得以下三種結果之一:

  • Success(成功):容器通過了診斷。
  • Failure(失敗):容器未通過診斷。
  • Unknown(未知):診斷失敗,因此不會采取任何行動。

常見配置

Probe 中有很多精確和詳細的配置,通過它們您能准確的控制 liveness 和 readiness 檢查:

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

HTTP probe 中可以給 httpGet設置其他配置項:

  • host:連接的主機名,默認連接到 pod 的 IP。您可能想在 http header 中設置 “Host” 而不是使用 IP。
  • scheme:連接使用的 schema,默認HTTP。
  • path: 訪問的HTTP server 的 path。
  • httpHeaders:自定義請求的 header。HTTP運行重復的 header。
  • port:訪問的容器的端口名字或者端口號。端口號必須介於 1 和 65525 之間。

對於 HTTP 探測器,kubelet 向指定的路徑和端口發送 HTTP 請求以執行檢查。 Kubelet 將 probe 發送到容器的 IP 地址,除非地址被httpGet中的可選host字段覆蓋。 在大多數情況下,您不想設置主機字段。 有一種情況下您可以設置它。 假設容器在127.0.0.1上偵聽,並且 Pod 的hostNetwork字段為 true。 然后,在httpGet下的host應該設置為127.0.0.1。 如果您的 pod 依賴於虛擬主機,這可能是更常見的情況,您不應該是用host,而是應該在httpHeaders中設置Host頭。

示例

官網例子中提供的鏡像是k8s.gcr.io/busybox,在國內拉取不了,需要換成地址,具體看這篇文章:https://www.cnblogs.com/saolv/p/12996115.html

或者換成其他鏡像進行測試,比如下方說的nginx鏡像

測試的話可以把鏡像換成nginx,探測80端口,等pod起來后,登錄進容器,手動修改nginx使用的80端口,然后重啟nginx服務,從而觸發有關探針,進而實現pod重啟

liveness ExecAction

以下是 Pod 的配置文件 exec-liveness.yaml:

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: k8s.gcr.io/busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5
      periodSeconds: 5

該配置文件給 Pod 配置了一個容器。periodSeconds 規定 kubelet 要每隔5秒執行一次 liveness probe。 initialDelaySeconds 告訴 kubelet 在第一次執行 probe 之前要的等待5秒鍾。探針檢測命令是在容器中執行 cat /tmp/healthy 命令。如果命令執行成功,將返回0,kubelet 就會認為該容器是活着的並且很健康。如果返回非0值,kubelet 就會殺掉這個容器並重啟它。

在容器生命的最初30秒內有一個 /tmp/healthy 文件,在這30秒內 cat /tmp/healthy命令會返回一個成功的返回碼。30秒后, cat /tmp/healthy 將返回失敗的返回碼。

# 創建pod
kubectl create -f exec-liveness.yaml

# 在30秒內,查看 Pod 的 event,結果顯示沒有失敗的 liveness probe
kubectl describe pod liveness-exec

# 35秒后,再次查看 Pod 的 event,在最下面有一條信息顯示 liveness probe 失敗,容器被刪掉並重新創建

# 再等30秒,確認容器已經重啟
kubectl get pod liveness-exec

# 從輸出結果來RESTARTS值加1了。

liveness HTTP請求

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-http
spec:
  containers:
  - name: liveness
    image: k8s.gcr.io/liveness
    args:
    - /server
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
        httpHeaders:
        - name: X-Custom-Header
          value: Awesome
      initialDelaySeconds: 3
      periodSeconds: 3

liveness tcpSocket

apiVersion: v1
kind: Pod
metadata:
  name: goproxy
  labels:
    app: goproxy
spec:
  containers:
  - name: goproxy
    image: k8s.gcr.io/goproxy:0.1
    ports:
    - containerPort: 8080
    readinessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 10
    livenessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 15
      periodSeconds: 20

readiness probe

Readiness probe的配置跟liveness probe很像。唯一的不同是使用 readinessProbe而不是livenessProbe。

readinessProbe:
  exec:
    command:
    - cat
    - /tmp/healthy
  initialDelaySeconds: 5
  periodSeconds: 5

Readiness probe 的 HTTP 和 TCP 的探測器配置跟 liveness probe 一樣。

Readiness 和 livenss probe 可以並行用於同一容器。 使用兩者可以確保流量無法到達未准備好的容器,並且容器在失敗時重新啟動。

何時該使用存活態探針

如果容器中的進程能夠在遇到問題或不健康的情況下自行崩潰,則不一定需要存活態探針; kubelet 將根據 Pod 的restartPolicy 自動執行修復操作。

如果你希望容器在探測失敗時被殺死並重新啟動,那么請指定一個存活態探針, 並指定restartPolicy 為 "Always" 或 "OnFailure"。

何時該使用就緒態探針

如果要僅在探測成功時才開始向 Pod 發送請求流量,請指定就緒態探針。 在這種情況下,就緒態探針可能與存活態探針相同,但是規約中的就緒態探針的存在意味着 Pod 將在啟動階段不接收任何數據,並且只有在探針探測成功后才開始接收數據。

如果你的容器需要加載大規模的數據、配置文件或者在啟動期間執行遷移操作,可以添加一個 就緒態探針。

如果你希望容器能夠自行進入維護狀態,也可以指定一個就緒態探針,檢查某個特定於 就緒態的因此不同於存活態探測的端點。

何時該使用啟動探針

對於所包含的容器需要較長時間才能啟動就緒的 Pod 而言,啟動探針是有用的。 你不再需要配置一個較長的存活態探測時間間隔,只需要設置另一個獨立的配置選定, 對啟動期間的容器執行探測,從而允許使用遠遠超出存活態時間間隔所允許的時長。

如果你的容器啟動時間通常超出 initialDelaySeconds + failureThreshold × periodSeconds 總值,你應該設置一個啟動探測,對存活態探針所使用的同一端點執行檢查。 periodSeconds 的默認值是 30 秒。你應該將其 failureThreshold 設置得足夠高, 以便容器有充足的時間完成啟動,並且避免更改存活態探針所使用的默認值。 這一設置有助於減少死鎖狀況的發生。

匯總

使用tcpSocket方式探測端口是否啟動,使用httpGet方式探測服務是否就緒

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-v1
  namespace: blue-green
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
      version: v1
  template:
    metadata:
     labels:
      app: myapp
      version: v1
    spec:
       containers:
       - name: myapp
         image: jdd.io/demo:20210402174646
         imagePullPolicy: IfNotPresent
         livenessProbe:
           tcpSocket:
             port: 8888
           initialDelaySeconds: 15
           periodSeconds: 20
         readinessProbe:
           httpGet:           
             path: /hello/test
             port: 8888
           initialDelaySeconds: 5
           periodSeconds: 10
       imagePullSecrets:
         - name: regcred

額外補充:使用命名的端口

可以使用命名的 ContainerPort 作為 HTTP 或 TCP liveness檢查:

ports:
- name: liveness-port
  containerPort: 8080
  hostPort: 8080

livenessProbe:
  httpGet:
  path: /healthz
  port: liveness-port


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM