pod健康檢查(liveness probe存活探針&&readiness probe 可讀性探針)


Kubernetes集群當中,我們可以通過配置liveness probe(存活探針)和readiness probe(可讀性探針)來影響容器的生存周期。參考文檔:https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/

kubelet 通過使用 liveness probe 來確定你的應用程序是否正在運行,通俗點將就是是否還活着。一般來說,如果你的程序一旦崩潰了, Kubernetes 就會立刻知道這個程序已經終止了,然后就會重啟這個程序。而我們的 liveness probe 的目的就是來捕獲到當前應用程序還沒有終止,還沒有崩潰,如果出現了這些情況,那么就重啟處於該狀態下的容器,使應用程序在存在 bug 的情況下依然能夠繼續運行下去。
kubelet使用活躍度探頭知道什么時候重新啟動的容器。例如,liveness probe可以捕獲死鎖,應用程序正在運行,但無法取得進展。在這種狀態下重新啟動容器可以繼續存活。
kubelet 使用 readiness probe 來確定容器是否已經就緒可以接收流量過來了。這個探針通俗點講就是說是否准備好了,現在可以開始工作了。只有當 Pod 中的容器都處於就緒狀態的時候 kubelet 才會認定該 Pod 處於就緒狀態,因為一個 Pod 下面可能會有多個容器。當然 Pod 如果處於非就緒狀態,那么我們就會將他從我們的工作隊列(實際上就是我們后面需要重點學習的 Service)中移除出來,這樣我們的流量就不會被路由到這個 Pod 里面來了。
使用readiness probe來了解容器何時准備開始接受流量。當所有容器准備就緒時,Pod被認為已准備就緒。此信號的一個用途是控制哪些Pod用作服務的后端。當Pod未就緒時,它將從服務負載平衡器中刪除。例如當一個應用服務有大文件加載時,這種情況下不允許接受用戶訪問,readiness probe就不會對這類型的程序啟動服務。

許多運行很長時間的應用程序最終會轉換到損壞狀態,除非重新啟動,否則無法恢復。Kubernetes提供活體探測器來檢測和糾正這種情況。

通過busybox來練習一下liveness probe

liveness-exec.yaml  liveness-http.yaml  pod-example.yaml  poststart-hook.yaml  prestop-hook.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: 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具有單個Container。該periodSeconds字段指定kubelet應每5秒執行一次活躍度探測。該initialDelaySeconds字段告訴kubelet它應該在執行第一次探測之前等待5秒。要執行探測,kubelet將cat /tmp/healthy在Container中執行命令。如果命令成功,則返回0,並且kubelet認為Container是活動且健康的。如果該命令返回非零值,則kubelet會終止Container並重新啟動它。

當Container啟動時,它會執行以下命令:

/bin/sh -c "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600"

在Container的生命的前30秒,有一個/tmp/healthy文件。因此,在前30秒內,該命令cat /tmp/healthy返回成功代碼。30秒后,cat /tmp/healthy返回失敗代碼。

創建Pod:

kubectl apply -f liveness-exec.yaml

在30秒內,查看Pod事件:

kubectl describe pod liveness-exec

有消息指示活動探測失敗,並且容器已被殺死並重新創建。

另一種活動探測器使用HTTP GET請求

apiVersion: v1
kind: Pod
metadata:
  name: liveness-http
  labels:
    app: liveness
spec:
  containers:
  - name: liveness
    image: cnych/liveness
    args:
    - /server
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
      initialDelaySeconds: 3
      periodSeconds: 3

在配置文件中,您可以看到Pod具有單個Container。該periodSeconds字段指定kubelet應每3秒執行一次活躍度探測。該initialDelaySeconds字段告訴kubelet它應該在執行第一次探測之前等待3秒。為了執行探測,kubelet向在Container中運行的服務器發送HTTP GET請求並偵聽端口8080.如果服務器/healthz路徑的處理程序返回成功代碼,則kubelet認為Container是活動且健康的。如果處理程序返回失敗代碼,則kubelet會終止Container並重新啟動它。

任何大於或等於200且小於400的代碼表示成功。任何其他代碼表示失敗。

您可以在server.go中查看服務器的源代碼 。

對於Container /healthz處於活動狀態的前10秒,處理程序返回狀態200.之后,處理程序返回狀態500。

http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
    duration := time.Now().Sub(started)
    if duration.Seconds() > 10 {
        w.WriteHeader(500)
        w.Write([]byte(fmt.Sprintf("error: %v", duration.Seconds())))
    } else {
        w.WriteHeader(200)
        w.Write([]byte("ok"))
    }
})

在容器啟動3秒后,kubelet開始執行運行狀況檢查。因此,前幾次健康檢查將成功。但是10秒后,運行狀況檢查將失敗,並且kubelet將終止並重新啟動Container。

要嘗試HTTP活躍度檢查,請創建一個Pod:

kubectl apply -f liveness-http.yaml

10秒后,查看Pod事件以驗證活動探測失敗並且Container已重新啟動:

kubectl describe pod liveness-http

在v1.13之前的版本(包括v1.13)中,如果在運行pod的節點上設置了環境變量http_proxy(或HTTP_PROXY),則HTTP活動探針將使用該代理。在v1.13之后的版本中,本地HTTP代理環境變量設置不會影響HTTP活動探測。

定義TCP活動探測

第三種類型的活動探測器使用TCP套接字。使用此配置,kubelet將嘗試在指定端口上打開容器的套接字。如果它可以建立連接,則容器被認為是健康的,如果它不能被認為是失敗的話。

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

我們可以看到,TCP 檢查的配置與 HTTP 檢查非常相似,只是將httpGet替換成了tcpSocket。 而且我們同時使用了readiness probeliveness probe兩種探針。 容器啟動后5秒后,kubelet將發送第一個readiness probe(可讀性探針)。 該探針會去連接容器的8080端,如果連接成功,則該 Pod 將被標記為就緒狀態。然后Kubelet將每隔10秒鍾執行一次該檢查。

除了readiness probe之外,該配置還包括liveness probe。 容器啟動15秒后,kubelet將運行第一個 liveness probe。 就像readiness probe一樣,這將嘗試去連接到容器的8080端口。如果liveness probe失敗,容器將重新啟動。

有的時候,應用程序可能暫時無法對外提供服務,例如,應用程序可能需要在啟動期間加載大量數據或配置文件。 在這種情況下,您不想殺死應用程序,也不想對外提供服務。 那么這個時候我們就可以使用readiness probe來檢測和減輕這些情況。 Pod中的容器可以報告自己還沒有准備,不能處理Kubernetes服務發送過來的流量。

從上面的YAML文件我們可以看出readiness probe的配置跟liveness probe很像,基本上一致的。唯一的不同是使用readinessProbe而不是livenessProbe。兩者如果同時使用的話就可以確保流量不會到達還未准備好的容器,准備好過后,如果應用程序出現了錯誤,則會重新啟動容器。

另外除了上面的initialDelaySecondsperiodSeconds屬性外,探針還可以配置如下幾個參數:

  • timeoutSeconds:探測超時的秒數。默認為1秒。最小值為1。
  • initialDelaySeconds:啟動活動或准備就緒探測之前容器啟動后的秒數。
  • periodSeconds:執行探測的頻率(以秒為單位)。默認為10秒。最小值為1。
  • failureThreshold:當Pod啟動並且探測失敗時,Kubernetes會failureThreshold在放棄之前嘗試一次。在活動探測的情況下放棄意味着重新啟動Pod。如果准備好探測,Pod將被標記為未准備好。默認為3.最小值為1。
  • successThreshold:失敗后探測成功的最小連續成功次數。默認為1.活躍度必須為1。最小值為1。

[HTTP探針] 具有可以設置的其他字段httpGet

  • host:要連接的主機名,默認為pod IP。您可能希望在httpHeaders中設置“主機”。
  • scheme:用於連接主機的方案(HTTP或HTTPS)。默認為HTTP。
  • path:HTTP服務器上的訪問路徑。
  • httpHeaders:要在請求中設置的自定義標頭。HTTP允許重復標頭。
  • port:容器上要訪問的端口的名稱或編號。數字必須在1到65535的范圍內。

對於HTTP探測,kubelet將HTTP請求發送到指定的路徑和端口以執行檢查。kubelet將探測器發送到pod的IP地址,除非地址被可選host字段覆蓋httpGet。如果 scheme字段設置為HTTPS,則kubelet會發送跳過證書驗證的HTTPS請求。在大多數情況下,您不希望設置該host字段。這是您設置它的一個場景。假設Container偵聽127.0.0.1並且Pod的hostNetwork字段為true。然后host,在httpGet,應設置為127.0.0.1。如果您的pod依賴虛擬主機,這可能是更常見的情況,您不應該使用host,而是設置Host標頭httpHeaders

對於探測器,kubelet在節點處而不是在pod中進行探測連接,這意味着您無法在host參數中使用服務名稱,因為kubelet無法解析它。


免責聲明!

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



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