网站服务器空间大小,asp.net 网站管理系统,网页制作开版费,wordpress怎么编辑代码TCP 3 次握手
在最简单的形式中#xff0c;TCP 三次握手很容易理解#xff0c;并且有 大量在线材料都在讨论这个问题。#xff08;如果你能读懂 Chinease#xff0c;你可以看看我之前的一篇文章。
然而#xff0c;在实际中理解、练习和解决 TCP 问题 世界是另一回事。随… TCP 3 次握手
在最简单的形式中TCP 三次握手很容易理解并且有 大量在线材料都在讨论这个问题。如果你能读懂 Chinease你可以看看我之前的一篇文章。
然而在实际中理解、练习和解决 TCP 问题 世界是另一回事。随着容器平台开始主宰世界随着 以及 service-mesh 成为底层的下一个重大转变 网络基础设施这些平台中的现代网络功能使 TCP 相关问题更加复杂。在传统观点中这些问题 可能看起来相当奇怪。
本文将介绍其中两种情况。你看到时有什么想法 下面两张图片 方案 1 的 TCP 流有问题 方案 2 的有问题的 TCP 流
1. 场景 1
1.1 现象SYN - SYNACK - RST
客户端发起了与服务器的连接服务器立即确认 SYNACK但客户端在收到此数据包时重置了它并继续等待 用于来自服务器的下一个 SYNACK。经过多次 retransmit 和 reset 连接终于超时了。
1.2 捕获
tcpdump 输出 span stylecolor:#333333span stylebackground-color:#f8f8f8span stylebackground-color:#f6f8facode1 18:56:40.353352 IP 10.4.26.45.35582 span stylecolor:#000000strong/strong/span 10.4.26.234.80: Flags span stylecolor:#000000strong[/strong/spanS], span stylecolor:#0086b3seq /span853654705, win 29200, length 0
2 18:56:40.353506 IP 10.4.26.11.80 span stylecolor:#000000strong/strong/span 10.4.26.45.35582: Flags span stylecolor:#000000strong[/strong/spanS.], span stylecolor:#0086b3seq /span914414059, ack 853654706, win 28960, length 0
3 18:56:40.353521 IP 10.4.26.45.35582 span stylecolor:#000000strong/strong/span 10.4.26.11.80: Flags span stylecolor:#000000strong[/strong/spanR], span stylecolor:#0086b3seq /span853654706, win 0, length 0
4 18:56:41.395322 IP 10.4.26.45.35582 span stylecolor:#000000strong/strong/span 10.4.26.234.80: Flags span stylecolor:#000000strong[/strong/spanS], span stylecolor:#0086b3seq /span853654705, win 29200, length 0
5 18:56:41.395441 IP 10.4.26.11.80 span stylecolor:#000000strong/strong/span 10.4.26.45.35582: Flags span stylecolor:#000000strong[/strong/spanS.], span stylecolor:#0086b3seq /span930694343, ack 853654706, win 28960, length 0
6 18:56:41.395457 IP 10.4.26.45.35582 span stylecolor:#000000strong/strong/span 10.4.26.11.80: Flags span stylecolor:#000000strong[/strong/spanR], span stylecolor:#0086b3seq /span853654706, win 0, length 0
/code/span/span/span 哪里
客户10.4.26.45服务器在端口提供 HTTP 服务10.4.26.23480
怎么了在继续之前请考虑一下这一点。
1.3 分析
让我们试着深入了解发生了什么
#1客户端启动了与服务器的连接使用src_port35582,dst_port80#2服务器已确认 SYNACK#3客户端重置服务器的 SYNACK 数据包#4超时客户端重传#1#5服务器已确认仍为 SYNACK#4#6客户端再次被拒绝 SYNACK#5
此 TCP 流的时间序列在此处重新描述 图 1.1 有问题的 TCP 流
乍一看这似乎很奇怪因为服务器确认了客户端的请求 而 Client 端在收到后立即重置此数据包然后一直等待 Next 来自服务器的 SYNACK而不是关闭此连接尝试。它 甚至在超时时重新传输第一个 SYN 数据包注意到它使用与 do 相同的临时端口。#4#1
1.4 根本原因
注意这一点客户端假设服务器在 为什么 SYNACK 数据包 和 来自 通过一些调查 我们发现该服务器部署为 K8S ExternalIP Service作为 VIPExternalIP和 PodIP。10.4.26.234#2#410.4.26.1110.4.26.1110.4.26.234
1.4.1 简短的回答
客户端连接到服务器目标 IP 为 server但 server 实例回复了其真实 IP PodIP。IP 不匹配使客户相信 SYNACK 数据包无效因此拒绝了它们。
1.4.2 长答案
首先我们位于 Cilium 驱动的 K8S 集群中。 Cilium 将生成 BPF 规则以将流量负载均衡到此 VIP 添加到其所有后端 Pod 中。正常流量路径如图 1.1 所示 图 1.2 客户端和服务器实例之间的正常数据流
Client客户端向服务器发送流量VIPClientHostCilium 做 DNAT把 VIP 改成它的 backend 实例 IPPodIPServerHost路由到 IP 为PodIPServer服务器实例回复为自己的PodIPServerHost将回复数据包路由到客户端主机ClientHostCilium 进行 SNAT将服务器的 schange 为 然后转发 到客户端实例的流量PodIPVIPClient客户端接收流量。从它自己的角度来看 received packet 只是前一个发送的 packet 两者都是 因此它接受该数据包。3 次握手完成。src_ipdst_ipVIP
当客户端和服务器位于同一主机上时会出现此问题其中 的情况下步骤 6 不是由 Cilium 实现的如图 1.2 所示 图 1.3 客户端和服务器位于同一主机上时的数据流
我们已经报告了这个问题并确认了一个错误请参阅此 问题了解更多详情。
2. 场景 2
2.1 现象握手正常传输数据时连接重置
客户端成功启动了与服务器的 TCP 连接3 个数据包但是在 发送第一个数据包总共第 4 个数据包连接得到 由 Server 立即重置。
2.2 捕获 span stylecolor:#333333span stylebackground-color:#f8f8f8span stylebackground-color:#f6f8facode1 12:10:30.083284 IP 10.6.2.2.51136 span stylecolor:#000000strong/strong/span 10.7.3.3.8080: Flags span stylecolor:#000000strong[/strong/spanS], span stylecolor:#0086b3seq /span1658620893, win 29200, length 0
2 12:10:30.083513 IP 10.6.3.3.8080 span stylecolor:#000000strong/strong/span 10.7.2.2.51136: Flags span stylecolor:#000000strong[/strong/spanS.], span stylecolor:#0086b3seq /span2918345428, ack 1658620894, win 28960, length 0
3 12:10:30.083612 IP 10.6.2.2.51136 span stylecolor:#000000strong/strong/span 10.7.3.3.8080: Flags span stylecolor:#000000strong[/strong/span.], ack 1, win 229, length 0
4 12:10:30.083899 IP 10.6.2.2.51136 span stylecolor:#000000strong/strong/span 10.7.3.3.8080: Flags span stylecolor:#000000strong[/strong/spanP.], span stylecolor:#0086b3seq /span1:107, ack 1, win 229, length 106
5 12:10:30.084038 IP 10.6.3.3.8080 span stylecolor:#000000strong/strong/span 10.7.2.2.51136: Flags span stylecolor:#000000strong[/strong/span.], ack 107, win 227, length 0
6 12:10:30.084251 IP 10.6.3.3.8080 span stylecolor:#000000strong/strong/span 10.7.2.2.51136: Flags span stylecolor:#000000strong[/strong/spanR.], span stylecolor:#0086b3seq /span1, ack 107, win 227, length 0
/code/span/span/span 同样在继续之前考虑这一点是值得的。
2.3 分析
#1客户端启动了与服务器的连接src_port51136,dst_port8080#2服务器已确认 SYNACK#3 客户端已确认服务器TCP 连接成功建立#4客户端发送了一个字节数据包106#5 服务器已确认#4#6服务器在之后立即重置此连接#5
此 TCP 流的时间序列在此处重新描述 图 2.1 有问题的 TCP 流的时间序列
2.4 根本原因
客户端看到一个如图 2.1 所示的拓扑 图 2.2 两侧的客户端视图
它发起了一个连接该连接被服务器成功接受即 3 次握手完成没有任何错误。但是在传输数据时 服务器立即拒绝了此连接。因此问题必须存在于 服务器端。
深入研究服务器端我们发现一个 sidecar具体来说是 envoy 已注入到服务器端容器。如果你不熟悉这个 word请参考 Istio 的一些介绍性文档。 简而言之sidecar 充当服务器容器和 外面的世界
在 Ingress 方向上它会拦截到 Server 的所有 Ingress 流量做一些 处理然后将允许的流量转发到 Server在 egress 方向上它会拦截来自服务器的所有 egress 流量再次执行 some 处理并将允许的流量转发到外部世界。 流量拦截是通过 Istio 中的 iptables 规则实现的。 详细实现的解释在本文的范围之外 但如果您有兴趣可以参考附录 A 中的图表。 这就是魔力所在客户端和 server 直接访问但拆分为 2 个单独的连接
客户端和 sidecar 之间的连接Sidecar 和 Server 之间的连接
这两个连接是独立的握手因此即使后者 失败前者仍然可以成功。 图 2.3 双方的实际视图一个中间人坐在客户端和服务器之间
这就是确切发生的情况由于某些内部原因服务器无法启动 错误但 Client 和 sidecar 之间的连接已建立。什么时候 客户端开始发送数据包sidecar 先 ack 接收然后 将此转发到失败的服务器但被拒绝。然后它意识到 后端服务不可用因此关闭 RST 了 自身和 Client 端。 图 2.4 sidecar 和服务器之间的连接未建立
3. 结束语
在现代底层网络基础设施越来越强大 且灵活但代价是堆栈深度更深并且构成更多 开发人员和维护人员的故障排除挑战。这不可避免 需要更深入地了解网络基础设施、虚拟化 技术、内核堆栈等。
4. 附录 AIstio Sidecar 拦截 图 4.1 使用 iptables 规则的 Istio sidecar 拦截入站
对应的 iptables 规则 span stylecolor:#333333span stylebackground-color:#f8f8f8span stylebackground-color:#f6f8facodespan stylecolor:#999988em# get the Pod netns/em/span
span stylecolor:#008080$ /spandocker inspect Container ID or Name | span stylecolor:#0086b3grep/span span stylecolor:#dd1144\/spanPidspan stylecolor:#dd1144\/spanspan stylecolor:#dd1144Pid/span: 82881,span stylecolor:#999988em# show iptables rules in Pod netns/em/span
span stylecolor:#008080$ /spannsenter span stylecolor:#000080-t/span 82881 span stylecolor:#000080-n/span iptables span stylecolor:#000080-t/span nat span stylecolor:#000080-nvL/span
Chain PREROUTING span stylecolor:#000000strong(/strong/spanpolicy ACCEPT 1725 packets, 104K bytesspan stylecolor:#000000strong)/strong/spanpkts bytes target prot opt span stylecolor:#000000strongin /strong/spanout span stylecolor:#0086b3source /spandestination2086 125K ISTIO_INBOUND tcp span stylecolor:#000080--/span span stylecolor:#000000strong*/strong/span span stylecolor:#000000strong*/strong/span 0.0.0.0/0 0.0.0.0/0Chain INPUT span stylecolor:#000000strong(/strong/spanpolicy ACCEPT 2087 packets, 125K bytesspan stylecolor:#000000strong)/strong/spanpkts bytes target prot opt span stylecolor:#000000strongin /strong/spanout span stylecolor:#0086b3source /spandestinationChain OUTPUT span stylecolor:#000000strong(/strong/spanpolicy ACCEPT 465 packets, 29339 bytesspan stylecolor:#000000strong)/strong/spanpkts bytes target prot opt span stylecolor:#000000strongin /strong/spanout span stylecolor:#0086b3source /spandestination464 27840 ISTIO_OUTPUT tcp span stylecolor:#000080--/span span stylecolor:#000000strong*/strong/span span stylecolor:#000000strong*/strong/span 0.0.0.0/0 0.0.0.0/0Chain POSTROUTING span stylecolor:#000000strong(/strong/spanpolicy ACCEPT 498 packets, 31319 bytesspan stylecolor:#000000strong)/strong/spanpkts bytes target prot opt span stylecolor:#000000strongin /strong/spanout span stylecolor:#0086b3source /spandestinationChain ISTIO_INBOUND span stylecolor:#000000strong(/strong/span1 referencesspan stylecolor:#000000strong)/strong/spanpkts bytes target prot opt span stylecolor:#000000strongin /strong/spanout span stylecolor:#0086b3source /spandestination362 21720 ISTIO_IN_REDIRECT tcp span stylecolor:#000080--/span span stylecolor:#000000strong*/strong/span span stylecolor:#000000strong*/strong/span 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080Chain ISTIO_IN_REDIRECT span stylecolor:#000000strong(/strong/span1 referencesspan stylecolor:#000000strong)/strong/spanpkts bytes target prot opt span stylecolor:#000000strongin /strong/spanout span stylecolor:#0086b3source /spandestination362 21720 REDIRECT tcp span stylecolor:#000080--/span span stylecolor:#000000strong*/strong/span span stylecolor:#000000strong*/strong/span 0.0.0.0/0 0.0.0.0/0 redir ports 15001Chain ISTIO_OUTPUT span stylecolor:#000000strong(/strong/span1 referencesspan stylecolor:#000000strong)/strong/spanpkts bytes target prot opt span stylecolor:#000000strongin /strong/spanout span stylecolor:#0086b3source /spandestination0 0 ISTIO_REDIRECT all span stylecolor:#000080--/span span stylecolor:#000000strong*/strong/span lo 0.0.0.0/0 span stylecolor:#000000strong!/strong/span127.0.0.1420 25200 RETURN all span stylecolor:#000080--/span span stylecolor:#000000strong*/strong/span span stylecolor:#000000strong*/strong/span 0.0.0.0/0 0.0.0.0/0 owner UID match 13370 0 RETURN all span stylecolor:#000080--/span span stylecolor:#000000strong*/strong/span span stylecolor:#000000strong*/strong/span 0.0.0.0/0 0.0.0.0/0 owner GID match 133711 660 RETURN all span stylecolor:#000080--/span span stylecolor:#000000strong*/strong/span span stylecolor:#000000strong*/strong/span 0.0.0.0/0 127.0.0.133 1980 ISTIO_REDIRECT all span stylecolor:#000080--/span span stylecolor:#000000strong*/strong/span span stylecolor:#000000strong*/strong/span 0.0.0.0/0 0.0.0.0/0Chain ISTIO_REDIRECT span stylecolor:#000000strong(/strong/span2 referencesspan stylecolor:#000000strong)/strong/spanpkts bytes target prot opt span stylecolor:#000000strongin /strong/spanout span stylecolor:#0086b3source /spandestination33 1980 REDIRECT tcp span stylecolor:#000080--/span span stylecolor:#000000strong*/strong/span span stylecolor:#000000strong*/strong/span 0.0.0.0/0 0.0.0.0/0 redir ports 15001/code/span/span/span