

咫尺部署在 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 这种复杂系统时,尽量紧靠社区及大厂公开的分娩最好现实,减少仅凭经历的或机械延用的样式进行架构假想,不然很容易踩坑,事倍功半。
迷水商城
下一篇:读书名言名句520句