存活探針(Liveness Probe)

存活探針

 
Kubernetes提供了自愈的能力,具體就是能感知到容器崩潰,然後能夠重啓這個容器。但是有時候例如Java程序內存泄漏了,程序無法正常工作,但是JVM進程卻是一直運行的,對於這種應用本身業務出了問題的情況,Kubernetes提供了Liveness Probe機制,通過檢測容器響應是否正常來決定是否重啓,這是一種很好的健康檢查機制。

毫無疑問,每個Pod最好都定義Liveness Probe,否則Kubernetes無法感知Pod是否正常運行。

Kubernetes支持如下三種探測機制。

  • HTTP GET:向容器發送HTTP GET請求,如果Probe收到2xx或3xx,說明容器是健康的。
  • TCP Socket:嘗試與容器指定端口建立TCP連接,如果連接成功建立,說明容器是健康的。
  • Exec:Probe執行容器中的命令並檢查命令退出的狀態碼,如果狀態碼爲0則說明容器是健康的。
    與存活探針對應的還有一個就緒探針(Readiness Probe),將在就緒探針(Readiness Probe)中會詳細介紹。

HTTP GET

HTTP GET方式是最常見的探測方法,其具體機制是向容器發送HTTP GET請求,如果Probe收到2xx或3xx,說明容器是健康的,定義方法如下所示。

apiVersion: v1
kind: Pod
metadata:
  name: liveness-http
spec:
  containers:
  - name: liveness
    image: nginx:alpine
    livenessProbe:           # liveness probe
      httpGet:               # HTTP GET定義
        path: /
        port: 80
  imagePullSecrets: 
  - name: default-secret

創建這個Pod。

$ kubectl create -f liveness-http.yaml
pod/liveness-http created

如上,這個Probe往容器的80端口發送HTTP GET請求,如果請求不成功,Kubernetes會重啓容器。

查看Pod詳情。

$ kubectl describe po liveness-http
Name:               liveness-http
......
Containers:
  liveness:
    ......
    State:          Running
      Started:      Mon, 03 Aug 2020 03:08:55 +0000
    Ready:          True
    Restart Count:  0
    Liveness:       http-get http://:80/ delay=0s timeout=1s period=10s #success=1 #failure=3
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-vssmw (ro)
......

可以看到Pod當前狀態是Running,Restart Count爲0,說明沒有重啓。如果Restart Count不爲0,則說明已經重啓。

TCP Socket

TCP Socket嘗試與容器指定端口建立TCP連接,如果連接成功建立,說明容器是健康的,定義方法如下所示。

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-tcp
spec:
  containers:
  - name: liveness
    image: nginx:alpine
    livenessProbe:           # liveness probe
      tcpSocket:
        port: 80
  imagePullSecrets: 
  - name: default-secret

Exec

Exec即執行具體命令,具體機制是Probe執行容器中的命令並檢查命令退出的狀態碼,如果狀態碼爲0則說明健康,定義方法如下所示。

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: nginx:alpine
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
    livenessProbe:           # liveness probe
      exec:                  # Exec定義
        command:
        - cat
        - /tmp/healthy
  imagePullSecrets: 
  - name: default-secret

上面定義在容器中執行cat /tmp/healthy命令,如果成功執行並返回0,則說明容器是健康的。上面定義中,30秒後命令會刪除/tmp/healthy,這會導致Liveness Probe判定Pod處於不健康狀態,然後會重啓容器。

Liveness Probe高級配置

上面liveness-http的describe命令回顯中有如下行。

Liveness: http-get http://:8080/ delay=0s timeout=1s period=10s #success=1 #failure=3

這一行表示Liveness Probe的具體參數配置,其含義如下:

  • delay:延遲,delay=0s,表示在容器啓動後立即開始探測,沒有延遲時間
  • timeout:超時,timeout=1s,表示容器必須在1s內進行響應,否則這次探測記作失敗
  • period:週期,period=10s,表示每10s探測一次容器
  • success:成功,#success=1,表示連續1次成功後記作成功
  • failure:失敗,#failure=3,表示連續3次失敗後會重啓容器
    以上存活探針表示:容器啓動後立即進行探測,如果1s內容器沒有給出迴應則記作探測失敗。每次間隔10s進行一次探測,在探測連續失敗3次後重啓容器。

這些是創建時默認設置的,您也可以手動配置,如下所示。

apiVersion: v1
kind: Pod
metadata:
  name: liveness-http
spec:
  containers:
  - image: k8s.gcr.io/liveness
    livenessProbe:
      httpGet:
        path: /
        port: 8080
      initialDelaySeconds: 10    # 容器啓動後多久開始探測
      timeoutSeconds: 2          # 表示容器必須在2s內做出相應反饋給probe,否則視爲探測失敗
      periodSeconds: 30          # 探測週期,每30s探測一次
      successThreshold: 1        # 連續探測1次成功表示成功
      failureThreshold: 3        # 連續探測3次失敗表示失敗

initialDelaySeconds一般要設置大於0,這是由於很多情況下容器雖然啓動成功,但應用就緒也需要一定的時間,需要等就緒時間之後才能返回成功,否則就會導致probe經常失敗。

另外failureThreshold可以設置多次循環探測,這樣在實際應用中健康檢查的程序就不需要多次循環,這一點在開發應用時需要注意。

配置有效的Liveness Probe

  • Liveness Probe應該檢查什麼
    一個好的Liveness Probe應該檢查應用內部所有關鍵部分是否健康,並使用一個專有的URL訪問,例如 /health,當訪問 /health 時執行這個功能,然後返回對應結果。這裏要注意不能做鑑權,不然 probe 就會一直失敗導致陷入重啓的死循環。

另外檢查只能限制在應用內部,不能檢查依賴外部的部分,例如當前端web server不能連接數據庫時,這個就不能看成web server不健康。

  • Liveness Probe必須輕量
    Liveness Probe不能佔用過多的資源,且不能佔用過長的時間,否則所有資源都在做健康檢查,這就沒有意義了。例如Java應用,就最好用HTTP GET方式,如果用Exec方式,JVM啓動就佔用了非常多的資源。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章