加入收藏 | 设为首页 | 会员中心 | 我要投稿 宁德站长网 (https://www.0593zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 云计算 > 正文

当从Pod访问百度时有用到VTEP吗

发布时间:2022-04-15 15:12:11 所属栏目:云计算 来源:互联网
导读:一个公众号关注者私信问我一个问题:从 Pod 内发起的,向外网的访问过程会涉及到 VTEP 吗?涉及到的 NAT 细节是什么? 我大概整理了一下,写成此文。写公众号大概有半年左右的时间了,写一段小感想:于我,每篇文章的选题和文章所涉及知识点的汇编、学习、整理
  一个公众号关注者私信问我一个问题:从 Pod 内发起的,向外网的访问过程会涉及到 VTEP 吗?涉及到的 NAT 细节是什么?
 
  我大概整理了一下,写成此文。写公众号大概有半年左右的时间了,写一段小感想:于我,每篇文章的选题和文章所涉及知识点的汇编、学习、整理、成文都是一个历练过程;于你,是一个恰好数分钟的的短暂停留;于我们,是一个交流的纽带。利是断然没有的,虚名会有一丁点,但那绝非我初衷。
 
  在文章《​​tun设备的妙用-Flannel UDP模式篇​​》中,二哥借助 tun 设备,画了几张高清大图和老铁们详细聊了下 Pod 间通信时,数据流向是什么样子的,以及在这个数据流淌过程中涉及到了哪些网络设备,这些设备又是如何在各自的位置上尽心尽责地处理、搬移每一份网络包的。
 
  那篇文章涉及到的是 Pod 间网络通信的场景。在 K8s Overlay 网络模型下,这个过程不需要对进、出 Pod 的 traffic 进行任何的 NAT。在 VXLAN 这个神器加持下,宿主机网络根本不关心、也看不到 Pod traffic 的细节,因为 traffic 都被封装起来了。
 
  但当 Pod 想访问外网,比如 www.baidu.com 的时候,就是另外一个场景了。一是 VXLAN 在这里帮不上忙,VXLAN 是在通信双方所涉及到的 work node 上利用各自的 VTEP 分别进行封包和解包,很显然外网 remote service 不可能有这个对等的 VTEP。二是也没有必要使用 VXLAN 。
 
  其实大家多多少少能大概猜得出来或隐约觉得这里面涉及到了 NAT 。可架不住细问,比如:
 
  一定需要NAT吗?
 
  假如要NAT的话,从 Pod a 看来,既然 NAT 涉及到对去程的网络包进行 IP 或 Port 的修改,那它势必需要记得这些连接在被修改过之前的信息,这样才能在网络包回来的时候再修改一番。那这些连接信息记录在那里呢?
 
  NAT 这个过程到底发生在哪里呢?Pod 里还是宿主机上?具体是网络包流经到哪个位置发生了 NAT 呢?
 
  先回答第一个问题:当 traffic 离开宿主机的时候不一定需要NAT。这取决于 K8s 所使用的网络模型。比如在 Underlay 模型下,就完全没有必要用到NAT, 具体内容详见二哥在《多图汇总梳理VPC与三种K8s网络模型》中的总结。但在 Overlay 模型下,NAT就很有必要了,所以本文的场景限定于 Overlay 模型。
 
  另外,本文所讨论的 NAT 只会到 work node 这一级。我们知道从网络包离开 work node 到最终达到百度服务器,中间可能会经过若干次 NAT ,那些我们就管不着了。不过二哥在《广角-聊聊Underlay》这篇文章里,画出了数据中心网络拓扑高清大图,如果你感兴趣的话,可以打开看看。
 
  看完了一条 conntrack entry 长什么样子,我们再来看下记录是在哪里发生的。下图中 routing + iptables of root namespace 里面,你会看到一共两处有椭圆形所标记的 conntrack 。一处是在 PREROUTING 链附近,一处是在 OUTPUT 链附近。
 
  为什么是这两个 hook 点创建连接跟踪记录呢?因为它们都是新连接的第一个包最先达到的地方:
 
  PRE_ROUTING 是外部包或者源自本机其它 network namepsace 的包最先到达的地方。从 eth0 进来的包为外部包,而从 1.5 处 cni0 bridge 进来的则为本机上其它 network namepsace 的包。
 
  LOCAL_OUT 是本机通过 root network namepsace 主动与对方通信时,网络包最先到达的地方。这里的“对方”既可以是外部服务,也可以是位于本机上的,但使用的是其它 network namepsace 的进程。
 
  当然,在LOCAL_IN和POSTROUTING处还会执行一次 confirm 操作,以确保这样一件事情:刚才所说的这个新创建的 conntrack entry ,它对应的是一条新的单向连接,这个连接的第一个包经过各种处理,一直到这里仍然健在、没有被丢弃。这并非本文重点,略过不聊。
 
  没有特殊情况,我们可以粗略地认为前文所提 conntrack entry 在 PREROUTING 和 OUTPUT 链被成功地记录下来了,以备后用。
 
  连接跟踪是许多网络应用的基础,例如 Kubernetes Service、ServiceMesh sidecar、 软件四层负载均衡器 LVS/IPVS、Docker network、OVS、iptables 主机防火墙等等都依赖连接跟踪功能。NAT更是离不开 CT 。
 
  我们结合上图来看看当 Pod a 访问百度的时候,网络包流经协议栈以及在 routing table 和 iptables 共同作用下,具体发生了什么。
 
  www.baidu.com IP 地址是 180.101.49.11 , 我们的 Pod a IP 地址为 10.244.0.2 。
 
  1.1:从Pod a发起的请求会从 1.1 一路来到 1.5 的位置。二哥在《​​tun设备的妙用-Flannel UDP模式篇​​》里面已细聊过细节,这里就跳过去了。
 
  1.6:当bridge将网络包递交到网络层后,网络包在 1.6 处便开始了它在 root network namespace 的新旅程。与之对应的是从 1.1 ~ 1.4 网络包还依旧只是在 Pod a 自己的 network namespace 里面转悠。在 1.5 处,网络包从一个 network namespace 跳转到了另外一个。
 
  1.7:如前一节所述,这里的 conntrack 会记录新的连接。
 
  1.8:经过路由选择,网络包需要从宿主机的 eth0 离开。于是走 FORWARD 链,来到 POSTROUTING 链。
 
  1.9:现在来到了 NAT 现场。结合下面的 iptables dump,我们可以清楚地看到当源IP位于 CIDR 10.244.0.0/16 ,且不是去 docker0 这个interface ,则会进行 NAT 。将Pod a的源 IP 地址修改成了 Node 1 的 IP 地址。
 
  1.10:开始将网络包送到链路层。
 
  1.11:网络包从 eth0 离开宿主机。
 
  复制
 
  -A POSTROUTING -s 10.244.0.0/16 ! -o docker0 -j MASQUERADE
 
  1.
 
  再看问题
 
  看完 Pod 访问百度时,CT 和 NAT 的介入细节,我们再来梳理一下这位同学的问题:为什么 Pod a 访问百度时 VTEP 不会介入?
 
  图2是文章《tun设备的妙用-Flannel UDP模式篇》的配图。它详细地标出了从 Node 1 上的 Pod a 访问 Node X 的 Pod b 时的数据流。为了方便理解,我们将 Flannel VXLAN 模式所用的 VTEP 换成了 UDP 模式所用的 tun 设备 + flannel daemon 组合。这样的更换只是把原本位于内核态的数据解、封装动作挪动到用户态的 daemon 里面来完成了,换汤不换药。
 
  当请求从 Pod a 发起,无论是访问外网还是访问另一个 Pod,图1和图2中 1.1 ~ 1.5 这个流程是不变的。
 
  当网络包从 1.5 处进入网络层后,网络包的去向发生了变化:
 
  如果是 Pod 间通信,网络包会经由图2中的 1.7 流动到 1.9,再完成后续的数据封包过程。
 
  与之相比,当 Pod 访问百度时,网络包在图1中 1.9 处经过 NAT 处理后,直接从 1.11 处离开了宿主机,不需要任何的封包过程,也就不需要VTEP的介入。
 

(编辑:宁德站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!