亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Kubernetes 健康狀態檢查(九)

發布時間:2020-07-22 06:18:40 來源:網絡 閱讀:2636 作者:wzlinux 欄目:云計算

強大的自愈能力是 Kubernetes 這類容器編排引擎的一個重要特性。自愈的默認實現方式是自動重啟發生故障的容器。除此之外,用戶還可以利用 LivenessReadiness 探測機制設置更精細的健康檢查,進而實現如下需求:

  • 零停機部署。
  • 避免部署無效的鏡像。
  • 更加安全的滾動升級。

一、Liveness 探測

Liveness 探測讓用戶可以自定義判斷容器是否健康的條件。如果探測失敗,Kubernetes 就會重啟容器。

我們創建一個 Pod 的配置文件liveness.yaml,可以使用命令kubectl explain pod.spec.containers.livenessProbe查看其使用方法。

apiVersion: v1
kind: Pod
metadata:
  name: liveness
  labels:
    test: liveness
spec:
  restartPolicy: OnFailure
  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: 10
      periodSeconds: 5

啟動進程首先創建文件 /tmp/healthy,30 秒后刪除,在我們的設定中,如果 /tmp/healthy 文件存在,則認為容器處于正常狀態,反正則發生故障。

livenessProbe 部分定義如何執行 Liveness 探測:

  1. 探測的方法是:通過 cat 命令檢查 /tmp/healthy 文件是否存在。如果命令執行成功,返回值為零,Kubernetes 則認為本次 Liveness 探測成功;如果命令返回值非零,本次 Liveness 探測失敗。
  2. initialDelaySeconds: 10 指定容器啟動 10 之后開始執行 Liveness 探測,我們一般會根據應用啟動的準備時間來設置。比如某個應用正常啟動要花 30 秒,那么initialDelaySeconds 的值就應該大于 30。
  3. periodSeconds: 5 指定每 5 秒執行一次 Liveness 探測。Kubernetes 如果連續執行 3 次 Liveness 探測均失敗,則會殺掉并重啟容器。

下面創建 Pod liveness:

[root@master ~]# kubectl apply -f liveness.yaml 
pod/liveness created

從配置文件可知,最開始的 30 秒,/tmp/healthy 存在,cat 命令返回 0,Liveness 探測成功,這段時間 kubectl describe pod liveness 的 Events部分會顯示正常的日志。

[root@master ~]# kubectl describe pod liveness

Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Pulling    25s   kubelet, node02    pulling image "busybox"
  Normal  Pulled     24s   kubelet, node02    Successfully pulled image "busybox"
  Normal  Created    24s   kubelet, node02    Created container
  Normal  Started    23s   kubelet, node02    Started container
  Normal  Scheduled  23s   default-scheduler  Successfully assigned default/liveness to node02

35 秒之后,日志會顯示 /tmp/healthy 已經不存在,Liveness 探測失敗。再過幾十秒,幾次探測都失敗后,容器會被重啟。

[root@master ~]# kubectl describe pod liveness

Events:
  Type     Reason     Age                    From               Message
  ----     ------     ----                   ----               -------
  Normal   Scheduled  6m9s                   default-scheduler  Successfully assigned default/liveness to node02
  Normal   Pulled     3m41s (x3 over 6m10s)  kubelet, node02    Successfully pulled image "busybox"
  Normal   Created    3m41s (x3 over 6m10s)  kubelet, node02    Created container
  Normal   Started    3m40s (x3 over 6m9s)   kubelet, node02    Started container
  Warning  Unhealthy  2m57s (x9 over 5m37s)  kubelet, node02    Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
  Normal   Pulling    2m27s (x4 over 6m11s)  kubelet, node02    pulling image "busybox"
  Normal   Killing    60s (x4 over 4m57s)    kubelet, node02    Killing container with id docker://liveness:Container failed liveness probe.. Container will be killed and recreated.

然后我們查看容器,已經重啟了一次。

[root@master ~]# kubectl get pod
NAME       READY   STATUS    RESTARTS   AGE
liveness   1/1     Running   3          5m13s

二、Readiness 探測

用戶通過 Liveness 探測可以告訴 Kubernetes 什么時候通過重啟容器實現自愈;Readiness 探測則是告訴 Kubernetes 什么時候可以將容器加入到 Service 負載均衡池中,對外提供服務。

Readiness 探測的配置語法與 Liveness 探測完全一樣,我們創建配置文件readiness.yaml

apiVersion: v1
kind: Pod
metadata:
  name: readiness
  labels:
    test: readiness
spec:
  restartPolicy: OnFailure
  containers:
  - name: readiness
    image: busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
    readinessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 10
      periodSeconds: 5

創建 Pod,然后查看其狀態。

[root@master ~]# kubectl apply -f readiness.yaml 
pod/readiness created

剛剛創建時,READY 狀態為不可用。

[root@master ~]# kubectl get pod
NAME        READY   STATUS    RESTARTS   AGE
readiness   0/1     Running   0          21s

15 秒后(initialDelaySeconds + periodSeconds),第一次進行 Readiness 探測并成功返回,設置 READY 為可用。

[root@master ~]# kubectl get pod
NAME        READY   STATUS    RESTARTS   AGE
readiness   1/1     Running   0          38s

30 秒后,/tmp/healthy 被刪除,連續 3 次 Readiness 探測均失敗后,READY 被設置為不可用。

[root@master ~]# kubectl get pod
NAME        READY   STATUS    RESTARTS   AGE
readiness   0/1     Running   0          63s

通過 kubectl describe pod readiness 也可以看到 Readiness 探測失敗的日志。

Events:
  Type     Reason     Age                   From               Message
  ----     ------     ----                  ----               -------
  Normal   Pulling    5m29s                 kubelet, node01    pulling image "busybox"
  Normal   Scheduled  5m25s                 default-scheduler  Successfully assigned default/readiness to node01
  Normal   Pulled     5m13s                 kubelet, node01    Successfully pulled image "busybox"
  Normal   Created    5m12s                 kubelet, node01    Created container
  Normal   Started    5m12s                 kubelet, node01    Started container
  Warning  Unhealthy  28s (x51 over 4m38s)  kubelet, node01    Readiness probe failed: cat: can't open '/tmp/healthy': No such file or directory

下面對 Liveness 探測和 Readiness 探測做個比較:

  1. Liveness 探測和 Readiness 探測是兩種 Health Check 機制,如果不特意配置,Kubernetes 將對兩種探測采取相同的默認行為,即通過判斷容器啟動進程的返回值是否為零來判斷探測是否成功。
  2. 兩種探測的配置方法完全一樣,支持的配置參數也一樣。不同之處在于探測失敗后的行為:Liveness 探測是重啟容器;Readiness 探測則是將容器設置為不可用,不接收 Service 轉發的請求。
  3. Liveness 探測和 Readiness 探測是獨立執行的,二者之間沒有依賴,所以可以單獨使用,也可以同時使用。用 Liveness 探測判斷容器是否需要重啟以實現自愈;用 Readiness 探測判斷容器是否已經準備好對外提供服務。

三、Health Check 在 Scale Up 中的應用

對于多副本應用,當執行 Scale Up 操作時,新副本會作為 backend 被添加到 Service 的負責均衡中,與已有副本一起處理客戶的請求。考慮到應用啟動通常都需要一個準備階段,比如加載緩存數據,連接數據庫等,從容器啟動到正真能夠提供服務是需要一段時間的。我們可以通過 Readiness 探測判斷容器是否就緒,避免將請求發送到還沒有 ready 的 backend。

下面我們創建一個配置文件來說明這種情況。

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 3
  template:
    metadata:
      labels:
        run: web
    spec:
      containers:
      - name: web
        images: myhttpd
        ports:
        - containerPort: 8080
        readinessProbe:
          httpGet:
            scheme: HTTP
            path: /health
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: web-svc
spec:
  selector:
    run: web
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 80

重點關注 readinessProbe 部分。這里我們使用了不同于 exec 的另一種探測方法 -- httpGet。Kubernetes 對于該方法探測成功的判斷條件是 http 請求的返回代碼在 200-400 之間。

  • schema 指定協議,支持 HTTP(默認值)和 HTTPS。
  • path 指定訪問路徑。
  • port 指定端口。

上面配置的作用是:

  1. 容器啟動 10 秒之后開始探測。
  2. 如果 http://[container_ip]:8080/healthy 返回代碼不是 200-400,表示容器沒有就緒,不接收 Service web-svc 的請求。
  3. 每隔 5 秒再探測一次。
  4. 直到返回代碼為 200-400,表明容器已經就緒,然后將其加入到 web-svc 的負責均衡中,開始處理客戶請求。
  5. 探測會繼續以 5 秒的間隔執行,如果連續發生 3 次失敗,容器又會從負載均衡中移除,直到下次探測成功重新加入。

對于生產環境中重要的應用都建議配置 Health Check,保證處理客戶請求的容器都是準備就緒的 Service backend。

四、Health Check 在 Rolling Update 中的應用

Health Check 另一個重要的應用場景是 Rolling Update。試想一下下面的情況,現有一個正常運行的多副本應用,接下來對應用進行更新(比如使用更高版本的 image),Kubernetes 會啟動新副本,然后發生了如下事件:

  1. 正常情況下新副本需要 10 秒鐘完成準備工作,在此之前無法響應業務請求。
  2. 但由于人為配置錯誤,副本始終無法完成準備工作(比如無法連接后端數據庫)。

因為新副本本身沒有異常退出,默認的 Health Check 機制會認為容器已經就緒,進而會逐步用新副本替換現有副本,其結果就是:當所有舊副本都被替換后,整個應用將無法處理請求,無法對外提供服務。如果這是發生在重要的生產系統上,后果會非常嚴重。

如果正確配置了 Health Check,新副本只有通過了 Readiness 探測,才會被添加到 Service;如果沒有通過探測,現有副本不會被全部替換,業務仍然正常進行。

下面通過例子來實踐 Health Check 在 Rolling Update 中的應用。

用如下配置文件 app.v1.yml 模擬一個 10 副本的應用:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: app
spec:
  replicas: 10
  template:
    metadata:
      labels:
        run: app
    spec:
      containers:
      - name: app
        images: busybox
        args:
        - /bin/sh
        - -c
        - sleep 10; touch /tmp/healthy; sleep 30000
        readinessProbe:
          exec:
            command:
            - cat
            - /tmp/healthy
          initialDelaySeconds: 10
          periodSeconds: 5

10 秒后副本能夠通過 Readiness 探測。

[root@master ~]# kubectl apply -f app.v1.yaml 
deployment.extensions/app created
[root@master ~]# kubectl get pods
NAME                   READY   STATUS    RESTARTS   AGE
app-56878b4676-4rftg   1/1     Running   0          34s
app-56878b4676-6jtn4   1/1     Running   0          34s
app-56878b4676-6smfj   1/1     Running   0          34s
app-56878b4676-8pnc2   1/1     Running   0          34s
app-56878b4676-hxzjk   1/1     Running   0          34s
app-56878b4676-mglht   1/1     Running   0          34s
app-56878b4676-t2qs6   1/1     Running   0          34s
app-56878b4676-vgw44   1/1     Running   0          34s
app-56878b4676-vnxfx   1/1     Running   0          34s
app-56878b4676-wb9rh   1/1     Running   0          34s

接下來滾動更新應用,配置文件 app.v2.yml如下:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: app
spec:
  replicas: 10
  template:
    metadata:
      labels:
        run: app
    spec:
      containers:
      - name: app
        image: busybox
        args:
        - /bin/sh
        - -c
        - sleep 30000
        readinessProbe:
          exec:
            command:
            - cat
            - /tmp/healthy
          initialDelaySeconds: 10
          periodSeconds: 5

很顯然,由于新副本中不存在 /tmp/healthy,是無法通過 Readiness 探測的。驗證如下:

[root@master ~]# kubectl apply -f app.v2.yaml 
deployment.extensions/app configured
[root@master ~]# kubectl get pod
NAME                   READY   STATUS    RESTARTS   AGE
app-56878b4676-4rftg   1/1     Running   0          4m42s
app-56878b4676-6jtn4   1/1     Running   0          4m42s
app-56878b4676-6smfj   1/1     Running   0          4m42s
app-56878b4676-hxzjk   1/1     Running   0          4m42s
app-56878b4676-mglht   1/1     Running   0          4m42s
app-56878b4676-t2qs6   1/1     Running   0          4m42s
app-56878b4676-vgw44   1/1     Running   0          4m42s
app-56878b4676-vnxfx   1/1     Running   0          4m42s
app-56878b4676-wb9rh   1/1     Running   0          4m42s
app-84fc656775-hf954   0/1     Running   0          66s
app-84fc656775-p287w   0/1     Running   0          66s
[root@master ~]# kubectl get deploy
NAME   READY   UP-TO-DATE   AVAILABLE   AGE
app    9/10    2            9           7m1s

先關注 kubectl get pod 輸出:

  1. 從 Pod 的 AGE 欄可判斷,最后 2 個 Pod 是新副本,目前處于 NOT READY 狀態。
  2. 舊副本從最初 10 個減少到 8 個。

再來看 kubectl get deployment app 的輸出:

  1. DESIRED 10 表示期望的狀態是 10 個 READY 的副本。
  2. UP-TO-DATE 2 表示當前已經完成更新的副本數:即 2 個新副本。
  3. AVAILABLE 9 表示當前處于 READY 狀態的副本數:即 9個舊副本。

在我們的設定中,新副本始終都無法通過 Readiness 探測,所以這個狀態會一直保持下去。

上面我們模擬了一個滾動更新失敗的場景。不過幸運的是:Health Check 幫我們屏蔽了有缺陷的副本,同時保留了大部分舊副本,業務沒有因更新失敗受到影響。

滾動更新可以通過參數 maxSurgemaxUnavailable 來控制副本替換的數量。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

自治县| 涿鹿县| 崇阳县| 博乐市| 芒康县| 新泰市| 宝清县| 中江县| 密云县| 郑州市| 阿坝县| 轮台县| 中西区| 朝阳市| 东海县| 永新县| 四会市| 红原县| 中方县| 资兴市| 青冈县| 邢台市| 清涧县| 平原县| 湖口县| 曲阳县| 皋兰县| 长武县| 邹城市| 沁阳市| 桃园市| 丹江口市| 石楼县| 皮山县| 张家界市| 五寨县| 北流市| 赤峰市| 祁门县| 盐池县| 湖州市|