海外大秀直播网址

咫尺部署在 Kubernetes 中的作事,通过 Calico BGP 将 Service 与集群外齐集买通,并在外部的 nginx 中建树 Service 地址对外进行作事披露。经过一段期间的不雅察,发咫尺 Deployment 周折更新中及之后一段期间,偶现作事考查 502 的问题。

[[418415]]

问题配景和样式

现时 Kuberntes 集群使用 Calico 看成 CNI 组件,并使用 BGP 模式将 Pod IP 和 Service IP 与集群外齐集买通,通过集群外的 Nginx 作反向代理对外提供作事,讹诈齐是以 Deployment 体式部署。通过一段期间的不雅察,部分讹诈响应,在讹诈发布后一段期间内,作事有一定几率出现 502 报错。

问题排查

最径直的猜度,是否问题只发生在周折更新流程中,即讹诈莫得作念好查验检测的建树,导致作事莫得确凿可用,Pod 却照旧处于 ready 现象。

浮浅的测试后很快摒除这个可能,对建树了有用健康查验探针的 Deployment 进行周折更新,并使用 ab 通过 Nginx 建树的域名进行无间恳求(此时无并发),发咫尺讹诈周折更新竣事后,并通过 pod IP 东说念主工阐明了作事莫得问题,仍有概率出现 502 谬误,且出现谬误的样式会无间几分钟致使十几分钟的期间,彰着远远跨越了周折更新所需期间。

上头的初步测试的样式,摒除了讹诈本人的问题。下一个怀疑的贪图指向了 Nginx。既然样式是通过 Nginx 代理考查产生的,那么径直恳求 Service 有莫得问题呢,由于现时集群 Service 地址和外部齐集作念了买通,测试起来很便捷,我准备了如下的测试:

ab 无间恳求域名通过 Nginx 考查作事,并触发周折更新(ab -r -v 2 -n 50000 http://service.domain.com/test) ab 无间恳求 serviceIP:port 考查作事,并触发周折更新(ab -r -v 2 -n 50000 http://10.255.10.101/test)

经过测试,案例 1 出现了 502 谬误,案例 2 未出现。是以,问题是在 Nginx 嘛?

找到负责 Nginx 的共事进行分析,论断是 Nginx 似乎不会形成类似的问题。那为什么上头测试中唯有案例1 复现了问题呢?于是我决定重新进行测试,此次在 ab 恳求的时候加上了并发(-c 10),遵循,两个案例齐出现了 502 的谬误。这么,问题似乎又回到了 Kubernetes 集群本人,而且似乎在恳求量较大的情况下才会出现。

这时,我初始怀疑是否可能是因为某种原因,周折发布后的一段期间里,一些恳求会谬误的被分发到照旧被杀掉的老得 podIP 上。为了考据这一猜度,我进行了如下实验:

创建一个测试的 Deployment,副本数为 1,提供浮浅的 http 作事,并在招揽到恳求时输出日记,并创建对应 Service。 使用 ab 并发恳求该作事 Service 地址。 使用 kubectl patch 修改 Pod 的 label,使其和 Deployment 不一致,触发 Deployment 自动拉起一个新的 Pod。 跟踪新的 Pod 和老的 Pod 的日记,不雅察恳求进来的情况。

第三步 patch pod 的 label,是为了保留正本的 pod 实例,以便不雅察恳求是否会分发到老的 Pod。(patch Pod 的 label 不会使 Pod 重启或退出,可是改变了 label,会使 Pod 脱离原 Deployment 的禁止,因此触发 Deployment 新建一个 Pod)。

遵循和预期一致,当新的 Pod 照旧 ready,Endpoint 照旧出现了新的 Pod 的 IP,恳求仍然会进到正本的 Pod 中。

基于以上的遵循,又通过屡次实验,不雅察 Kubernetes 节点上的 IPVS 法律讲明注解,发咫尺周折更新及之后一段期间,老的 podIP 还会出咫尺 IPVS 法律讲明注解中,不外 weight 为 0,手动删除后 weight 为 0 的 rs 后,问题就不再出现。到此,找到问题方位是 IPVS,可是为什么会这么呢,在搜索了干系的著述后,大约找到了原因。

诡异的 No route to host,讲到了 IPVS 的一个脾气:

也即是 IPVS 模块处理报文的主要进口,发现它会先在腹地联贯转发表看这个包是否照旧有对应的联贯了(匹配五元组),要是有就讲明它不是新联贯也就不会改造,径直发给这个联贯对应的之前照旧改造过的 rs(也不会判断权重);要是没匹配到讲明这个包是新的联贯,就会走到改造这里 (rr,wrr 等改造计谋)。

即:五元组(源IP地址、想法IP地址、条约号、源端口、想法端口)一致的情况下,IPVS 有可能不经过权重判断,径直将新的联贯当成存量联贯,柬埔寨修车群转发到正本的 real server(即 PodIP)上。表面上这种情况在单一客户端大量恳求的场景下,才有可能触发,这亦然诡异的 No route to host一文中模拟出的场景,即:

不同恳求的源 IP 长久是磋议的,关节点在于源端口是否可能磋议。由于 ServiceA 向 ServiceB 发起大量短联贯,ServiceA 方位节点就会有大量 TIME_WAIT 现象的联贯,需要等 2 分钟(2*MSL)才会算帐,而由于联贯量太大,每次发起的联贯齐会占用一个源端口,当源端口不够用了,就会重用 TIME_WAIT 现象联贯的源端口,这个时候当报文参加 IPVS 模块,检测到它的五元组跟腹地联贯转发表中的某个联贯一致(TIME_WAIT 现象),就觉得它是一个存量联贯,然后径直将报文转发给这个联贯之前对应的 rs 上,关联词这个 rs 对应的 Pod 早已毁灭,是以捏包看到的样式是将 SYN 发给了旧 Pod,况兼无法收到 ACK,伴跟着复返 ICMP 奉告这个 IP 不成达,也被讹诈讲明注解为 “No route to host”。

原因分析

这里分析一下之前的测试中为何会出现两种不同的遵循。我一共进行了两次对比实验。

第一次,未加并发,通过 Nginx 和 通过 Service IP 进行考查并对比。这组实验中,通过 Nginx 考查复现了问题,而通过 Service IP 莫得,这个遵循也几乎将排查引入邪途。而咫尺分析一下,原因是因为咫尺的 Kubernetes 作事考查进口的设想,是集群外 Nginx 为扫数这个词 Kubernetes 集群共用,是以 Nginx 的考查量很高,这也导致 Nginx 向后端的 upstream(即 Service IP)发起联贯时,表面上源端口重用的概率较高(事实上经过捏包不雅察,如实几分钟内就会不雅察到屡次端口重用的样式),因而更容易出现五元组访佛的情况。

第二次,相似的对比,此次加了并发,双方的案例齐复现了问题。这么,和上头著述中的场景类似,由于加了并发,发布 ab 恳求的机器,也出现了源端口不及而重用的情况,因此也复现了问题。

而崇拜环境出现的问题响应,和我第一次实验通过 Nginx 考查得到复现,是团结个原因,固然单个讹诈的恳求量远莫得达到能够触发五元组访佛的量级,可是集群中的扫数讹诈恳求量加起来,就会触发此问题。

处置有狡计

几种处置有狡计,上头援用的著述中也齐提到,另外可参考isuue 81775,对这一问题及干系的处置方法有许多的谋划。

鉴于咫尺咱们的技艺智力和集群限制,暂时无法也无需进行 linux 内核级别的功能修改和考据,况兼调研了业务讹诈,绝大部分以短联贯为主,咱们遴选了一种浮浅径直的方法,在一定程度上幸免该问题。开拓一个自界说的进度,并以 Daemonset 的方法部署在每个 Kubernetes 的每个节点上。该进度通过 informer 机制监听集群 Endpoint 的变化,一朝监听到事件,便取得 Endpoint 尽头对应 Service 的信息,并由此找到其在本节点上对应产生的 IPVS 法律讲明注解,要是发咫尺 Virtual Service 下有 weight 为 0 的 Real Service,则立即删除此 Real Service。可是这一处置方法,不成幸免的糟跶了部分优雅退出的脾气。可是在抽象了业务讹诈的特质量度之后,这如实是咫尺可继承的一种处置方法(固然极其不优雅)。

念念考

是否应该如斯使用 Service?

转头问题的原因,在咱们单一业务的恳求量远未达到会触发五元组访佛这种小概率事件的瓶颈时,过早的遭受这一问题,和咱们对 Kubernetes 作事的进口网关的设想有很大关系,买通 Service 和捏造机的齐集,使用外部 Nginx 看成进口网关,这种用法,在 Kubernetes 的现实中应该算历害常特等(致使可称为仙葩),可是这一设想,亦然由于咫尺业务的实例,存在大量捏造机和容器混布的场景。训戒是,在实行和开拓 Kubernetes 这种复杂系统时,尽量紧靠社区及大厂公开的分娩最好现实,减少仅凭阅历的或机械延用的方法进行架构设想,不然很容易踩坑,事倍功半。

 海外大秀直播网址






Powered by 柬埔寨修车群 @2013-2022 RSS地图 HTML地图

Copyright Powered by365建站 © 2013-2025