参考自大佬博文:https://blog.csdn.net/one_clouder/article/details/103509487,主要是对新版vxlan过程增加一些详细描述
当前主机信息如下(需要纠正,右图分别为容器C/容器D而非容器A/容器B),查看文章需要对照图的路由表、arp表、fdb表:
1、同主机
1.1、容器A依次将报文封装到ip层,报文如下
应用层:X
TCP层:src 13099,dst 80
IP层:src 10.10.1.2,dst 10.10.1.3
1.2、填充mac层
1、容器A会检查自己的arp表缓存,若有则直接填充。若没有,则发送arp请求给网桥bro端口(同网段,直接发送给网桥即可)。arp请求内容大致如下:
IP层:src 10.10.1.2,dst 10.10.1.3
MAC层:src xxx,dst FFFF
2、bro会广播arp请求给所有的其他容器,容器B会响应arp请求,将mac地址发送给bro,bro再发送给容器A,容器A拿到arp响应,填充mac层,此时报文如下:
应用层:X
TCP层:src 13099,dst 80
IP层:src 10.10.1.2,dst 10.10.1.3
MAC层:src 容器A eth0 mac地址,dst 容器B eth0 mac地址
1.3、容器A发送数据包给bro网桥
其实是发送给veth-pair另一段设备,但是这个设备没有处理协议栈的能力,因此bro会进行协议栈处理。bro网桥根据arp信息表发送给容器B,容器B进行协议栈解析,收到报文X
2、跨主机
2.1、主机A
2.1.1、容器A依次将报文封装到ip层,报文如下
应用层:X
TCP层:src 13099,dst 80
IP层:src 10.10.1.2,dst 10.10.2.3
2.1.2、mac层填充
1、容器A会检查目的网段跟自己不在一个网段,则直接将arp请求发送给网关,也即bro网卡(不同于bro网桥,但是可以认为是网桥自己的ip,网桥的网络命名空间是根命名空间)
2、网关响应容器A的arp请求,并将自己的mac地址返回给容器A,此时报文如下:
应用层:X
TCP层:src 13099,dst 80
IP层:src 10.10.1.2,dst 10.10.2.3
MAC层:src 容器A eth0 mac地址,dst 网关mac地址
2.1.3、容器A发送数据包给bro网桥
由于网段不在本交换机二层可达范围内,网桥会将报文交由bro网卡处理。bro网卡会根据主机路由(由flanneld预设置好)查看,目标网段需要将报文发送给vtep网卡
2.1.4、vtep网卡处理
1、vtep拿到数据包之后进行vxlan header封装
2、根据arp表找到目的网段对应的mac地址
3、根据fdb表拿到目的mac地址对应的对端主机ip地址,然后封装报文,内容如下:
应用层:X
TCP层:src 13099,dst 80
IP层:src 10.10.1.2,dst 10.10.2.3
MAC层:src 容器A eth0 mac地址,dst 网关mac地址
vxlan头部:xxx
udp头部:xxx(端口根据vtep设置的udp端口)
IP层:src 192.168.0.101,dst 192.168.0.102(ip获取也是根据vtep配置,一般会绑定一个本地的物理网卡)
MAC层:src 主机A vtep网卡mac,dst 主机B vtep网卡mac(需要flanneld预设置)
4、数据包从主机A物理网卡发出,最终到达主机B
2.2、主机B
2.2.1、主机B解析外层数据包
主机B解析外层协议栈,解析mac/ip/udp包,然后将数据包发送给vtep网卡
2.2.2、vtep网卡解析(flannel没有用vxlan vnid的特性,只是适配vxlan模型,用以发送数据包)
1、vtep解析数据包之后,根据主机路由发现10.1.2.0网段应该交由bro网卡处理,因此将arp请求发送给bro网卡。
2、bro网桥接收到arp请求,开始广播
3、容器D收到arp请求,进行响应并将响应转发给vtep网卡
4、vtep网卡修改内层mac数据目的mac地址为arp响应地址
5、vtep网卡将数据发送给bro网卡
2.2.3、bro交换机
bro交换机根据mac地址将数据转发给容器D对应的bro交换机端口
2.2.4、容器D协议栈解析
容器D进行mac/ip/tcp解析,最终获取到X报文