站点图标 Linux-技术共享

更新应用时,如何实现 K8s 零中断滚动更新?

传统 NodePort 场景

K8S 服务对外暴露传统方案是 LB 绑定 Service 的 NodePort 流量从 LB 打到 NodePort 之后再由 kube-proxy 生成的 ipvs 或 iptables 规则进行转发:

这样当滚动更新时,LB 绑定的 NodePort 一般无需变动,也就不需要担心 LB 解绑导致对业务有损。

LB 直通 Pod 场景

现在很多云厂商也都支持了 LB 直通 Pod,即 LB 直接将流量转发给 Pod,不需要再经过集群内做一次转发:

当滚动更新时,LB 就需要解绑旧 Pod,绑定新 Pod,如果 LB 到旧 Pod 上的存量连接的存量请求还没处理完,直接解绑的话就可能造成请求异常;我们期望的是,等待存量请求处理完,LB 才真正解绑旧 Pod。

解决方案

TKE

腾讯云 TKE 官方针对四层 Service 和七层 Ingress 都提供了解决方案。

如果是四层 Service,在 Service 上加上这样的注解即可(前提是 Service 用了 CLB 直通 Pod 模式):

 
service.cloud.tencent.com/enable-grace-shutdown: "true"

参考官方文档 Service 优雅停机

如果是七层 CLB 类型 Ingress,在 Ingress 上加上这样的注解即可(前提是 Service 用了 CLB 直通 Pod 模式):

 
ingress.cloud.tencent.com/enable-grace-shutdown: "true"

参考官方文档 Ingress 优雅停机

ACK

阿里云 ACK 目前只针对四层 Service 提供了解决方案,通过注解开启优雅中断与设置中断超时时间:

 
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-connection-drain: "on"
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-connection-drain-timeout: "900"
退出移动版