VXLAN是使用隧道技术的封装协议,常用于在物理层之上创建overlay网络,赋能虚拟网络。同时支持数据中心网络的虚拟化,并通过提供必要的分段满足多租户的需求。
优势在于
默认MTU为1500Bytes,在经过VTEP时会封装50字节的VXLAN报文头,那么可能会达到1550字节。所以这要求要买VTEP之间网络设备MTU设为1550字节,要买让终端机器设为1450
spine-leaf是由spine和leaf交换机组成的两层网络拓扑结构,有助于数据中心网络减少网络延迟和跳数,提高网络效率。
spine-leaf拓扑好处在于每两个目的地最多两跳,并且可以在不影响overlay网络架构的情况下进行动态扩展
大概过程是
在同vxlan内一个主机A上的虚拟机vm1向另一个主机B上的虚拟机B发送报文的关键在于
以下是一个详细arp请求报文发送过程
vm1发现与vm3在同一网段,但没有vm3的mac地址,于是发起对vm3的arp请求。
arp请求源ip在vm ip,目的ip是vm3 ip,源mac是vm 1的mac,目的mac是全0字段,表示希望获取vm3 mac。
vtep leaf A收到vm 1 arp请求,根据入端口和vlan信息判断应该匹配vxlan 10,
leaf A接着发现arp请求是广播,于是将这个报文在本地和远端所有vxlan 10的端口进行广播
spine C收到leaf A发来的报文,发现目的ip是自己,于是将其解封装。而后发现UDP的目的端口是4789,于是将UDP的上层报文进行VXLAN解封装处理。接着发现是广播报文于是在VXLAN 10进行广播
leaf B收到leaf A报文,解包。由于报文是从Tunnel 1中收到的,所以端口信息为Tunnel 1。根据VXLAN 10的映射关系表,将原始二层报文在本地所有VXLAN 10端口进行广播
vm3收到vm1,写入vm1 ip和mac对应关系到arp表项,并准备arp应答
广播过程中leaf、spine都会顺便将vxlan、mac、入端口和vlan信息写入相应vsi mac表。vsi mac记录了VETP ip、vm mac、vni,那么之后在接受到目的mac为该vm mac的时候就能直接找到对应的VETP ip和所在的vxlan
# 在一台虚拟机上添加vxl0的vxlan interface,其中vni为11,dstport是linux默认的8472端口,并将vtep加入到group 239.1.1.1多播组
ip link add vxl0 type vxlan id 11 dstport 4789 group 239.1.1.1 dev eth0
# 查看是否成功添加
ip link show
# 添加ip地址
ip addr add 10.20.1.2/24 dev vxl0
# 启动vtep
ip link set vxl0 up
# 查看fdb表项
bridge fdb
多播:多播地址能让源设备将分组发送给一组设备。属于多播组的设备将被分配一个多播组ip地址,多播地址范围为224.0.0.0~239.255.255.255
fdb表:arp是三层转发,而fdb是二层转发。所以对于fdb来说就算没配ip,也能通过fdb转发数据。FDB表的作用就在于告诉设备从某个端口出去就可以到某个目的MAC。
那么FDB表是怎么形成的呢?很简单,交换机会在收到数据帧时,提取数据帧中的源MAC、VLAN和接收数据帧的端口等组成FDB表的条目。当下次有到该VLAN中的该MAC的报文就直接从该端口丢出去就OK了。
在实际生产中,每台主机上都有几十台甚至几百台虚拟机或者容器需要通信,因此需要一些机制将这些通信实体组织起来,然后通过隧道vtep转发出去
一个常见的方案就是通过Linux bridge将多个虚拟网卡连接
# 在主机添加vxl0的vxlan interface,其中vni为12,dstport是linux默认的8472端口,并将vtep加入到group 224.1.1.1多播组
ip link add vxl0 type vxlan id 12 dstport 4789 local 192.168.3.107 group 224.1.1.1
# 添加连接的bridge
ip link add vxbr0 type bridge
# 将vxl0作为vxbr0的主设备
ip link set vxl0 master vxbr0
# 启动vxlan和bridge
ip link set vxl0 up
ip link ser vxbr0 up
# 新增网络命名空间
ip netns add vxns0
# 添加主机与vxns0之间的veth peer,并连接vxbr0
ip link add vxve0 type veth peer name eth1 netns vxns0
ip link set vxve0 master vxbr0
ip link set vxve0 up
# 在命名空间内,设置loopback,添加eth1设备地址,并启动
ip -n vxns0 link set lo up
ip -n vxns0 addr add 174.17.1.2/24 dev eth1
ip -n vxns0 link set eth1 up
所以容器怎么办呢?怎么将一个主机的多个容器纳入到一个vxlan管理呢?难道是在容器内建立与bridge之间veth peer?那这和netns有什么关系呢?为什么要有这个netns?
在overlay网络中,网段范围分布多个主机,因此传统arp报文广播无法直接使用,所以引入了多播
但多播的不利之处在于不是所有网络支持多播,而且要事先规划多播组和vni对应关系,同时也会导致大量无用报文
因此我们可以采用自动化方式
# nolearning 告诉vtep不要通过收到的报文来学习fdb表项内容
# proxy 告诉vtep承担arp代理功能。收到arp请求,在知道结果的情况就直接应答
ip link add vxl1 type vxlan id 13 dstport 4789 local 192.168.3.107 nolearning proxy
# 告诉vtep 容器mac对应主机ip地址。
# 默认(全0)表项可以在不知道ip和mac对应关系时通过arp报文查询对方的mac地址
bridge fdb append 00:00:00:00:00:00 dev vxl1 dst 192.168.3.105
bridge fdb append 00:00:00:00:00:00 dev vxl1 dst 192.168.8.106
bridge fdb append 52:5e:55:58:9a:ab dev vxl1 dst 192.168.8.105
bridge fdb append d6:d9:cd:0a:a4:28 dev vxl1 dst 192.168.8.106
# 添加arp表项
ip neigh add 174.17.1.3 lladdr d6:d9:cd:0a:a4:28 dev vxl1
ip neigh add 174.17.1.4 lladdr 52:5e:55:58:9a:ab dev vxl1
在提前添加所有可能通信容器到arp、fdb表项,但不是所有容器都会互相通信。所以Linux提供了能够动态通知节点要和哪个容器通信,应用可以订阅这些事件。若内核发现需要arp、fdb不存在,就会发送给订阅的应用,这样应用从中心化控制拿到这些来更新表项,做到更精确控制
# l2miss 若设备找不到mac需要的vtep地址就发送事件
# l3miss 若设备找不到ip对应mac地址就发送事件
ip link add vxl2 type vxlan id 14 dstport 4689 dev en0 nolearning proxy l2miss l3miss
# 监听vxl2事件
ip monoitor all dev vxl2
# 若发现l3 miss [nsid current]miss 10.20.1.3 STALE
# 添加arp记录
# nud reachable 就是有一个超时事件。若系统发现无效一段时间后会自动删除
# nud是neighbour unreachability detection, permanet 代表记录永远不会过时
ip neigh replace 10.20.1.3 lladdr b2:ee:aa:42:8b:0b dev vxl2 nud reachable
# 若发现l2miss [nsid current]miss lladdr b2:ee:aa:42:8b:0b STALE
# 手动添加fdb记录
bridge fdb add b2:ee:aa:42:8b:0b dst 192.168.8.101 dev vxl2