【七】Kubernetes 探針介紹 - 存活、就緒探針案例測試


一、探針概述

探針是有 kubelet 對容器執行的定期診斷,並不是由 Master 節點發起的探測,而是由每一個 Node 所在的 kubelet 進行探測,這樣可以減輕 Master 節點系統負載壓力。

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

  • ExecAction: 在容器內執行指定命令。如果命令退出時返回碼為 0 則認為診斷成功,非 0 都屬於不成功。

  • TCPSocketAction: 對容器的 IP 地址上的指定端口執行 TCP 檢查。如果端口打開,則診斷被認為是成功的。

  • HTTPGetAction: 對容器的 IP 地址上指定端口和路徑執行 HTTP Get 請求。如果響應的狀態碼大於等於 200 且小於 400,則診斷被認為是成功的。

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

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

兩種探針方式:

liveness Probe:是一個存活探測器,會隨着 Pod 生命周期一直循環檢測。探測容器是否正在運行,如果存活探測失敗,則 kubelet 會殺死容器,然后根據其容器的重啟策略來對容器進行操作,默認為 Always,則 Pod 進行重啟。

readiness Probe:是一個就緒探測器,檢測 Pod 是否到達就緒狀態,只有達到就緒狀態了才可以對外提供服務,當一個 Pod 內的所有容器都准備好了,才能把這個 Pod 看作就緒了。

readiness Probe 應用場景:

就緒探針可以應用在 Service 后端的 Pod 探測上,在 Pod 還沒有准備好的時候,會從 Service 的負載均衡器中剔除。

二、探針實例測試

2.1 就緒探針 - HTTP Get

readiness-httpget.yaml如下:

apiVersion: v1
kind: Pod
metadata:
  name: readiness-httpget   # Pod 名稱
  namespace: test           # Pod 所在的命名空間
spec:
  containers:
  - name: readiness-httpget-container       # 容器名稱
    image: hub.test.com/library/mynginx:v1  # 鏡像地址
    imagePullPolicy: IfNotPresent           # 鏡像下載策略
    readinessProbe:             # 就緒探測
      httpGet:                  # 檢測方案
        path: /index1.html      # 檢測路徑
        port: 80                # 檢測端口
      initialDelaySeconds: 3    # 啟動后多少秒開始第一次檢測
      periodSeconds: 3          # 每次間隔檢測時間

實際就是檢測:http://localhost/index1.html,是否正常。

創建 Pod

[root@k8s-master01 ~]# kubectl create -f readiness-httpget.yaml 
pod/readiness-httpget created

查看 Pod 狀態

image-20210603163935025

雖然已經 Running 了,但是還沒就緒狀態,因為我們這個容器沒有index1.html這個頁面。

查看該 Pod 的詳細詳細

[root@k8s-master01 ~]# kubectl describe pod readiness-httpget -n test
...
Events:
  Type     Reason     Age                  From               Message
  ----     ------     ----                 ----               -------
  Normal   Scheduled  5m11s                default-scheduler  Successfully assigned test/readiness-httpget to k8s-node01
  Normal   Pulled     5m10s                kubelet            Container image "hub.test.com/library/mynginx:v1" already present on machine
  Normal   Created    5m10s                kubelet            Created container readiness-httpget-container
  Normal   Started    5m10s                kubelet            Started container readiness-httpget-container
  Warning  Unhealthy  8s (x100 over 5m5s)  kubelet            Readiness probe failed: HTTP probe failed with statuscode: 404

image-20210603164320813

提示就緒檢測找不到該頁面,返回狀態碼 404。

接下來進入該容器手動創建index1.html頁面

[root@k8s-master01 ~]# kubectl exec readiness-httpget -n test -it -- /bin/bash
root@readiness-httpget:/# cd /usr/share/nginx/html/
root@readiness-httpget:/usr/share/nginx/html# ls
50x.html  index.html
root@readiness-httpget:/usr/share/nginx/html# touch index1.html 
root@readiness-httpget:/usr/share/nginx/html# exit

再次查看 Pod 狀態已經就緒狀態了

image-20210603164938219

2.2 存活探針 - exec

liveness-exec.yaml文件如下:

apiVersion: v1
kind: Pod
metadata:
  name: liveness-exec       # Pod 名稱
  namespace: test           # Pod 所在的命名空間
spec:
  containers:
  - name: liveness-exec-container               # 容器名稱
    image: hub.test.com/library/busybox:latest  # 鏡像地址
    imagePullPolicy: IfNotPresent               # 鏡像下載策略
    command: ["/bin/sh","-c","touch /tmp/live; sleep 60; rm -rf /tmp/live; sleep 3600"]
    # 創建 live 文件,休眠60秒,刪除 live 文件,再休眠 1 分鍾。
    livenessProbe:              # 存活探測
      exec:                     # 檢測方案
        command: ["test","-e","/tmp/live"]  # 檢測該文件是否存在,返回值 0 成功,非 0 失敗
      initialDelaySeconds: 3    # 啟動后多少秒開始第一次檢測
      periodSeconds: 3          # 每次間隔檢測時間

創建 Pod

[root@k8s-master01 ~]# kubectl create -f liveness-exec.yaml 
pod/liveness-exec created

查看 Pod 狀態,加上-w實時查看

[root@k8s-master01 ~]# kubectl get pod -n test -w

image-20210603171543754

從上圖可以看到 RESTARTS 已經重啟一次了,它會循環重啟,因為重新創建 Pod 到時候 /tmp/live 就會被創建,但是 60 秒后又被刪除。

2.3 存活探針 - HTTPGet

liveness-httpgat.yaml文件如下:

apiVersion: v1
kind: Pod
metadata:
  name: liveness-httpgat    # Pod 名稱
  namespace: test           # Pod 所在的命名空間
spec:
  containers:
  - name: liveness-httpgat-container            # 容器名稱
    image: hub.test.com/library/mynginx:v1      # 鏡像地址
    imagePullPolicy: IfNotPresent               # 鏡像下載策略
    ports:
    - name: http
      containerPort: 80
    livenessProbe:              # 存活探測
      httpGet:                  # 檢測方案
        port: http
        path: /index.html
      initialDelaySeconds: 3    # 啟動后多少秒開始第一次檢測
      periodSeconds: 3          # 每次間隔檢測時間
      timeoutSeconds: 10        # 探測的超時時間

創建 Pod

[root@k8s-master01 ~]# kubectl create -f liveness-httpget.yaml 
pod/liveness-httpgat created

查看 Pod 狀態,此時是正常的

[root@k8s-master01 ~]# kubectl get pod -n test
NAME                               READY   STATUS    RESTARTS   AGE
hpa-nginx-deploy-9f8676f85-5fk6c   1/1     Running   0          12m
liveness-httpgat                   1/1     Running   0          30s

現在將 nginx 容器里面的 index.html 文件給刪除

[root@k8s-master01 ~]# kubectl exec liveness-httpgat -n test -it -- rm -rf /usr/share/nginx/html/index.html

image-20210603173503627

重啟次數變為 1 ,由於 liveness沒有檢測到 index.html 文件,則會刪掉主容器,主容器一旦被刪除 Pod 也會進行重啟。

2.4 存活探針 - TCP

liveness-tcp.yaml文件如下:

apiVersion: v1
kind: Pod
metadata:
  name: liveness-tcp        # Pod 名稱
  namespace: test           # Pod 所在的命名空間
spec:
  containers:
  - name: liveness-tcp-container                # 容器名稱
    image: hub.test.com/library/mynginx:v1      # 鏡像地址
    imagePullPolicy: IfNotPresent               # 鏡像下載策略
    livenessProbe:                # 存活探測
      tcpSocket:                  # 檢測方案
        port: 8080                # 檢測端口
      initialDelaySeconds: 3      # 啟動后多少秒開始第一次檢測
      periodSeconds: 3            # 每次間隔檢測時間

創建 Pod

[root@k8s-master01 ~]# kubectl create -f liveness-tcp.yaml 
pod/liveness-tcp created

查看 Pod 狀態,此時由於 nginx 端口為 80,所以檢測不到 8080 端口,會一直重啟。

image-20210603174704209

2.5 就緒探針+存活探針 - HTTPGet

live-readi-httpgat.yaml文件如下:

apiVersion: v1
kind: Pod
metadata:
  name: live-readi-httpgat    # Pod 名稱
  namespace: test             # Pod 所在的命名空間
spec:
  containers:
  - name: live-readi-httpgat-container          # 容器名稱
    image: hub.test.com/library/mynginx:v1      # 鏡像地址
    imagePullPolicy: IfNotPresent               # 鏡像下載策略
    ports:
    - name: http
      containerPort: 80         # 容器端口
    readinessProbe:             # 就緒探測
      httpGet:                  # 檢測方案
        path: /index1.html      # 檢測路徑
        port: 80                # 檢測端口
      initialDelaySeconds: 3    
      periodSeconds: 3          
    livenessProbe:              # 存活探測
      httpGet:                  # 檢測方案
        port: http              # 檢測協議
        path: /index.html       # 檢測路徑
      initialDelaySeconds: 3    # 啟動后多少秒開始第一次檢測
      periodSeconds: 3          # 每次間隔檢測時間
      timeoutSeconds: 10        # 探測的超時時間

創建 Pod

[root@k8s-master01 ~]# kubectl create -f live-read-httpget.yaml 
pod/live-readi-httpgat created

查看 Pod 狀態

image-20210603175600770

雖然是 Running 狀態,但是還沒 Read,因為就緒探針沒有檢測到index1.html這個文件存在。

進入容器手動創建測試

[root@k8s-master01 ~]# kubectl exec live-readi-httpgat -n test -it -- /bin/bash
root@live-readi-httpgat:/# cd /usr/share/nginx/html/
root@live-readi-httpgat:/usr/share/nginx/html# touch index1.html

再次查看 Pod 狀態,現在已經就緒狀態

image-20210603175930057

我們再測試liveness探針,刪除 index.html 文件

[root@k8s-master01 ~]# kubectl exec live-readi-httpgat -n test -it -- rm -rf /usr/share/nginx/html/index.html

可以看到 Pod 重啟 1 次,又回到未就緒狀態了,因為重啟完后默認是沒有index1.html 文件的

image-20210603180317721

三、配置補充

使用啟動探測器保護慢啟動容器

有時候,會有一些現有的應用程序在啟動時需要較多的初始化時間。 要不影響對引起探測死鎖的快速響應,這種情況下,設置存活探測參數是要技巧的。 技巧就是使用一個命令來設置啟動探測,針對HTTP 或者 TCP 檢測,可以通過設置 failureThreshold * periodSeconds 參數來保證有足夠長的時間應對糟糕情況下的啟動時間。

實例:

startupProbe:
  httpGet:
    path: /test
    port: liveness-port
  failureThreshold: 30
  periodSeconds: 10

應用程序可以有最多 5 分鍾(30 * 10 = 300s) 的時間來完成它的啟動。

還有很多配置字段,可以使用這些字段精確的控制存活和就緒檢測的行為:

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


免責聲明!

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



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