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 markedReadyand receives traffic only after these conditions are met. -
Example procedure
-
How it works
With
readinessGatesconfigured, a Pod becomes ready as follows:-
Container probe readiness: The kubelet runs the container
readinessProbe. After the probe succeeds,ContainersReadybecomesTrue, but the Pod stays not ready until all readiness gate conditions are confirmed. -
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-svctoTrue. -
Pod becomes fully ready: After all readiness gate conditions are
True, the kubelet setsReadytoTrue. The rolling update can then safely terminate the old Pod.
-
-
Usage notes
-
The Service must exist: The Service name in
readinessGatesmust 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 reachesReady, stalling the deployment. -
Multiple Services are supported: A Pod can list multiple
readinessGates.conditionTypeentries for multipleLoadBalancerServices. 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
-
Add the
k8s.alibabacloud.com/pod-readiness-gate-inject: enabledlabel to thedefaultnamespace.kubectl label namespace default k8s.alibabacloud.com/pod-readiness-gate-inject=enabledExpected output:
namespace/default labeled -
Verify the label on the namespace.
kubectl get namespace default -oyamlExpected 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: ActiveThe label is added to the namespace.
Create a LoadBalancer Service
-
Create
my-svc.yamlfrom 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: LoadBalancerNLB
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 -
Apply the Service.
kubectl apply -f my-svc.yaml -
Check Service status.
kubectl get service my-svcWait until EXTERNAL-IP shows an IP address or domain name, indicating the
load balancerinstance 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
-
Create
my-nginx.yamlfrom 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. -
Apply the Deployment.
kubectl apply -f my-nginx.yaml -
Check Pod status and readiness gates.
kubectl get pod -owide -l app=nginxExpected 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/1Repeated 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
-
Restart the Deployment.
kubectl rollout restart deployment my-nginxExpected output:
deployment.apps/my-nginx restarted -
Check Pod status and readiness gates.
kubectl get pod -owide -l app=nginxExpected 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/1During 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
-
Create
my-svc.yamlfrom 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: LoadBalancerNLB
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 -
Apply the Service.
kubectl apply -f my-svc.yaml -
Check Service status.
kubectl get service my-svcWait until EXTERNAL-IP shows an IP address or domain name, indicating the
load balancerinstance 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
-
Create
my-nginx.yaml. In the Pod template, set the readiness gateconditionTypetoservice.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. -
Apply the Deployment.
kubectl apply -f my-nginx.yaml -
Check Pod status and readiness gates.
kubectl get pod -owide -l app=nginxExpected 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/1Repeated 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
-
Restart the Deployment.
kubectl rollout restart deployment my-nginxExpected output:
deployment.apps/my-nginx restarted -
Check Pod status and readiness gates.
kubectl get pod -owide -l app=nginxExpected 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/1During 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.