全部產品
Search
文件中心

Container Service for Kubernetes:應用零中斷部署:變換與優雅下線配置實踐

更新時間:Nov 19, 2025

為保障ACK叢集應用程式更新不中斷服務,可通過配置Deployment的就緒探針、readinessGates、preStop鉤子和SLB優雅中斷等,實現流量的平滑遷移,保障業務持續高可用。

工作原理

為確保服務升級時的高可用性,可基於無狀態(Deployment)應用的變換(Rolling Update)策略,通過逐個替換Pod的方式確保應用始終存在能夠接入流量的Pod。其核心流程可分為以下幾個階段:

  1. 啟動階段:首先,建立新版本(v2)的Pod。Kubernetes會等待新Pod通過就緒檢查,確認其能夠正常處理請求。在此之前,它不會接收任何來自Service的流量。

  2. 流量切換階段:啟用 readinessGates 後,新Pod需先完成就緒檢查,然後將其IP註冊到Service關聯的Endpoints中,並且同步到負載平衡器(SLB)的後端組才能開始接入流量。隨後,系統向舊版本(v1)Pod發送終止訊號,並將其IP從Endpoints中移除,使其不再接收新的業務請求。

    詳細原理解釋,請參考readinessGate工作原理
  3. 優雅下線階段:舊Pod在被徹底刪除前,會先執行預定義的preStop鉤子,並利用優雅終止寬限期(terminationGracePeriodSeconds)處理完已建立的串連,與此同時SLB也會進行存量串連優雅中斷。此過程確保了所有正在處理的請求都能正常完成,最終實現零中斷變換。

適用範圍

部署樣本應用

以下為一個Nginx無狀態應用的部署樣本。

控制台

  1. ACK叢集列表頁面,單擊目的地組群名稱,在叢集詳情頁左側導覽列,選擇工作负载 > 无状态

  2. 無狀態頁面,單擊使用YAML建立資源,然後將以下內容複寫到模板地區,單擊建立

    樣本應用YAML

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment-demo
    spec:
      replicas: 1                 # 生產環境建議配置2以上保證高可用,此處方便驗證滾動部署設定為1
      selector:
        matchLabels:
          app: nginx-demo
      # 變換策略:保證更新期間服務不中斷,
      # strategy:
        # type: RollingUpdate     # Deployment工作負載預設為RollingUpdate策略
        # rollingUpdate:
          # maxUnavailable: "25%" # 預設值,更新過程中最多允許25%的Pod副本處於不可用狀態
          # maxSurge: "25%"       # 預設值,更新過程中允許建立的Pod總數最多可超出期望副本數的 25%
      template:
        metadata:
          labels:
            app: nginx-demo 
        spec:
          # Pod層級的優雅下線總時限。必須大於 preStop 鉤子執行時間與應用清理時間之和
          terminationGracePeriodSeconds: 60 
          readinessGates:
          - conditionType: service.readiness.alibabacloud.com/nginx-demo-service # 設定nginx-demo-service服務的Readiness Gate
          containers:
          - name: nginx
            image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
            ports:
            - containerPort: 80
            resources:
              requests:
                cpu: 500m
                memory: 1Gi
              limits:
                cpu: 500m
            # --- 健全狀態檢查探針 ---
            # 啟動探針 (Startup Probe): 確保容器內應用已完成啟動
            startupProbe:
              httpGet:
                path: / # Nginx預設根路徑可訪問即代表啟動成功
                port: 80
              # 給予應用足夠長的啟動時間。總逾時 = failureThreshold * periodSeconds
              # 總逾時時間為 failureThreshold * periodSeconds,即 30 * 10 = 300 秒
              failureThreshold: 30
              periodSeconds: 10
            # 就緒探針 (Readiness Probe): 判斷容器是否準備好接收流量
            readinessProbe:
              httpGet:
                path: /
                port: 80
              initialDelaySeconds: 5  # 容器啟動後5秒開始探測
              periodSeconds: 5        # 每5秒探測一次
              timeoutSeconds: 2       # 探測逾時時間
              successThreshold: 1     # 1次成功即標記為就緒
              failureThreshold: 3     # 連續3次失敗即標記為不就緒
            # --- 服務優雅下線配置 ---
            lifecycle:
              preStop:
                exec:
                  # 建議根據業務自行設定鉤子方法,等待存量串連處理完成然後關閉應用
                  # 若只使用sleep命令可能會導致優雅下線無法正常退出
                  command: ["sh", "-c", "sleep 30 && /usr/sbin/nginx -s quit"]
    ---           
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-demo-service
      annotations:
        # 設定串連優雅中斷逾時時間,此值應接近應用preStop中處理存量串連的時間長度,取值範圍[10, 900]
        service.beta.kubernetes.io/alibaba-cloud-loadbalancer-connection-drain-timeout: "30" 
        # 開啟串連優雅中斷功能
        service.beta.kubernetes.io/alibaba-cloud-loadbalancer-connection-drain: "on"
    spec:
      type: LoadBalancer
      selector:
        app: nginx-demo 
      ports:
        - protocol: TCP
          port: 80
  3. 在彈窗中找到目標無狀態應用,單擊查看,確認Pod狀態為Running。 

kubectl

  1. 擷取叢集KubeConfig並通過kubectl工具串連叢集

  2. 將以下YAML內容儲存為nginx-demo.yaml檔案。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment-demo
    spec:
      replicas: 1                 # 生產環境建議配置2以上保證高可用,此處方便驗證滾動部署設定為1
      selector:
        matchLabels:
          app: nginx-demo
      # 變換策略:保證更新期間服務不中斷,
      # strategy:
        # type: RollingUpdate     # Deployment工作負載預設為RollingUpdate策略
        # rollingUpdate:
          # maxUnavailable: "25%" # 預設值,更新過程中最多允許25%的Pod副本處於不可用狀態
          # maxSurge: "25%"       # 預設值,更新過程中允許建立的Pod總數最多可超出期望副本數的 25%
      template:
        metadata:
          labels:
            app: nginx-demo 
        spec:
          # Pod層級的優雅下線總時限。必須大於 preStop 鉤子執行時間與應用清理時間之和
          terminationGracePeriodSeconds: 60 
          readinessGates:
          - conditionType: service.readiness.alibabacloud.com/nginx-demo-service # 設定nginx-demo-service服務的Readiness Gate
          containers:
          - name: nginx
            image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
            ports:
            - containerPort: 80
            resources:
              requests:
                cpu: 500m
                memory: 1Gi
              limits:
                cpu: 500m
            # --- 健全狀態檢查探針 ---
            # 啟動探針 (Startup Probe): 確保容器內應用已完成啟動
            startupProbe:
              httpGet:
                path: / # Nginx預設根路徑可訪問即代表啟動成功
                port: 80
              # 給予應用足夠長的啟動時間。總逾時 = failureThreshold * periodSeconds
              # 總逾時時間為 failureThreshold * periodSeconds,即 30 * 10 = 300 秒
              failureThreshold: 30
              periodSeconds: 10
            # 就緒探針 (Readiness Probe): 判斷容器是否準備好接收流量
            readinessProbe:
              httpGet:
                path: /
                port: 80
              initialDelaySeconds: 5  # 容器啟動後5秒開始探測
              periodSeconds: 5        # 每5秒探測一次
              timeoutSeconds: 2       # 探測逾時時間
              successThreshold: 1     # 1次成功即標記為就緒
              failureThreshold: 3     # 連續3次失敗即標記為不就緒
            # --- 服務優雅下線配置 ---
            lifecycle:
              preStop:
                exec:
                  # 建議根據業務自行設定鉤子方法,等待存量串連處理完成然後關閉應用
                  # 若只使用sleep命令可能會導致優雅下線無法正常退出
                  command: ["sh", "-c", "sleep 30 && /usr/sbin/nginx -s quit"]
    ---           
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-demo-service
      annotations:
        # 設定串連優雅中斷逾時時間,此值應接近應用preStop中處理存量串連的時間長度,取值範圍[10, 900]
        service.beta.kubernetes.io/alibaba-cloud-loadbalancer-connection-drain-timeout: "30" 
        # 開啟串連優雅中斷功能
        service.beta.kubernetes.io/alibaba-cloud-loadbalancer-connection-drain: "on"
    spec:
      type: LoadBalancer
      selector:
        app: nginx-demo 
      ports:
        - protocol: TCP
          port: 80
  3. 部署Nginx應用並建立服務(Service)。

    kubectl apply -f nginx-demo.yaml
  4. 確認目標應用Pod狀態為Running

    kubectl get pod | grep nginx-deployment-demo
  • Pod就緒檢查

    • startupProbe (啟動探針):用於啟動較慢的應用(如Java)檢測是否完成啟動。啟動探測成功前,就緒探針和存活探針不會被執行,防止啟動緩慢而被Kubelet誤判為失敗並重啟。

    • readinessProbe (就緒探針):用於判斷容器是否準備好處理外部請求。就緒檢查成功後,Pod的IP地址會加入其關聯的所有 Service 的Endpoints中,表示可以接入流量。

    • readinessGates:在 readinessProbe 的基礎上等待 readinessGates 的狀態也可用時,才視為Pod完全就緒,然後正式接入流量。

  • 優雅下線

    • 應用優雅下線

      • preStop :容器終止前執行的鉤子命令,可設定應用優雅下線的命令,確儲存量串連處理完成,保障服務無損下線。

        建議根據業務自行設定鉤子方法,若只使用sleep命令可能會導致優雅下線無法正常退出。
      • terminationGracePeriodSeconds:Pod從被標記為終止到被強制殺死(SIGKILL訊號)前的總時間長度,預設為30秒。該值必須充足,以覆蓋preStop鉤子的執行時間與容器自身清理時間之和。

    • SLB串連優雅中斷

      • service.beta.kubernetes.io/alibaba-cloud-loadbalancer-connection-drain註解:為SLB開啟串連優雅中斷功能。

      • service.beta.kubernetes.io/alibaba-cloud-loadbalancer-connection-drain-timeout註解:SLB存量串連優雅中斷逾時時間長度(單位:秒)。建議配置為接近preStop中處理存量串連請求的時間長度。

  • 變換策略

    • strategy:Deployment的預設更新策略為RollingUpdate,採用漸進式替換方式,逐步建立新版本Pod,並在新Pod就緒後刪除對應的舊版本Pod,確保服務在更新過程中持續可用。

    • maxUnavailable:變換過程中最大不可用Pod副本數。預設值25%,可填寫數字。

    • maxSurge:變換過程中,允許超出期望副本數的 Pod 數量上限。配置越大,更新速度越快,但佔用資源更多。預設值25%,可填寫數字。

驗證零中斷滾動部署

  1. 擷取叢集KubeConfig並通過kubectl工具串連叢集

  2. 擷取樣本應用訪問地址。

    export NGINX_ENDPOINT=$(kubectl get service nginx-demo-service -o jsonpath='{.status.loadBalancer.ingress[0].ip}{":"}{.spec.ports[0].port}')
    echo $NGINX_ENDPOINT
  3. 安裝壓測工具hey。進行壓力測試,以200的並發度執行50000次請求(按照樣本的資源配置單副本運行通常在1分鐘左右)。

    hey -c 200 -n 50000  -disable-keepalive http://$NGINX_ENDPOINT

    同時立即開啟一個新命令列視窗執行Deployment重啟操作。

    kubectl rollout restart deployment nginx-deployment-demo
  4. 預期輸出結果對照。

    部署方案類型

    預期輸出

    未配置零中斷滾動部署

    未配置零中斷的YAML樣本

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment-demo
    spec:
      replicas: 1                 # 生產環境建議配置2以上保證高可用,此處方便驗證滾動部署設定為1
      selector:
        matchLabels:
          app: nginx-demo
      template:
        metadata:
          labels:
            app: nginx-demo 
        spec:
          containers:
          - name: nginx
            image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
            ports:
            - containerPort: 80
            resources:
              requests:
                cpu: 500m
                memory: 1Gi
              limits:
                cpu: 500m
    ---           
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-demo-service
    spec:
      type: LoadBalancer
      selector:
        app: nginx-demo 
      ports:
        - protocol: TCP
          port: 80

    流量有損。

    Status code distribution:
      [200]	49644 responses
    
    Error distribution:
      [320]	Get "http://114.215.XXX.XXX": dial tcp 114.215.XXX.XXX:80: connect: connection refused
      [18]	Get "http://114.215.XXX.XXX": dial tcp 114.215.XXX.XXX:80: connect: no route to host
      [18]	Get "http://114.215.XXX.XXX": dial tcp 114.215.XXX.XXX:80: connect: operation timed out

    已配置零中斷滾動部署

    流量無損。

    Status code distribution:
      [200]	50000 responses

常見問題

Pod啟動時一直處於Running但未就緒狀態(Snipaste_2025-11-05_13-57-58

原因說明:通常由於啟動探測或就緒探測失敗導致。

解決方案

  • 就緒檢查配置:進入目標工作負載編輯頁,確認健全狀態檢查請求路徑(如/healthz)和連接埠與實際應用提供的是否一致。如啟動時間較長,可增加不健康閾值,避免過早判定為失敗。

    可臨時關閉就緒檢查,進入Pod終端或其所在宿主機,使用命令(如curl)驗證健全狀態檢查方法是否能正確響應。
  • 排查業務異常:結合Pod事件日誌(勾選顯示上個容器退出時的日誌)排查。

相關文檔