Linux 网络基础知识 - VXLAN 原理介绍


在介绍虚拟网络隔离技术 vxlan 之前,我们先来了解一下在没有虚拟网络情况下,我们使用什么方式来做网络的隔离。
什么是 VLAN?
VLAN(即虚拟局域网)是一种逻辑网络,允许连接到物理上不同 LAN 的设备进行通信。VLAN 可以在单个交换机上或跨多个控制器创建,并根据端口、MAC 地址或协议进行配置。VLAN 提供网络分段、提高安全性并增强网络性能。
VLAN 使用唯一的 VLAN ID 或编号来区分和隔离网络流量。交换机配置为使用 VLAN ID 来识别 VLAN 流量。这使得控制器能够转发同一 VLAN 内的流量,同时阻止来自其他 VLAN 的流量。
VLAN 的好处
VLAN 为网络基础设施提供了多项优势,包括:
减小广播域大小:VLAN 用于将网络分割成更小的广播域。这减少了网络上的广播流量,提高了网络性能。
增强网络安全:VLAN 可以隔离敏感数据和设备,防止其他 VLAN 进行未经授权的访问。这有助于提高网络的整体安全性。
可扩展性:通过创建逻辑段,VLAN 可以更轻松地管理大型网络。通过分配新的 VLAN 可以轻松地添加新用户或设备。
提高网络性能:隔离某些类型的网络流量并优化 VLAN 内的数据传输速率可以显著提高网络性能,从而实现更快、更可靠的数据传输。

VLAN 的不足
VLAN 有一个非常明显的缺陷,就是 VLAN tag 的设计,只有 12 位来存储 VLAN ID,标准定义中 VLAN 的数量只有 4000 个左右,这显然无法支持大型数据中心数以万计的多租户需求。
为什么需要 VXLAN
为什么需要VXLAN呢?这和数据中心服务器侧的虚拟化趋势紧密相关,一方面服务器虚拟化后出现了虚拟机动态迁移,要求提供一个无障碍接入的网络;另一方面,数据中心规模越发庞大,租户数量激增,需要网络提供隔离海量租户的能力。采用VXLAN可以满足上述两个关键需求。
虚拟机动态迁移,要求提供一个无障碍接入的网络
传统的数据中心物理服务器利用率太低,平均只有10%~15%,浪费了大量的电力能源和机房资源,所以出现了服务器虚拟化技术。如下图所示,服务器虚拟化技术是把一台物理服务器虚拟化成多台逻辑服务器,这种逻辑服务器被称为虚拟机(VM)。每个VM都可以独立运行,有自己的操作系统、APP,当然也有自己独立的MAC地址和IP地址,它们通过服务器内部的虚拟交换机(vSwitch)与外部实体网络连接。

服务器虚拟化示意图
通过服务器虚拟化,可以有效地提高服务器的利用率,降低能源消耗,降低数据中心的运营成本,所以虚拟化技术目前得到了广泛的应用。
虚拟机动态迁移,就是在保证虚拟机上服务正常运行的同时,将一个虚拟机系统从一个物理服务器移动到另一个物理服务器的过程。该过程对于最终用户来说是无感知的,从而使得管理员能够在不影响用户正常使用的情况下,灵活调配服务器资源,或者对物理服务器进行维修和升级。
在服务器虚拟化后,虚拟机动态迁移变得常态化,为了保证迁移时业务不中断,就要求在虚拟机迁移时,不仅虚拟机的IP地址不变,而且虚拟机的运行状态也必须保持原状(例如TCP会话状态),所以虚拟机的动态迁移只能在同一个二层域中进行,而不能跨二层域迁移。
传统的二三层网络架构限制了虚拟机的动态迁移范围
为了打破这种限制,实现虚拟机的大范围甚至跨地域的动态迁移,就要求把VM迁移可能涉及的所有服务器都纳入同一个二层网络域,这样才能实现VM的大范围无障碍迁移。
VXLAN 如何满足虚拟机动态迁移时对网络的要求?
众所周知,同一台二层交换机可以实现下挂服务器之间的二层通信,而且服务器从该二层交换机的一个端口迁移到另一个端口时,IP地址是可以保持不变的。这样就可以满足虚拟机动态迁移的需求了。VXLAN的设计理念和目标正是由此而来的。
从上一个小节我们可以知道,VXLAN本质上是一种隧道技术,当源和目的之间有通信需求时,便在数据中心IP网络之上创建一条虚拟的隧道,透明转发用户数据。而数据中心内相互通信的需求众多,这种隧道的建立方式几乎是全互联形态才能满足通信需求。
VXLAN 可以提供一套方法论,在数据中心IP网络基础上,构建一张全互联的二层隧道虚拟网络,保证任意两点之间都能通过VXLAN隧道来通信,并忽略底层网络的结构和细节。从服务器的角度看,VXLAN为它们将整个数据中心基础网络虚拟成了一台巨大的“二层交换机”,所有服务器都连接在这台虚拟二层交换机上。而基础网络之内如何转发都是这台“巨大交换机”内部的事情,服务器完全无需关心。
VXLAN 将整个数据中心基础网络虚拟成了一台巨大的“二层交换机”

基于这种“二层交换机”的模型,就很容易理解为什么VXLAN可以实现VM动态迁移了:将虚拟机从“二层交换机”的一个端口换到另一个端口,完全无需变更IP地址。
数据中心租户数量激增,要求提供一个可隔离海量租户的网络
众所周知,在传统的VLAN网络中,标准定义所支持的可用VLAN数量只有4000个左右。服务器虚拟化后,一台物理服务器中承载了多台虚拟机,每个虚拟机都有独立的IP地址和MAC地址,相当于接入数据中心的服务器成倍扩大了。另外,公有云或其它大型虚拟化云数据中心动辄需容纳上万甚至更多租户,VLAN的能力显然已经力不从心。
VXLAN 如何来解决上述问题呢?VXLAN 在 VXLAN 帧头中引入了类似 VLAN ID的网络标识,称为 VXLAN 网络标识 VNI(VXLAN Network ID),由 24 比特组成,理论上可支持多达 16M 的VXLAN段,从而满足了大规模不同网络之间的标识、隔离需求。
SDN 网络模型
SDN(Software Definded Network,软件定义网络)在云计算和分布式时代下应运而生。SDN 的核心思想是在物理网络之上,再构建一层虚拟化的网络,通过上层控制平面参与对网络的控制管理,以满足业务网络运维的需求。SDN 位于下层的物理网络被称为 Underlay,它着重解决网络的连通性,位于上层的逻辑网络被称为 overlay,它着重为应用提供与软件需求相符的传输服务和拓扑结构。

vxlan 就是一种基于虚拟交换机实现的 overlay 网络。
vxlan 原理
VXLAN 将二层数据帧封装在 UDP 数据包中,构建隧道在不同节点间通信。包结构如下图所示:

从包结构上可以看到,VXLAN会额外消耗50字节的空间。为了防止因数据包大小超过网络设备的MTU值而被丢弃,需要将VM的MTU减少50甚至更多,或者调整中间网络设备的MTU。
VXLAN 协议中将对原始数据包进行封装和解封装的设备称为 VTEP(VXLAN Tunnel End Point),它可以由硬件设备实现,也可以由软件实现。
VXLAN 的整体应用示意拓朴结构如图:

我们来看VXLAN的通信过程。在上图的虚拟机VM1和VM2处于逻辑二层网络中。VM1发出的二层以太网帧由VTEP封装进IP数据包,之后发送到VM2所在主机。VM2所在主机接收到IP报文后,解封装出原始的以太网帧再转发给VM2。然而,VM1所在主机的VTEP做完数据封装后,如何知道要将封装后的数据包发到哪个VTEP呢?实际上,VTEP通过查询转发表来确定目标VTEP地址,而转发表通过泛洪和学习机制来构建。目标MAC地址在转发表中不存在的流量称为未知单播(Unknown unicast)。广播(broadcast)、未知单播(unknown unicast)和组播(multicast)一般统称为BUM流量。VXLAN规范要求BUM流量使用IP组播进行洪泛,将数据包发送到除源VTEP外的所有VTEP。目标VTEP发送回响应数据包时,源VTEP从中学习MAC地址、VNI和VTEP的映射关系,并添加到转发表中。后续VTEP再次发送数据包给该MAC地址时,VTEP会从转发表中直接确定目标VTEP,从而只发送单播数据到目标VTEP。
OpenvSwitch没有实现IP组播,而是使用多个单播来实现洪泛。洪泛流量本身对性能有一定影响,可以通过由controller收集相应信息来填充转发表而避免洪泛。

VXLAN 对网络基础设施的要求很低,不需要专门的硬件提供特别支持,只要三层可达的网络就可以部署 VXLAN。VXLAN 每个边缘入口都部署了一个 VTEP,VTEP 是 VXLAN 隧道的起点和终点,VXLAN 对用户原始数据帧的封装和解封装均在 VTEP 上进行,VTEP 既可以是一台独立的网络设备,也可以是在服务器中的虚拟交换机。源服务器发出的原始数据帧,在 VTEP 上被封装成 VXLAN 格式的报文,并在 IP 网络中传递到另外一个 VTEP 上,并经过解封转还原出原始的数据帧,最后转发给目的服务器。
目前 Linux 对 VXLAN 有较完善的支持,一台 Linux 主机经过简单配置之后,就可以把 Linux bridge 作为 VETP 设备使用。VXLAN 带来了很高的灵活性、扩展性和可管理性,不过 VXLAN 也带来了额外的复杂度和性能开销,每个 VXLAN 报文的解封和封包都属于额外操作,尤其是使用软件实现 VETP,额外的性能消耗不可忽视。
Linux 上的 vxlan 实现
Linux 环境中常用的 VXLAN 实现有两种: Linux 内核实现和 OpenvSwitch实现。
Linux 内核实现
准备三台主机,物理网卡IP分别为 192.168.33.12/24, 192.168.33.13/24和192.168.33.14/24。我们在每台机器上创建一个 Linux Bridge, 三台主机上的Linux Bridge默认接口的IP分别设置为10.1.1.2/24, 10.1.1.3/24和10.1.1.4/24。此时三台主机的 Linux 网桥处于同一虚拟二层网络,但由于没有相互连接,所以无法互相访问。我们通过建立 VXLAN 隧道使其可互相访问实现虚拟二层网络 10.1.1.0/24。网络拓扑如下图所示:

在主机 1 上创建 Linux 网桥:
brctl addbr br0
给网桥接口设置 IP 并启动:
ip addr add 10.1.1.2/24 dev br0ip link set up br0
我们从主机 1 访问主机 2 上的虚拟二层网络IP:
[root@host1]ping 10.1.1.3PING 10.1.1.3 (10.1.1.3): 56 data bytes^C--- 10.1.1.3 ping statistics ---1 packets transmitted, 0 packets received, 100.0% packet loss
接下来,我们添加 VTEP 虚拟接口 vxlan0, 并加入组播 IP:239.1.1.1, 后续发送到该组播 IP 的数据包,该 VTEP 都可以接收到:
ip link add vxlan0 type vxlan id 1 group 239.1.1.1 dev eth1 dstport 4789
将虚拟接口 vxlan0 连接到网桥:
brctl addif br0 vxlan0
在另外两台主机上也完成类似配置。
首先在主机 1 查看 VTEP 的转发表,可以看到此时只有一条组播条目,所有发出流量都将发送给该组播 IP:
[root@host1]# bridge fdb show dev vxlan000:00:00:00:00:00 dst 239.1.1.1 via eth1 self permanent
我们再次从主机 1 上访问主机 2 上的网桥 IP, 此时访问成功
[root@host1]# ping 10.1.1.3PING 10.1.1.3 (10.1.1.3) 56(84) bytes of data.64 bytes from 10.1.1.3: icmp_seq=1 ttl=64 time=1.58 ms64 bytes from 10.1.1.3: icmp_seq=2 ttl=64 time=0.610 ms^C--- 10.1.1.3 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 1001msrtt min/avg/max/mdev = 0.610/1.096/1.582/0.486 ms
此时再次在主机 1 上查看 VTEP 转发表,可以看到转发表中已经学习到 10.1.1.3 所在主机的 VTEP 地址:192.168.33.13,下次再发送数据给 10.1.13 所对应的 MAC 该直接发送到 192.168.33.13:
[root@host1]# bridge fdb show dev vxlan000:00:00:00:00:00 dst 239.1.1.1 via eth1 self permanent2e:7a:a2:53:7b:31 dst 192.168.33.13 self
我们根据主机 2 上 tcpdump 的抓包结果来分析具体过程:
14:57:54.330846 IP 192.168.33.12.38538 > 239.1.1.1.4789: VXLAN, flags [I] (0x08), vni 1ARP, Request who-has 10.1.1.3 tell 10.1.1.2, length 28
10.1.1.2 主机不知道 10.1.1.3 对应的 MAC 地址,因而发送 ARP 广播,ARP 数据包发送至 VTEP,VTEP 进行封装并发送给组播 IP:239.1.1.1
14:57:54.330975 IP 192.168.33.13.58823 > 192.168.33.12.4789: VXLAN, flags [I] (0x08), vni 1ARP, Reply 10.1.1.3 is-at 2e:7a:a2:53:7b:31, length 28
主机 2 收到数据包之后解封装,VTEP 会学习数据包的 MAC 及 VTEP 地址,将其添加到转发表,并将解封后的数据帧发送到网桥接口 10.1.1.3。10.1.1.3 的接口发送 ARP 响应。
14:57:54.332055 IP 192.168.33.12.48980 > 192.168.33.13.4789: VXLAN, flags [I] (0x08), vni 1IP 10.1.1.2 > 10.1.1.3: ICMP echo request, id 4478, seq 1, length 64
主机 1 之后开始发送 ICMP 数据包,从这里可以看出外层 IP 地址不再为组播IP,而是学习到的 192.168.33.13。
14:57:54.332225 IP 192.168.33.13.55921 > 192.168.33.12.4789: VXLAN, flags [I] (0x08), vni 1IP 10.1.1.3 > 10.1.1.2: ICMP echo reply, id 4478, seq 1, length 64
接着,10.1.1.3发送回 ICMP 响应包。
参考:
https://support.huawei.com/enterprise/zh/doc/EDOC1100087027
https://thebyte.com.cn/content/chapter1/vxlan.html
https://just4coding.com/2017/05/21/vxlan/
到顶部