首页
视频
资源
登录
原
Flannel Vxlan
3939
人阅读
2022/12/5 13:28
总访问:
2273166
评论:
1
收藏:
0
手机
分类:
容器编排
 ># Flannel Vxlan [TOC] ## 同节点同Pod不同容器 tn2>使用共享的网络名称空间进行通信,使用Container网络模式,通过lo网卡建立两个容器之间的通讯。 其他名称空间仍然隔离。(文件名称空间,系统名称空间,进程列表) ## 同节点不同Pod >### 精简 tn2>首先走2层16位的路由段,到主网络名称空间下。由于是桥接,所以再从桥接下的网络查询mac地址到指定的接口不同的网络名称空间中。 Pod的里面eth0对应的peer是谁? 可通过`ethtool -S eth0`查询该Pod的虚拟网卡对在主机网卡中所对应的下标。 如何知道该主机虚拟网卡的pod peer是在哪个Linux Bridge下? 可以通过`brctl show`来查看。 Pod如何发包到同节点的Pod? 通过Linux Bridge桥接模式实现的,可通过`brctl showmacs cni0`查看cni0网桥下的所有Mac地址。 cni0网桥是如何学习到同节点下面其他网络的? 首先一个Pod在Ping同节点另一个Pod的时候,会发一个ARP包进行广播询问,有Pod响应,然后主机Bridge记录两端的IP与mac信息。 然后可进行通信。 Pod本地会记录对端IP和MAC地址到ARP表中,当然主机的arp表会记录所有的。 是走路由还是查ARP表直接进行通信? 首先通过查询路由表走二层的网络,然后可以看到走的eth0的网卡。  >### 细节实践 tn2>首先创建三个Pod,两个相同节点一个不同的节点。 ```bash vim deploy.yaml ``` ```yaml apiVersion: v1 kind: Pod metadata: name: c1 spec: containers: - name: c1 image: burlyluo/nettoolbox nodeSelector: kubernetes.io/hostname: k8s-125-node1 --- apiVersion: v1 kind: Pod metadata: name: c2 spec: containers: - name: c2 image: burlyluo/nettoolbox nodeSelector: kubernetes.io/hostname: k8s-125-node1 --- apiVersion: v1 kind: Pod metadata: name: c3 spec: containers: - name: c3 image: burlyluo/nettoolbox nodeSelector: kubernetes.io/hostname: k8s-125-node2 --- ``` ```bash kubectl apply -f deploy.yaml ```  tn2>由于c1和c2 pod在同一个`k8s-125-node1`节点中,我就以这两个pod为例,c1 ping c2 是没有问题的。 ```bash kubectl exec c1 -- ping 192.168.1.4 -c 1 ```  tn2>首先我们通过查询c1 Pod的路由,当ping c2的时候会从第三条路由出去,并且会从`eth0`接口出去,如何知道连接的哪条线到root ns(主机网络名称空间)呢? ```bash kubectl exec c1 -- route -n ```  tn2>我们可以通过`ethtool -S eth0`命令来查询该接口对应主机接口的下标,我们看到下标为10,在node1主机上我们通过`ip -a`来查看插入两头的虚拟网卡对,我们查到对应的peer名为`vethf8fbd60e@if2`并且指定网桥设备为`cni0`。 ```bash kubectl exec c1 -- ethtool -S eth0 ```   tn2>然后在主机上再次查看路由表,发现c2 `192.168.1.4`从第四条路由出去,并且是从`cni0`这个接口出去,我们从上图得知`cni0`是一个虚拟网桥,那么我们可以通过`brctl show`查询Bridge下有几个虚拟网卡对连接的,便可以从这几个接口中通过发送ARP包获取两端mac地址,并记录到Bridge Mac表中。 那么Bridge的mac地址该如何查询呢?可通过`brctl showmacs cni0`命令进行查询。   tn2>我们再来查询一下c2的mac地址为:`E6:F7:42:B5:1A:59`。所以结合上图我们就知道该mac从第三个接口`veth6d1d420a`出去,完成整个通信。 ```bash kubectl exec c2 -- ifconfig ```  ## 不同节点不同的Pod通信。  >### 精简 tn2>首先查询路由到主网络名称空间下,然后查询路由获得对端Pod所在的主机的网关地址,并发现从`flannel.1`接口出去,那么我们源IP和目的IP不变是pod的ip,Mac地址改变为两个Node中`flannel.1`接口的mac。 主机是如何知道对端IP和Mac地址的? 是有一个`flanneld`进程通过`ip monitor`的一些网络事件来收集信息这些信息将存储到etcd中,然后将相关mac地址与ip记录到(IP)fdb表中和(mac)arp表中,然后`flannel.1`通过ARP表查询对端mac地址(通过三层IP查询二层mac地址就该查ARP表,如果没有还是会发ARP包进行询问的)得到mac地址后查询fdb表查询知道了对方的节点的ip地址,再通过封装Vxlan的包发出去,然后到对端的`flannel.1`后再进行解析内部IP。 >### 细节实践 tn2>首先我们通过c1来ping c3发现是没有问题的。 接下来我们分析路由。  tn2>接下来我们查询路由表,发现走的是第二条路由并且是从主机eth0接口出去的,也是通过对端插入的`vethf8fbd60e@if2`网卡到cni0下面后,将包递给主机的内核协议栈中主网络名称空间下面。 ```bash kubectl exec pod/c1 -- route -n ```  tn2>然后根据上面的路由,我们发现它是走的第五条路由,该包会从`flannel.1`接口出去。 ```bash 192.168.2.0 192.168.2.0 255.255.255.0 UG 0 0 0 flannel.1 ``` tn2>当数据包到达`flannel.1`时,需要对其进行二层Vxlan封装,网关下一跳为`192.168.2.0/32`,那么我们知道IP但不知道目的mac地址啊,将如何得知呢? 首先我们查ARP表可以得到该目标地址的mac地址,我们可以通过执行`arp`命令进行查看。  tn2>这一条Mac地址arp表又是如何得到的呢? 是通过`flanneld`的进程通过etcd数据库中记录的ip和mac地址信息插入arp表中的。 那么我们如何知道该ip是在哪台主机上呢? 其实是通过`fdb`表查询mac获得具体主机的ip地址。 ```bash # 对端的192.168.2.0 bridge fdb show dev flannel.1 | grep 'e6:a0:83:60:8d:92' ```  tn2>我们知道了是`10.211.55.9`主机上面。 那么又是谁在维护`fdb`的信息?以及是怎么管理的? 答案还是`flanneld`插入的这些信息,先通过`ip monitor`获取网络的事件然后将其中的网络信息存储到etcd中,最后`flanneld`将更新和维护fdb表和arp表、route表。  tn>注意这个时候封装的Vxlan的包将修改源mac和目的mac为两端的`flannel.1`网卡的mac地址,当然IP上层为主机IP就是`10.211.55.8`和`10.211.55.9`。 我们可以通过抓包来查看。 ```bash tcpdump -pne -i flannel.1 # 9e:72:63:96:91:7e 是node1中的flannel.1 # e6:a0:83:60:8d:92 是node2中的flannel.1 ```  tn2>当然我们在进行UDP封包的时候,还需要知道VNI和UDP发出的Port端口如何获取呢? 任何一个VXLAN设备在创建时都会指定一个三层物理网络设备作为VTEP,这个物理网络设备的IP就是UDP的源IP。可使用以下命令查询flannel.1的VTEP信息、VNI信息、UDP Port信息。 ```bash ip -d link show flannel.1 ```  tn2>我们可以看到VNI为1,然后UDP的port为8472,与我们概述的Flannel相符合。 然后UDP发送对端节点后,就会去对比对端VNI是否一致,Mac地址是否一致,都一致就会去掉Vxlan的头和Inner Ethernet 的头,然后把数据包从flannel.1网卡进行发送,然后通过对端路由到cni0中。  tn2>大致就是这样的。唯一需要注意的就是当跨节点flannle.1到对端的flannle.1的时候,mac地址会更改但vxlan解析后mac地址除了源mac地址改为cni0的地址外目的mac是c3 pod的mac。 tn>所以从理论来讲,Flannel使用的还不是真正的Vxlan模式。
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739
👈{{preArticle.title}}
👉{{nextArticle.title}}
评价
{{titleitem}}
{{titleitem}}
{{item.content}}
{{titleitem}}
{{titleitem}}
{{item.content}}
尘叶心繁
这一世以无限游戏为使命!
博主信息
排名
6
文章
6
粉丝
16
评论
8
文章类别
.net后台框架
164篇
linux
17篇
linux中cve
1篇
windows中cve
0篇
资源分享
10篇
Win32
3篇
前端
28篇
传说中的c
4篇
Xamarin
9篇
docker
15篇
容器编排
101篇
grpc
4篇
Go
15篇
yaml模板
1篇
理论
2篇
更多
Sqlserver
4篇
云产品
39篇
git
3篇
Unity
1篇
考证
2篇
RabbitMq
23篇
Harbor
1篇
Ansible
8篇
Jenkins
17篇
Vue
1篇
Ids4
18篇
istio
1篇
架构
2篇
网络
7篇
windbg
4篇
AI
17篇
threejs
2篇
人物
1篇
嵌入式
2篇
python
10篇
HuggingFace
8篇
pytorch
1篇
最新文章
最新评价
{{item.articleTitle}}
{{item.blogName}}
:
{{item.content}}
关于我们
ICP备案 :
渝ICP备18016597号-1
网站信息:
2018-2023
TNBLOG.NET
技术交流:
群号656732739
联系我们:
contact@tnblog.net
欢迎加群
欢迎加群交流技术