0
点赞
收藏
分享

微信扫一扫

kkkkkk888888

止止_8fc8 2023-04-20 阅读 183

参考链接

https://cloud.tencent.com/developer/article/1683316

pod实际被删除了,但是endpointsip+端口的更新,可能订阅ep的组件比如ingress控制器维护的ingress 路由,kube-proxy维护的iptable路由规则还没有更新,,理想状态是啥,删除pod之前,集群中所有组件更新了endpoints列表对吧,但是不是这样,因为删除pod这个动作和ep的更新是并行的,这是由于ep源码机制决定的(原语分发ep),k8s不会验证订阅ep更改的组件是否有最新的集群消息,这就会导致什么问题?可能你的pod已经被干掉了,但是呀,你组件的ep还没有刷新出来,还有可能路由到旧的pod地址,你要是svc,ep地址就是就是cni ip+ trgetport,hostport就是宿主机ip+端口

那么如何保证ep在广播之后,各组件都刷新了自己的ep列表呢?

我们需要等待!!

当新pod就绪探针检查好,老pod要被被删除的时候,他会收到sigterm终止信号这是终止pod pid为1的进程用的,我们写个钩子函数可以捕捉这个信号,捕捉到让pod等待一段时间在死亡,不要立即死亡,不然我还是路由到老的pod咋办呢?高并发场景下不就是404 502吗?

那么捕捉到这个信号我干啥呢

1、请稍等片刻

2、即使有sigtem信号,我也可以处理传入的流量

3、关闭一些比如eureka、数据库连接池等长连接减少和数据底座的交互,因为此时老pod尽量不要和生产数据库交互,避免数据层出错

4、最后关闭容器进程

那么我们应该等多久?默认情况下,Kubernetes 将发送 SIGTERM 信号并等待 30 秒,然后强制终止该进程。因此,我们可以使用前 15 秒继续操作。该间隔应足以将 endpoint 删除信息传播到 kube-proxy、Ingress 控制器、CoreDNS 等,然后,到达 Pod 的流量会越来越少,直到停止。15 秒后,我们就可以安全地关闭与数据库的连接并终止该过程。所以一般情况下滚动更新没有流量丢失(注意流量丢失和业务实际中断是两码事),但是在负载高的情况下不会有异常吗,所以需要等待久些

如果我们认为需要更多时间,那么可以在 20 或 25 秒时停止该过程。这里有一点要注意,Kubernetes 将在 30 秒后强行终止该进程(除非我们更改 Pod 定义中的 terminationGracePeriodSeconds)。如果我们无法更改代码以获得更长的等待时间要怎么办?我们可以调用脚本以获得固定的等待时间,然后退出应用程序。

在调用 SIGTERM 之前,Kubernetes 会在 Pod 中公开一个 preStop hook(容器调用sigterm前执行的动作,这就是一个钩子)。我们可以将 preStop hook 设置为等待 90秒。下面是一个例子:

kkkkkk888888_pod

我们应该注意 Pod 从集群中删除后,它们的 IP 地址可能仍用于路由流量。相比立即关闭 Pod,我们不如在应用程序中等待一下或设置一个

preStop hook。在 endpoint 传播到集群中,并且 Pod 从 kube-proxy、Ingress 控制器、CoreDNS 等中删除后,Pod 才算被移除。preStop hook这个等待sleep时间就是给其他组件需要更新ep留的时间,弥补

ep原语机制的不足

这就是优雅停机,但是优雅停机只是保证我流量不中断,但是能保证业务不中断吗,并不能,举个例子,你发版本更新了,你设置了preStop hook钩子最简单的就是休眠90s比如,给各个比如kube-proxy或者ingress controller等有足够的时间更新ep列表刷新路由,虽然刷新的时间很短暂,但是如果你的新业务接入liquebase进行数据库脚本,数据库表字段更新,老pod访问是有异常的,如果老pod访问没有异常,这就是取决于你钩子函数的水平了,比如可以关闭一些数据库长连接,关闭一些别的东西,但是界面还是没问题的,所以优雅停机只是保证流量层面的不中断,并不是业务层面的不中断理解了不,业务层面不中断取决于你钩子函数的水平!!


kubelet创建容器的过程,kubelet不会自己创建容器,他会找k8s底层的三个接口

CRI接口:k8s底层定义的一个接口基于rpc协议,创建容器的组件,后端可以调起是docker,可以是rkt等等容器技术实现,各种容器的实现技术,执行的类似于docker run

我看下k8s中改接口方法

kkkkkk888888_pod_02


kkkkkk888888_pod_03


kkkkkk888888_pod_04

CNI接口:k8s底层定义的一个接口,将容器进行网络地址分配,底层方法只要四个添加网络、删除网络、添加网络列表、删除网络列表。

kkkkkk888888_pod_05

CSI接口:容器中装载卷的接口,不管是storagecalss都是基于这些实现的,volumons等


举报
0 条评论