1. 程式人生 > 其它 >K8s配置存活、就緒和啟動探測器

K8s配置存活、就緒和啟動探測器

這篇文章介紹如何給容器配置存活、就緒和啟動探測器。

kubelet 使用存活探測器來知道什麼時候要重啟容器。 例如,存活探測器可以捕捉到死鎖(應用程式在執行,但是無法繼續執行後面的步驟)。 這樣的情況下重啟容器有助於讓應用程式在有問題的情況下更可用。

kubelet 使用就緒探測器可以知道容器什麼時候準備好了並可以開始接受請求流量, 當一個 Pod 內的所有容器都準備好了,才能把這個 Pod 看作就緒了。 這種訊號的一個用途就是控制哪個 Pod 作為 Service 的後端。 在 Pod 還沒有準備好的時候,會從 Service 的負載均衡器中被剔除的。

kubelet 使用啟動探測器可以知道應用程式容器什麼時候啟動了。 如果配置了這類探測器,就可以控制容器在啟動成功後再進行存活性和就緒檢查, 確保這些存活、就緒探測器不會影響應用程式的啟動。 這可以用於對慢啟動容器進行存活性檢測,避免它們在啟動執行之前就被殺掉。

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

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

說明:
在 Kubernetes 1.20 版本之前,exec 探針會忽略 timeoutSeconds:探針會無限期地 持續執行,甚至可能超過所配置的限期,直到返回結果為止。

這一缺陷在 Kubernetes v1.20 版本中得到修復。你可能一直依賴於之前錯誤的探測行為, 甚至你都沒有覺察到這一問題的存在,因為預設的超時值是 1 秒鐘。 作為叢集管理員,你可以在所有的 kubelet 上禁用 ExecProbeTimeout 特性門控 (將其設定為 false),從而恢復之前版本中的執行行為,之後當叢集中所有的 exec 探針都設定了 timeoutSeconds 引數後,移除此標誌過載。 如果你有 Pods 受到此預設 1 秒鐘超時值的影響,你應該更新 Pod 對應的探針的 超時值,這樣才能為最終去除該特性門控做好準備。

當此缺陷被修復之後,在使用 dockershim 容器執行時的 Kubernetes 1.20+ 版本中,對於 exec 探針而言,容器中的程序可能會因為超時值的設定保持持續執行, 即使探針返回了失敗狀態。

注意:
如果就緒態探針的實現不正確,可能會導致容器中程序的數量不斷上升。 如果不對其採取措施,很可能導致資源枯竭的狀況。

HTTP 探測
HTTP Probes 可以在 httpGet 上配置額外的欄位:

host:連線使用的主機名,預設是 Pod 的 IP。也可以在 HTTP 頭中設定 “Host” 來代替。
scheme :用於設定連線主機的方式(HTTP 還是 HTTPS)。預設是 HTTP。
path:訪問 HTTP 服務的路徑。預設值為 "/"。
httpHeaders:請求中自定義的 HTTP 頭。HTTP 頭欄位允許重複。
port:訪問容器的埠號或者埠名。如果數字必須在 1 ~ 65535 之間。
對於 HTTP 探測,kubelet 傳送一個 HTTP 請求到指定的路徑和埠來執行檢測。 除非 httpGet 中的 host 欄位設定了,否則 kubelet 預設是給 Pod 的 IP 地址傳送探測。 如果 scheme 欄位設定為了 HTTPS,kubelet 會跳過證書驗證傳送 HTTPS 請求。 大多數情況下,不需要設定host 欄位。 這裡有個需要設定 host 欄位的場景,假設容器監聽 127.0.0.1,並且 Pod 的 hostNetwork 欄位設定為了 true。那麼 httpGet 中的 host 欄位應該設定為 127.0.0.1。 可能更常見的情況是如果 Pod 依賴虛擬主機,你不應該設定 host 欄位,而是應該在 httpHeaders 中設定 Host。

針對 HTTP 探針,kubelet 除了必需的 Host 頭部之外還發送兩個請求頭部欄位: User-Agent 和 Accept。這些頭部的預設值分別是 kube-probe/{{ skew latestVersion >}} (其中 1.23 是 kubelet 的版本號)和 */*。

你可以通過為探測設定 .httpHeaders 來過載預設的頭部欄位值;
例如:

livenessProbe:
  httpGet:
    httpHeaders:
      - name: Accept
        value: application/json

startupProbe:
  httpGet:
    httpHeaders:
      - name: User-Agent
        value: MyUserAgent

你也可以通過將這些頭部欄位定義為空值,從請求中去掉這些頭部欄位:

livenessProbe:
  httpGet:
    httpHeaders:
      - name: Accept
        value: ""

startupProbe:
  httpGet:
    httpHeaders:
      - name: User-Agent
        value: ""


示例:

          readinessProbe:
            httpGet:
              path: /ready
              port: http
              httpHeaders:
                - name: Accept
                 value: application/json, text/plain, */*
                - name: User-Agent
                 value: istio-envoy
            initialDelaySeconds: 120
            periodSeconds: 10
            timeoutSeconds: 1
            successThreshold: 1
            failureThreshold: 3
          livenessProbe:
            httpGet:
              path: /health
              port: http
            initialDelaySeconds: 120
            periodSeconds: 10
            timeoutSeconds: 1
            successThreshold: 1
            failureThreshold: 5

https://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/