All Products
Search
Document Center

Container Service for Kubernetes:Ensure smooth Pod updates with a readiness gate

Last Updated:Jun 24, 2026

When you expose backend pods through a LoadBalancer Service, rolling updates can interrupt access if pods become ready before the load balancer adds them to the backend server group. Configure a readiness gate to ensure smooth pod updates. This topic explains how to use the Pod Readiness Gate mechanism for smooth updates.

Prerequisites

  • An ACK managed cluster or ACK Serverless cluster meets the following requirements. See Create an ACK managed cluster and Create an ACK Serverless cluster.

    • For ACK managed clusters, the network plug-in must be Terway.

    • Cluster version is 1.24 or later. See Upgrade a cluster.

    • cloud-controller-manager is v2.10.0 or later. See Cloud Controller Manager.

    • For automatic readiness gate injection: cloud-controller-manager v2.12.4 or later with Pod ReadinessGate Webhook enabled. In Cloud Controller Manager Parameter Configuration, select Enable Pod ReadinessGate Webhook capability, then click Confirm.

  • A kubectl client is connected to the ACK cluster. For more information, see Connect to an ACK cluster using kubectl.

Background

Exposing an application with a LoadBalancer Service and performing a rolling update can cause brief service interruptions or connection failures.

  • Cause

    New Pods often become ready before the load balancer adds their IP to the backend server list. The rolling update may then terminate the old Pod while traffic still routes to it, causing connection failures.

  • Solution

    Use Pod Readiness Gate in the Pod YAML to add custom readiness conditions, such as service.readiness.alibabacloud.com/<Service Name> for a LoadBalancer Service. The Pod is marked Ready and receives traffic only after these conditions are met.

  • Example procedure

    image
  • How it works

    With readinessGates configured, a Pod becomes ready as follows:

    1. Container probe readiness: The kubelet runs the container readinessProbe. After the probe succeeds, ContainersReady becomes True, but the Pod stays not ready until all readiness gate conditions are confirmed.

    2. CCM registers the backend: CCM detects container readiness, adds the Pod IP to the load balancer backend server group, then sets a condition such as service.readiness.alibabacloud.com/my-svc to True.

    3. Pod becomes fully ready: After all readiness gate conditions are True, the kubelet sets Ready to True. The rolling update can then safely terminate the old Pod.

  • Usage notes

    • The Service must exist: The Service name in readinessGates must be correct and the Service must exist in the cluster. If the name is wrong or the Service is deleted during Pod startup, CCM cannot register the backend and the Pod never reaches Ready, stalling the deployment.

    • Multiple Services are supported: A Pod can list multiple readinessGates.conditionType entries for multiple LoadBalancer Services. The Pod becomes ready only after registering with all specified Service backends.

Procedure

Automatic

After you enable Pod ReadinessGate Webhook, add the label k8s.alibabacloud.com/pod-readiness-gate-inject: enabled to a namespace to inject readiness gates into all Pods.

The following steps enable automatic injection for the default namespace.

Add the automatic injection label

  1. Add the k8s.alibabacloud.com/pod-readiness-gate-inject: enabled label to the default namespace.

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

    Expected output:

    namespace/default labeled
  2. Verify the label on the namespace.

    kubectl get namespace default -oyaml

    Expected output:

    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

    The label is added to the namespace.

Create a LoadBalancer Service

  1. Create my-svc.yaml from the following YAML template. Create a Classic Load Balancer (CLB) or Network Load Balancer (NLB) instance as needed.

    CLB

    apiVersion: v1
    kind: Service
    metadata:
      name: my-svc
      namespace: default # The namespace is 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}" # Example: cn-hangzhou-k:vsw-i123456,cn-hangzhou-j:vsw-j654321.
    spec:
      loadBalancerClass: alibabacloud.com/nlb # Specifies that the load balancer type is NLB.
      ports:
      - port: 80
        targetPort: 80
        protocol: TCP
      selector:
        app: nginx
      type: LoadBalancer
  2. Apply the Service.

    kubectl apply -f my-svc.yaml
  3. Check Service status.

    kubectl get service my-svc

    Wait until EXTERNAL-IP shows an IP address or domain name, indicating the load balancer instance is created.

    NAME     TYPE           CLUSTER-IP       EXTERNAL-IP                 PORT(S)        AGE
    my-svc   LoadBalancer   192.XX.XX.215    <IP address/domain name>     80:30493/TCP   8s

Create an example Deployment

  1. Create my-nginx.yaml from the following YAML template.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-nginx    # Example name.
      namespace: default # The namespace is default.
      labels:
        app: nginx
    spec:
      replicas: 2       # Specifies the number of replicas.
      selector:
        matchLabels:
          app: nginx     # Must match the Service selector to be exposed by the Service.
      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                                # This port must be exposed in the Service.
  2. Apply the Deployment.

    kubectl apply -f my-nginx.yaml
  3. Check Pod status and readiness gates.

    kubectl get pod -owide -l app=nginx

    Expected output:

    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

    Repeated runs show READINESS GATES change from 0/1 to 1/1, indicating successful registration with the load balancer backend server group.

Perform a rolling update

  1. Restart the Deployment.

    kubectl rollout restart deployment my-nginx

    Expected output:

    deployment.apps/my-nginx restarted
  2. Check Pod status and readiness gates.

    kubectl get pod -owide -l app=nginx

    Expected output:

    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

    During the rolling update, Pods wait for the readiness gate before the update proceeds, ensuring new Pods register with the load balancer backend server group first.

Manual

Create a LoadBalancer Service

  1. Create my-svc.yaml from the following YAML template. Create a Classic Load Balancer (CLB) or Network Load Balancer (NLB) instance as needed.

    CLB

    apiVersion: v1
    kind: Service
    metadata:
      name: my-svc
      namespace: default # The namespace is 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}" # Example: cn-hangzhou-k:vsw-i123456,cn-hangzhou-j:vsw-j654321.
    spec:
      loadBalancerClass: alibabacloud.com/nlb # Specifies that the load balancer type is NLB.
      ports:
      - port: 80
        targetPort: 80
        protocol: TCP
      selector:
        app: nginx
      type: LoadBalancer
  2. Apply the Service.

    kubectl apply -f my-svc.yaml
  3. Check Service status.

    kubectl get service my-svc

    Wait until EXTERNAL-IP shows an IP address or domain name, indicating the load balancer instance is created.

    NAME     TYPE           CLUSTER-IP       EXTERNAL-IP                 PORT(S)        AGE
    my-svc   LoadBalancer   192.XX.XX.215    <IP address/domain name>     80:30493/TCP   8s

Create an example Deployment

  1. Create my-nginx.yaml. In the Pod template, set the readiness gate conditionType to service.readiness.alibabacloud.com/my-svc.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-nginx    # Example name.
      namespace: default # The namespace is default.
      labels:
        app: nginx
    spec:
      replicas: 2       # Specifies the number of replicas.
      selector:
        matchLabels:
          app: nginx     # Must match the Service selector to be exposed by the Service.
      template:
        metadata:
          labels:
            app: nginx
        spec:
          readinessGates:
          - conditionType: service.readiness.alibabacloud.com/my-svc # Set the readiness gate for the my-svc Service.
          containers:
          - name: nginx
            image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
            ports:
            - containerPort: 80                                # This port must be exposed in the Service.
  2. Apply the Deployment.

    kubectl apply -f my-nginx.yaml
  3. Check Pod status and readiness gates.

    kubectl get pod -owide -l app=nginx

    Expected output:

    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

    Repeated runs show READINESS GATES change from 0/1 to 1/1, indicating successful registration with the load balancer backend server group.

Perform a rolling update

  1. Restart the Deployment.

    kubectl rollout restart deployment my-nginx

    Expected output:

    deployment.apps/my-nginx restarted
  2. Check Pod status and readiness gates.

    kubectl get pod -owide -l app=nginx

    Expected output:

    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

    During the rolling update, Pods wait for the readiness gate before the update proceeds, ensuring new Pods register with the load balancer backend server group first.