Hi~朋友,关注置顶防止错过消息
什么是VXLAN?
VXLAN是Linux内核本身支持的一种网络虚拟化技术。
VXLAN的目的是?
VXLAN是为了在现有的三层网络之上,覆盖一层虚拟的由内核VXLAN模块负责维护的二层网络,使得连接在VXLAN之上的主机可以像在一个局域网里那样实现自由通信。
VTEP设备是什么?
为了实现VXLAN的目的,VXLAN会在宿主机上设置一个特殊的网络设备作为通信的两端,该设备就是VTEP设备。
VTEP设备既有IP地址也有MAC地址。
VTEP设备的作用是?
VTEP设备类似flanned进程,用来封装和解封二层数据帧,封装和解封的过程均在内核态完成。
当包含VTEP设备的宿主机并加入Flannel网络以后,会在其他的Flannel节点下添加路由规则,如下:
$ route -n
Kernel IP routing table
DestinationGatewayGenmaskFlagsMetricRefUseIface
...
10.1.16.010.1.16.0255.255.255.0 UG 000 flannel.1
该规则的含义是目的IP是10.1.16.0/24网段的IP数据包,都需要经过flannel.1设备发出,发往的网关地址是10.1.16.0,该网关地址也是目的主机上VTEP设备的IP地址。
VTEP设备的MAC地址如何获取?
为了让VTEP设备之间进行二层网络的通信,我们需要知道目的设备MAC地址,而MAC地址的学习正式ARP表的功能,在这里ARP记录,是新的Flannel节点加入时,自动在其他的Flannel节点上进行添加的,如下:
$ ip neigh show dev flannel.1
10.1.16.0 lladdr 5e:f8:4f:00:e3:37 PERMANENT
通过上述命令我们可以明确地知道IP地址为10.1.16.0 VTEP设备的MAC地址是5e:f8:4f:00:e3:37。
如何知道发给哪个宿主机?
上述过程我们都是VTEP设备的信息,但是VTEP设备所在的宿主机在哪我们还不清楚,为了知道宿主机在哪,flannel.1设备在这里还会扮演网桥的角色,在Linux内核中,网桥转发的依据需要查找一个FDB的转发数据库,flannel.1网桥对应的FDB信息也是由flanned进程进行维护,内容可以通过以下命令进行查看:
$ bridge fdb show flannel.1| grep 5e:f8:4f:00:e3:37
5e:f8:4f:00:e3:37 dev flannel.1 dst 10.168.0.3self permanent
dst 10.168.0.3即为我们发往的宿主机IP地址。
VXLAN通信过程

首先来自容器的包还是会先到达docker0网桥
到达网桥后,经由路由表判断,需要通过flannel.1设备发往10.1.16.0
在数据包到达flannel.1设备后,这里会查到目的端的VTEP设备的MAC地址,此时会进行第一次封包工作,在原始数据包上增加一个二层的数据头,如下图:

上述封装出来的数据帧并不能在我们的宿主机二层网络里面进行传输,因此Linux内核需要进一步进行封装,以便通过我们宿主机的eth0进行传输。
进一步封装二层数据帧,首先会增加一个VXLAN头,该头里面有一个重要的标志称之为VNI,在Flannel中VNI的默认值是1, Flannel默认的VETP设备都是flannel.1,它是VTEP设备识别该数据帧需不需要自己处理的重要标志.
Linux接着会将数据帧封装成一个UDP包进行转发,因此会增加UDP的header
UDP包是一个四层数据包,因此Linux内核会通过FDB表找到目的设备VTEP对应宿主机的IP,紧接着在IP包前面添加二层数据帧头,里面包含了目的宿主机的MAC地址(该MAC地址是由宿主机通过ARP自学习获取,和Flannel无关)

经过所有的封包,完整的二层数据帧封装完毕,经由宿主机的eth0网卡转发至目的宿主机,在目的宿主机上则是上述过程的逆向解封。
本期文章就到这,长按扫码关注,更多内容我们下期再见!





