全部產品
Search
文件中心

Container Service for Kubernetes:通過配置Readiness Gate確保Pod平滑更新

更新時間:Dec 25, 2025

在使用LoadBalancer類型的Service暴露後端Pod時,當Pod進行變換,可能會由於Pod更新速度快於負載平衡器後端伺服器組的掛載速度而導致訪問中斷。您可以通過配置Readiness Gate來確保Pod的平滑更新。本文將介紹如何使用Pod Readiness Gate機制實現Pod平滑更新。

適用範圍

使用說明

當使用 LoadBalancer 類型的 Service 暴露應用,並在進行變換(Rolling Update)時,可能會遇到短暫的服務中斷或串連失敗。

  • 問題原因

    新 Pod 的啟動速度通常快於負載平衡更新後端伺服器列表的速度。在新 Pod 容器已就緒、但其 IP 尚未被添加到負載平衡後端時,變換機制可能已經開始終止舊 Pod。這導致部分請求流量仍被導向正在終止或已從負載平衡移除的舊 Pod,從而引發訪問失敗。

  • 解決方案

    可在Pod YAML配置中Pod Readiness Gate機制,通過自訂條件控制Pod的就緒狀態。Readiness Gate允許設定自訂條件(例如與LoadBalancer Service相關的service.readiness.alibabacloud.com/<Service Name>)。只有當這些條件滿足時,Pod才會被標記為Ready,並開始正式接收流量。

  • 操作樣本步驟

    image
  • 工作原理

    當 Pod 配置 readinessGates 後,其就緒流程如下:

    1. 容器探針就緒 kubelet運行容器的 readinessProbe。探針成功後,Pod 的 ContainersReady 狀態變為 True。此時,Pod 整體仍為非就緒狀態,等待其他Readiness Gate狀態的確認。

    2. CCM添加後端 CCM 監測到容器就緒後,將該 Pod 的 IP 位址添加到指定負載平衡的後端伺服器組中。添加成功後,CCM 會為Pod添加對應Service的Condition(如service.readiness.alibabacloud.com/my-svc),並將其狀態設定為True

    3. Pod 最終就緒 kubelet確認所有 Readiness Gate 條件均為 True 後,將 Pod 的最終 Ready 狀態設定為 True。至此,Pod 才被正式視為就緒,同時變換流程可以安全地終止舊 Pod。

  • 注意事項

    • Service 必須存在: 確保 readinessGates 中引用的 Service 名稱正確無誤,並且該 Service 真實存在於叢集中。如果 Service 名稱錯誤或在 Pod 啟動期間被刪除,CCM 無法完成添加後端的操作,Pod 將永遠無法達到 Ready 狀態,導致部署流程卡住。

    • 支援多個 Service: 一個 Pod 需要配置多個 readinessGates.conditionType,對應掛載到多個不同的 LoadBalancer Service。此時,Pod 必須被成功添加到所有 Service 的後端後,才會最終變為就緒狀態。

操作步驟

自動注入Readiness Gate

當開啟Pod ReadinessGate Webhook能力後,可通過在命名空間添加標籤k8s.alibabacloud.com/pod-readiness-gate-inject: enabled的方式,為該命名空間下的所有Pod開啟ReadinessGate自動注入能力。

以下介紹如何為default命名空間開啟自動注入功能。

步驟一:添加自動注入標籤

  1. default命名空間添加標籤k8s.alibabacloud.com/pod-readiness-gate-inject: enabled,開啟自動注入能力。

    kubectl label namespace default k8s.alibabacloud.com/pod-readiness-gate-inject=enabled

    預期輸出:

    namespace/default labeled
  2. 驗證命名空間上標籤:

    kubectl get namespace default -oyaml

    預期輸出:

    apiVersion: v1
    kind: Namespace
    metadata:
      creationTimestamp: "2025-11-13T07:18:37Z"
      labels:
        k8s.alibabacloud.com/pod-readiness-gate-inject: enabled
        kubernetes.io/metadata.name: default
      name: default
      resourceVersion: "6440182"
      uid: 73aff814-ae29-465a-98a4-6d37b9b8ee1a
    spec:
      finalizers:
      - kubernetes
    status:
      phase: Active

    可見,標籤已被添加至命名空間上。

步驟二:建立負載平衡服務

  1. 參見以下YAML,建立my-svc.yaml,按需建立傳統型負載平衡CLB或網路型負載平衡NLB執行個體。

    CLB

    apiVersion: v1
    kind: Service
    metadata:
      name: my-svc
      namespace: default # 命名空間為default。
    spec:
      ports:
      - port: 80
        targetPort: 80
        protocol: TCP
      selector:
        app: nginx
      type: LoadBalancer

    NLB

    apiVersion: v1
    kind: Service
    metadata:
      name: my-svc
      annotations:
        service.beta.kubernetes.io/alibaba-cloud-loadbalancer-zone-maps: "${zone-A}:${vsw-A},${zone-B}:${vsw-B}" # 例如cn-hangzhou-k:vsw-i123456,cn-hangzhou-j:vsw-j654321。
    spec:
      loadBalancerClass: alibabacloud.com/nlb # 指定負載平衡類型為NLB。
      ports:
      - port: 80
        targetPort: 80
        protocol: TCP
      selector:
        app: nginx
      type: LoadBalancer
  2. 建立樣本Service。

    kubectl apply -f my-svc.yaml
  3. 查看當前Service狀態。

    kubectl get service my-svc

    等待出現<IP地址/網域名稱>後,即可確認對應的Server Load Balancer執行個體已建立完成。

    NAME     TYPE           CLUSTER-IP       EXTERNAL-IP       PORT(S)        AGE
    my-svc   LoadBalancer   192.XX.XX.215    <IP地址/網域名稱>     80:30493/TCP   8s

步驟三:建立樣本Deployment

  1. 參見以下YAML,建立my-nginx.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-nginx    # 樣本名稱
      namespace: default # 命名空間為default
      labels:
        app: nginx
    spec:
      replicas: 2       # 設定副本數量
      selector:
        matchLabels:
          app: nginx     # 對應服務中Selector的值需要與其一致,才可以通過服務公開
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
            ports:
            - containerPort: 80                                # 需要在服務中暴露該連接埠
  2. 部署樣本Deployment。

    kubectl apply -f my-nginx.yaml
  3. 查看Pod以及Readiness Gate狀態。

    kubectl get pod -owide -l app=nginx

    預期輸出:

    NAME                       READY   STATUS    RESTARTS   AGE   IP               NODE                         NOMINATED NODE   READINESS GATES
    my-nginx-d9f95dcf9-8dhwj   1/1     Running   0          14s   172.XX.XXX.188   cn-hangzhou.172.XX.XXX.174   <none>           0/1
    my-nginx-d9f95dcf9-z9hjm   1/1     Running   0          14s   172.XX.XXX.182   cn-hangzhou.172.XX.XXX.174   <none>           0/1

    可以看到,Pod Readiness Gate狀態已被成功注入。多次執行該命令後,可以觀察到Pod的ReadinessGate狀態從0變為1,表明Pod已成功掛載到負載平衡伺服器組中。

步驟四:變換Deployment

  1. 重新部署樣本Deployment。

    kubectl rollout restart deployment my-nginx

    預期輸出:

    deployment.apps/my-nginx restarted
  2. 查看Pod以及Readiness Gate狀態。

    kubectl get pod -owide -l app=nginx

    預期輸出:

    NAME                       READY   STATUS    RESTARTS   AGE    IP               NODE                         NOMINATED NODE   READINESS GATES
    my-nginx-d9f95dcf9-8dhwj   1/1     Running   0          113s   172.XX.XXX.188   cn-hangzhou.172.XX.XXX.174   <none>           1/1
    my-nginx-df5c9cf7d-6p5jc   1/1     Running   0          6s     172.XX.XXX.182   cn-hangzhou.172.XX.XXX.174   <none>           0/1
    my-nginx-df5c9cf7d-7dh2v   1/1     Running   0          15s    172.XX.XXX.189   cn-hangzhou.172.XX.XXX.174   <none>           1/1

    多次執行該命令時,可以觀察到在變換過程中,Pod會等待就緒狀態的Readiness Gate。只有當Readiness Gate就緒,表明Pod已成功掛載到負載平衡伺服器組中,變換才會繼續進行。

手動添加Readiness Gate

步驟一:建立負載平衡服務

  1. 參見以下YAML,建立my-svc.yaml,按需建立傳統型負載平衡CLB或網路型負載平衡NLB執行個體。

    CLB

    apiVersion: v1
    kind: Service
    metadata:
      name: my-svc
      namespace: default # 命名空間為default
    spec:
      ports:
      - port: 80
        targetPort: 80
        protocol: TCP
      selector:
        app: nginx
      type: LoadBalancer

    NLB

    apiVersion: v1
    kind: Service
    metadata:
      name: my-svc
      annotations:
        service.beta.kubernetes.io/alibaba-cloud-loadbalancer-zone-maps: "${zone-A}:${vsw-A},${zone-B}:${vsw-B}" # 例如cn-hangzhou-k:vsw-i123456,cn-hangzhou-j:vsw-j654321。
    spec:
      loadBalancerClass: alibabacloud.com/nlb # 指定負載平衡類型為NLB
      ports:
      - port: 80
        targetPort: 80
        protocol: TCP
      selector:
        app: nginx
      type: LoadBalancer
  2. 建立樣本Service。

    kubectl apply -f my-svc.yaml
  3. 查看當前Service狀態。

    kubectl get service my-svc

    等待出現<IP地址/網域名稱>後,即可確認對應的Server Load Balancer執行個體已建立完成。

    NAME     TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)        AGE
    my-svc   LoadBalancer   192.XX.XX.215   <IP地址/網域名稱>     80:30493/TCP   8s

步驟二:建立樣本Deployment

  1. 參見以下Pod YAML,建立my-nginx.yaml,將Readiness Gate的conditionType設定為service.readiness.alibabacloud.com/my-svc

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-nginx    # 樣本名稱
      namespace: default # 命名空間為default
      labels:
        app: nginx
    spec:
      replicas: 2       # 設定副本數量
      selector:
        matchLabels:
          app: nginx     # 對應服務中Selector的值需要與其一致,才可以通過服務公開
      template:
        metadata:
          labels:
            app: nginx
        spec:
          readinessGates:
          - conditionType: service.readiness.alibabacloud.com/my-svc # 設定my-svc服務的Readiness Gate
          containers:
          - name: nginx
            image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
            ports:
            - containerPort: 80                                # 需要在服務中暴露該連接埠
  2. 部署樣本Deployment。

    kubectl apply -f my-nginx.yaml
  3. 查看Pod以及Readiness Gate狀態。

    kubectl get pod -owide -l app=nginx

    預期輸出:

    NAME                       READY   STATUS    RESTARTS   AGE   IP               NODE                         NOMINATED NODE   READINESS GATES
    my-nginx-d9f95dcf9-8dhwj   1/1     Running   0          14s   172.XX.XXX.188   cn-hangzhou.172.XX.XXX.174   <none>           0/1
    my-nginx-d9f95dcf9-z9hjm   1/1     Running   0          14s   172.XX.XXX.182   cn-hangzhou.172.XX.XXX.174   <none>           0/1

    多次執行該命令後,可以觀察到Pod的Readiness Gate狀態從0變為1,表明Pod已成功掛載到負載平衡伺服器組中。

步驟三:變換Deployment

  1. 重新部署樣本Deployment。

    kubectl rollout restart deployment my-nginx

    預期輸出:

    deployment.apps/my-nginx restarted
  2. 查看Pod以及Readiness Gate狀態。

    kubectl get pod -owide -l app=nginx

    預期輸出:

    NAME                       READY   STATUS    RESTARTS   AGE    IP               NODE                         NOMINATED NODE   READINESS GATES
    my-nginx-d9f95dcf9-8dhwj   1/1     Running   0          113s   172.XX.XXX.188   cn-hangzhou.172.XX.XXX.174   <none>           1/1
    my-nginx-df5c9cf7d-6p5jc   1/1     Running   0          6s     172.XX.XXX.182   cn-hangzhou.172.XX.XXX.174   <none>           0/1
    my-nginx-df5c9cf7d-7dh2v   1/1     Running   0          15s    172.XX.XXX.189   cn-hangzhou.172.XX.XXX.174   <none>           1/1

    多次執行該命令時,可以觀察到在變換過程中,Pod會等待就緒狀態的Readiness Gate。只有當Readiness Gate就緒,表明Pod已成功掛載到負載平衡伺服器組中,變換才會繼續進行。