日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

使用preStop Hook實現ALB Ingress后端Pod滾動升級時平滑下線Pod

您可以配置preStop Hook,實現ALB Ingress后端Pod的平滑下線,使Pod在被ALB Ingress Controller完全從后端服務組中移除后才正式下線。配置后,容器在滾動更新期間能夠保障服務的流量無縫切換,避免出現中斷。

前提條件

原理介紹

Pod生命周期

Pod中的容器包括兩種類型:

  • 初始化容器(Init容器):運行服務的主容器前置依賴的容器,完成一些初始化操作。

  • 主容器(工作容器):運行服務進程的容器。

Pod啟動過程如下:

image
  1. 運行初始化容器:在主容器啟動之前,要運行的容器,為主容器執行預置操作。

  2. 運行主容器:

    1. 容器啟動后執行postStart Hook函數。

    2. 容器執行存活性探測(Liveness Probe)、就緒性檢測(Readiness Probe)。

    3. 在容器退出前執行preStop Hook函數。

Pod終止流程和網絡規則更新流程

在刪除Pod時K8s會同時進行Pod終止和網絡規則更新兩個主要的流程。Pod終止流程和網絡更新流程如下。

Pod終止流程

  1. kube-apiserver收到Pod刪除請求,將Pod標記為Terminating狀態。

  2. 如果Pod定義了preStop Hook,將執行preStop Hook。

  3. K8s集群向容器發送SIGTERM信號。

  4. 等待容器停止,或等待Pod刪除寬限期超時。

    說明

    Pod中容器刪除寬限期terminationGracePeriodSeconds默認為30秒。

  5. 超時Pod刪除寬限期后容器仍未終止,K8s發送SIGKILL信號給容器。

  6. Pod被完全刪除。

網絡規則更新流程

  1. kube-apiserver收到Pod刪除請求,將Pod標記為Terminating狀態。

  2. Endpoint Controller從Endpoint對象中刪除Pod的IP。

  3. ALB Ingress Controller進行Server節點調諧,將Service Endpoints從后端服務器組中移除,不再將流量路由到被刪除的Pod。

使用preStop Hook來實現Pod平滑下線

當Pod滾動升級過程中,如果舊的Pod沒有平滑退出,將導致應用無法正常處理業務請求,出現如下錯誤狀態碼,影響應用的可用性。

狀態碼

問題原因

504

當舊Pod在未處理完正常請求情況下被刪除,并且該請求為非冪等。

502

當ACK集群已經刪除舊Pod,容器收到終止信號(SIGTERM)并迅速終止,但ALB Ingress Controller仍在調諧流程中,導致Pod未及時從后端服務器組中移除,流量依然被錯誤地路由到已終止的舊Pod上。

為了避免以上的情況發生,您可以采取如下方案。

kube-apiserver接收到Pod刪除請求時,通過在Deployment配置內添加preStop Hook,可以為容器設置一個"Sleep"暫停期。這個暫停期是讓容器有時間在收到SIGTERM之前完成網絡規則的更新,并等待ALB Ingress Controller完成Server調諧事件并確保Pod已從后端服務器組中移除。這一步驟對于保障Pod的平穩下線至關重要,避免在滾動更新或服務重啟期間造成流量中斷。

同時,Kubernetes為容器設定了在接收到SIGTERM后能持續運行的最大寬限期(terminationGracePeriodSeconds)為30秒。當程序關閉時間與preStop Hook指定的操作時間之和超過了30秒時,默認寬限期將不足以讓容器完成所有的關閉步驟。kubelet會在等待2秒后直接給容器發送立即終止(SIGKILL)信號,導致容器強制退出。

說明

如果程序的關閉時間和在Deployment配置的preStop Hook之和超過30秒,應將terminationGracePeriodSeconds重新設置,調整為大于30秒,確保容器優雅退出。

步驟一:并配置Pod平滑退出preStop Hook

  1. 創建并保存tea-service.yaml,配置確保Pod平滑退出的preStop Hook。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: tea
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: tea
      template:
        metadata:
          labels:
            app: tea
        spec:
          containers:
          - name: tea
            image: registry.cn-hangzhou.aliyuncs.com/acs-sample/nginxdemos:latest
            ports:
            - containerPort: 80
            lifecycle:  # 設置preStop Hook函數,使kube-apiserver等待10秒后再向Pod發送SIGTERM信號。
              preStop:  # preStop鉤子設置。
                exec:  # 通過執行命令的方式來實現preStop操作。
                  command:  # 定義要執行的命令。
                  - /bin/sh
                  - -c
                  - "sleep 10"  # 執行sleep操作,暫停10秒。
          terminationGracePeriodSeconds: 45  # 設置Pod刪除寬限期。
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: tea-svc
    spec:
      ports:
      - port: 80
        targetPort: 80
        protocol: TCP
      selector:
        app: tea
      type: NodePort
  2. 執行以下命令,部署示例Deployment和Service。

    kubectl apply -f tea-service.yaml
  3. 創建并保存tea-ingress.yaml文件,用于配置Ingress。

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
    metadata:
      name: tea-ingress
    spec:
      ingressClassName: alb
      rules:
       - host: demo.ingress.top
         http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: tea-svc
                port:
                  number: 80
  4. 執行以下命令,部署Ingress。

    kubectl apply -f tea-ingress.yaml
  5. 執行以下命令,獲取ALB Ingress的ADDRESS

    kubectl get ingress

    預期輸出:

    NAME                    CLASS   HOSTS                     ADDRESS                                              PORTS   AGE
    tea-ingress             alb     demo.ingress.top          alb-110zvs5nhsvfv*****.cn-chengdu.alb.aliyuncs.com   80      7m5s

步驟二:結果驗證

  1. 啟動測試腳本。

    1. 使用以下內容,創建test.sh測試腳本文件。此腳本用于測試應用的可用性,按每秒一次的頻率請求Nginx服務并查看狀態碼。

      #!/bin/bash
      HOST="demo.ingress.top"
      DNS="alb-110zvs5nhsvfv*****.cn-chengdu.alb.aliyuncs.com"   # 填寫ALB Ingress的ADDRESS值。
      printf "Response Code|| TIME \n" >> log.txt
      
      while true; do
        RESPONSE=$(curl -H Host:$HOST  -s -o /dev/null -w "%{http_code}" -m 1  http://$DNS/)
        TIMESTAMP=$(date +%Y-%m-%d_%H:%M:%S)
        echo "$TIMESTAMP - $RESPONSE" >> log.txt
        sleep 1
      done
    2. 執行以下命令運行測試腳本test.sh

      bash test.sh
  2. 執行以下命令,重新部署應用,觸發Pod滾動升級。

    kubectl rollout restart deploy tea 
  3. 驗證Pod滾動升級。

    1. 初始階段應用副本數為3。

      image

    2. 在重新部署應用時,新Pod創建階段由于新Pod沒有就緒,舊Pod仍在提供服務,會同時運行新舊兩個Pod。

      image

    3. 新Pod就緒且成功掛載至ALB后端服務器組后,會終止舊Pod。

      image

    4. 所有舊Pod完成preStop Hook函數或超出terminationGracePeriodSeconds超時時間后,kubectl會向Container發送信號終止舊的Pod,此時滾動更新完成。

      image

  4. 查看測試腳本執行結果。檢查滾動更新過程中請求的狀態碼,可以看到狀態碼全部為200,更新過程沒有中斷。

    執行如下命令,查看測試腳本執行結果。

    cat log.txt

    預期輸出:

    image

相關文檔