1. 程式人生 > 其它 >7.5 實現基於探針對pod中的訪問的健康狀態檢查

7.5 實現基於探針對pod中的訪問的健康狀態檢查

1.pod的宣告週期

取值 描述
Pending Pod 已被 Kubernetes 系統接受,但有一個或者多個容器尚未建立亦未執行。此階段包括等待 Pod 被排程的時間和通過網路下載映象的時間,
Running Pod 已經繫結到了某個節點,Pod 中所有的容器都已被建立。至少有一個容器仍在執行,或者正處於啟動或重啟狀態。
Succeeded Pod 中的所有容器都已成功終止,並且不會再重啟。
Failed Pod 中的所有容器都已終止,並且至少有一個容器是因為失敗終止。也就是說,容器以非 0 狀態退出或者被系統終止。
Unknown 因為某些原因無法取得 Pod 的狀態。這種情況通常是因為與 Pod 所在主機通訊失敗。

2.容器的狀態

Kubernetes 會跟蹤 Pod 中每個容器的狀態,就像它跟蹤 Pod 總體上的階段一樣。
旦排程器將 Pod 分派給某個節點,kubelet 就通過 容器執行時 開始為 Pod 建立容器。 容器的狀態有三種:Waiting(等待)、Running(執行中)和 Terminated(已終止)
每種狀態都有特定的含義:

  • Waiting (等待)
    如果容器並不處在 Running 或 Terminated 狀態之一,它就處在 Waiting 狀態。 處於 Waiting 狀態的容器仍在執行它完成啟動所需要的操作:例如,從某個容器映象 倉庫拉取容器映象,或者向容器應用 Secret 資料等等。 當你使用 kubectl 來查詢包含 Waiting 狀態的容器的 Pod 時,你也會看到一個 Reason 欄位,其中給出了容器處於等待狀態的原因。
  • Running(執行中)
    Running 狀態表明容器正在執行狀態並且沒有問題發生。 如果配置了 postStart 回撥,那麼該回調已經執行且已完成。 如果你使用 kubectl 來查詢包含 Running 狀態的容器的 Pod 時,你也會看到 關於容器進入 Running 狀態的資訊。
  • Terminated(已終止)
    處於 Terminated 狀態的容器已經開始執行並且或者正常結束或者因為某些原因失敗。 如果你使用 kubectl 來查詢包含 Terminated 狀態的容器的 Pod 時,你會看到 容器進入此狀態的原因、退出程式碼以及容器執行期間的起止時間。
    如果容器配置了 preStop 回撥,則該回調會在容器進入 Terminated 狀態之前執行。

3.容器探針

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

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

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

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

  • livenessProbe:指示容器是否正在執行。如果存活態探測失敗,則 kubelet 會殺死容器, 並且容器將根據其重啟策略決定未來。如果容器不提供存活探針, 則預設狀態為 Success。

  • readinessProbe:指示容器是否準備好為請求提供服務。如果就緒態探測失敗, 端點控制器將從與 Pod 匹配的所有服務的端點列表中刪除該 Pod 的 IP 地址。 初始延遲之前的就緒態的狀態值預設為 Failure。 如果容器不提供就緒態探針,則預設狀態為 Success。

  • startupProbe: 指示容器中的應用是否已經啟動。如果提供了啟動探針,則所有其他探針都會被 禁用,直到此探針成功為止。如果啟動探測失敗,kubelet 將殺死容器,而容器依其 重啟策略進行重啟。 如果容器沒有提供啟動探測,則預設狀態為 Success。

3.1 配置探針

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

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

3.2 探針配置例項

HTTPGetAction

# yaml
root@k8-deploy:~/k8s-yaml/probe# cat HTTPGetAction.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels: #rs or deployment
      app: ng-deploy-80
    #matchExpressions:
    #  - {key: app, operator: In, values: [ng-deploy-80,ng-rs-81]}
  template:
    metadata:
      labels:
        app: ng-deploy-80
    spec:
      containers:
      - name: ng-deploy-80
        image: nginx:1.21.1
        ports:
        - containerPort: 80
        livenessProbe:
          httpGet:
            path: /index.html
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 3
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /index.html
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 3
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 3

---
apiVersion: v1
kind: Service
metadata:
  name: ng-deploy-80 
spec:
  ports:
  - name: http
    port: 80
    targetPort: 80
    nodePort: 30082
    protocol: TCP
  type: NodePort
  selector:
    app: ng-deploy-80

# 建立
root@k8-deploy:~/k8s-yaml/probe# kubectl apply -f HTTPGetAction.yaml 
deployment.apps/nginx-deployment created

root@k8-deploy:~/k8s-yaml/probe# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-7c4dbc5c76-w4j8c   1/1     Running   0          7s

# 驗證
root@k8-deploy:~/k8s-yaml/probe# kubectl get ep
NAME           ENDPOINTS                                               AGE
kubernetes     192.168.2.11:6443,192.168.2.12:6443,192.168.2.13:6443   33d
ng-deploy-80   10.100.172.231:80                                       17s

root@k8-deploy:~/k8s-yaml/probe# kubectl get svc
NAME           TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
kubernetes     ClusterIP   10.0.0.1      <none>        443/TCP        33d
ng-deploy-80   NodePort    10.0.104.36   <none>        80:30082/TCP   21s

root@k8-deploy:~/k8s-yaml/probe# curl -I 192.168.2.17:30082
HTTP/1.1 200 OK
Server: nginx/1.21.1
Date: Thu, 21 Oct 2021 10:08:57 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 06 Jul 2021 14:59:17 GMT
Connection: keep-alive
ETag: "60e46fc5-264"
Accept-Ranges: bytes

TCPSocketAction

# 建立yaml
root@k8-deploy:~/k8s-yaml/probe# cat TCPSocketAction.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels: #rs or deployment
      app: ng-deploy-80
    #matchExpressions:
    #  - {key: app, operator: In, values: [ng-deploy-80,ng-rs-81]}
  template:
    metadata:
      labels:
        app: ng-deploy-80
    spec:
      containers:
      - name: ng-deploy-80
        image: nginx:1.21.1
        ports:
        - containerPort: 80
        livenessProbe:
          tcpSocket:
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 3
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 3

        readinessProbe:
          tcpSocket:
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 3
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 3
      
---
apiVersion: v1
kind: Service
metadata:
  name: ng-deploy-80 
spec:
  ports:
  - name: http
    port: 80
    targetPort: 80
    nodePort: 30083
    protocol: TCP
  type: NodePort
  selector:
    app: ng-deploy-80

# 建立
root@k8-deploy:~/k8s-yaml/probe# kubectl apply -f TCPSocketAction.yaml 
deployment.apps/nginx-deployment created

# 驗證
root@k8-deploy:~/k8s-yaml/probe# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-7584b6d9f4-c6zxf   1/1     Running   0          8s

root@k8-deploy:~/k8s-yaml/probe# kubectl get svc
NAME           TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
kubernetes     ClusterIP   10.0.0.1      <none>        443/TCP        33d
ng-deploy-80   NodePort    10.0.167.50   <none>        80:30083/TCP   16s

root@k8-deploy:~/k8s-yaml/probe# kubectl get ep
NAME           ENDPOINTS                                               AGE
kubernetes     192.168.2.11:6443,192.168.2.12:6443,192.168.2.13:6443   33d
ng-deploy-80   10.100.172.232:80                                       93s

ExecAction

# 編寫yaml
root@k8-deploy:~/k8s-yaml/probe# cat ExecAction.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-deployment
spec:
  replicas: 1
  selector:
    matchLabels: #rs or deployment
      app: redis-deploy-6379
    #matchExpressions:
    #  - {key: app, operator: In, values: [redis-deploy-6379,ng-rs-81]}
  template:
    metadata:
      labels:
        app: redis-deploy-6379
    spec:
      containers:
      - name: redis-deploy-6379
        image: redis
        ports:
        - containerPort: 6379
        readinessProbe:
          exec:
            command:
            - /usr/local/bin/redis-cli
            - quit
          initialDelaySeconds: 5
          periodSeconds: 3
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 3

        livenessProbe:
          exec:
            command:
            - /usr/local/bin/redis-cli
            - quit
          initialDelaySeconds: 5
          periodSeconds: 3
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 3
        readinessProbe:
          exec:
            command:
            - /usr/local/bin/redis-cli
            - quit
          initialDelaySeconds: 5
          periodSeconds: 3
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 3
---
apiVersion: v1
kind: Service
metadata:
  name: redis-deploy-6379 
spec:
  ports:
  - name: http
    port: 6379
    targetPort: 6379
    nodePort: 40016
    protocol: TCP
  type: NodePort
  selector:
    app: redis-deploy-6379

# 建立
root@k8-deploy:~/k8s-yaml/probe# kubectl apply -f ExecAction.yaml 
deployment.apps/redis-deployment created

# 驗證
root@k8-deploy:~/k8s-yaml/probe# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
redis-deployment-775c65c67c-dwp7r   1/1     Running   0          2m12s

root@k8-deploy:~/k8s-yaml/probe# kubectl describe pod redis-deployment-775c65c67c-dwp7r
...
    Liveness:       exec [/usr/local/bin/redis-cli quit] delay=5s timeout=5s period=3s #success=1 #failure=3
    Readiness:      exec [/usr/local/bin/redis-cli quit] delay=5s timeout=5s period=3s #success=1 #failure=3
...