在使用LoadBalancer类型的Service暴露后端Pod时,当Pod进行滚动更新,可能会由于Pod更新速度快于负载均衡器后端服务器组的挂载速度而导致访问中断。您可以通过配置Readiness Gate来确保Pod的平滑更新。本文将介绍如何使用Pod Readiness Gate机制实现Pod平滑更新。
前提条件
已创建ACK托管集群或ACK Serverless集群,且符合以下要求。具体操作请参见创建ACK托管集群、创建ACK Serverless集群。
若集群类型为ACK托管集群,网络插件需为Terway。
集群版本为1.24及以上,请参见升级集群。
cloud-controller-manager组件为v2.10.0或更高版本,请参见Cloud Controller Manager。
已通过kubectl工具连接集群。具体操作,请参见获取集群KubeConfig并通过kubectl工具连接集群。
使用说明
当您的Service通过LoadBalancer方式暴露后端Pod时,Pod进行滚动更新可能会导致服务短暂中断。
问题原因
在Pod进行滚动更新时,新Pod的启动速度可能快于LoadBalancer Service对后端Pod更新的速度。这可能导致请求流量仍然被导向正在逐步退出的Pod,从而造成短暂的访问失败。
解决方案
您可以在Pod的YAML配置中使用Pod Readiness Gate机制,通过自定义条件控制Pod的就绪状态。Readiness Gate允许您设置自定义条件(例如与LoadBalancer Service相关的
service.readiness.alibabacloud.com/<Service Name>
),当这些条件满足时,Pod才会被标记为Ready,从而能够接收流量。如果一个Pod挂载了多个负载均衡,您可以为其配置多个Readiness Gate。操作示例步骤
步骤一:创建负载均衡服务
参见以下示例YAML内容,创建名为
my-svc.yaml
文件,按需创建传统型负载均衡CLB或网络型负载均衡NLB实例。CLB
apiVersion: v1 kind: Service metadata: name: my-svc 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
执行以下命令,创建示例Service。
kubectl apply -f my-svc.yaml
执行以下命令,查看当前Service状态。
kubectl get service my-svc
等待出现
<IP地址域名>
后,即可确认对应的负载均衡实例已创建完成。NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-svc LoadBalancer 192.XX.XX.215 <IP地址域名> 80:30493/TCP 8s
步骤二:创建示例Deployment
使用以下示例Pod的YAML内容,创建一个名为
my-nginx.yaml
的文件,且Readiness Gate的conditionType
设置为service.readiness.alibabacloud.com/my-svc
。apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx # 示例名称。 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 # 需要在服务中暴露该端口。
执行以下命令,部署示例Deployment。
kubectl apply -f my-nginx.yaml
执行以下命令,查看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
执行以下命令,重新部署示例Deployment。
kubectl rollout restart deployment my-nginx
预期输出:
deployment.apps/my-nginx restarted
执行以下命令,查看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已成功挂载到负载均衡服务器组中,滚动更新才会继续进行。