https://cizixs.com/2017/09/25/vxlan-protocol-introduction/
VXLAN 全称是 Virtual eXtensible Local Area Network
,虚拟可扩展的局域网。它是一种 overlay 技术,通过三层的网络来搭建虚拟的二层网络。rfc7348 (参考资料1) 上的介绍是这样的:
A framework for overlaying virtualized layer 2 networks over lay 3 networks.
每一个技术出来都有它要解决的问题,VXLAN 也不例外,那么我们先看看 VXLAN 到底要解决哪些问题。
传统二层+三层的网络在应对这些要求时变得力不从心,虽然很多改进型的技术比如堆叠、SVF、TRILL 等能够增加二层的范围,努力改进经典网络,但是要做到对网络改动小同时保证灵活性高却非常困难。
为了解决这些问题,有很多方案被提出来,vxlan 就是其中之一。vxlan 是 VMware、Cisco 等一众大型企业共同推出的,目前标准文档在 RFC7348。
vxlan 这类隧道网络的一个特点是对原有的网络架构影响小,原来的网络不需要做任何改动,在原来网络基础上架设一层新的网络。
vxlan 自然会引入一些新的概念,这部分就讲讲它们。下面这张图 是 vxlan 的工作模型,它创建在原来的 IP 网络(三层)上,只要是三层可达(能够通过 IP 互相通信)的网络就能部署 vxlan。在每个端点上都有一个 vtep 负责 vxlan 协议报文的封包和解包,也就是在虚拟报文上封装 vtep 通信的报文头部。物理网络上可以创建多个 vxlan 网络,这些 vxlan 网络可以认为是一个隧道,不同节点的虚拟机能够通过隧道直连。每个 vxlan 网络由唯一的 VNI 标识,不同的 vxlan 可以不相互影响。
现在来说,这些概念还是非常晦涩难理解的,我们会在下面具体讲解 vxlan 网络的报文和通信流程,希望文章结束之后再回来看这些概念能明白它们的意思。
前面说过,vxlan 在三层网络上构建一个虚拟的二层网络出来,这一点能够在 vxlan 的报文上很明显地体现出来。
下图是 vxlan 协议的报文,白色的部分是虚拟机发送报文(二层帧,包含了 MAC 头部、IP 头部和传输层头部的报文),前面加了 vxlan 头部用来专门保存 vxlan 相关的内容,在前面是标准的 UDP 协议头部(UDP 头部、IP 头部和 MAC 头部)用来在底层网路上传输报文。
从这个报文中可以看到三个部分:
报文各个部分的意义如下:
可以看出 vxlan 协议比原始报文多 50 字节的内容,这会降低网络链路传输有效数据的比例。vxlan 头部最重要的是 VNID 字段,其他的保留字段主要是为了未来的扩展,目前留给不同的厂商用这些字段添加自己的功能。
通过上节的内容,我们大致了解 vxlan 报文的发送过程。虚拟机的报文通过 vtep 添加上 vxlan 以及外部的报文层,然后发送出去,对方 vtep 收到之后拆除 vxlan 头部然后根据 VNI 把原始报文发送到目的虚拟机。
上面的过程是双方已经知道所有通信信息的过程,但是在第一次通信之前还有很多问题有解决:
这三个问题可以归结为同一个问题:vxlan 网络怎么感知彼此的存在并选择正确的路径传输报文?
而且第一个问题也是不用回答的,因为 vtep 形成的组是虚构的概念,只有某些 vtep 能够正确地传递报文,它们就是在同一个组内。也就是说,我们只要回答后面两个问题就行。
要回答这两个问题,我们还是回到 vxlan 协议报文上,看看一个完整的 vxlan 报文需要哪些信息。
总结一下,一个 vxlan 报文需要确定两个地址信息:目的虚拟机的 MAC 地址和目的 vtep 的 IP 地址,如果 VNI 也是动态感知的,那么 vtep 就需要一个三元组:
内部 MAC <--> VNI <--> VTEP IP
根据实现的不同,一般分为两种方式:多播和控制中心。多播的概念是同个 vxlan 网络的 vtep 加入到同一个多播网络,如果需要知道以上信息,就在组内发送多播来查询;控制中心的概念是在某个集中式的地方保存了所有虚拟机的上述信息,自动化告知 vtep 它需要的信息。
针对这两种方式,我们下面就分别分析。
多播的概念和工作原理不是这里的重点,所以就不介绍了。简单来说,每个多播组对应一个多播 IP 地址,往这个多播 IP 地址发送的报文会发给多播组的所有主机。
为什么要使用多播?因为 vxlan 的底层网络是三层的,广播地址无法穿越三层网络,要给 vxlan 网络所有 vtep 发送报文只能通过多播。
下图是在多播模式下,vxlan 的报文工作流程,位于左下方的 机器 A 要通过 vxlan 网络发送报文给右下方的机器 B。
vtep 建立的时候会通过配置加入到多播组(具体做法取决于实现),图中的多播组 IP 地址是 239.1.1.1
。
239.1.1.1
,支持多播的底层网络设备(交换机和路由器)会把报文发送给组内所有的成员在这个过程中,只有一次多播,因为 vtep 有自动学习的能力,后续的报文都是通过单播直接发送的。可以看到,多播报文非常浪费,每次的多播其实只有一个报文是有效的,如果某个多播组的 vtep 数量很多,这个浪费是非常大的。但是多播组也有它的实现起来比较简单,不需要中心化的控制,只有底层网络支持多播,只有配置好多播组就能自动发现了。
单播报文的发送过程就是上述应答报文的逻辑,应该也非常容易理解了。还有一种通信方式,那就是不同 VNI 网络之间的通信,这个需要用到 vxlan 网关(可以是物理网络设备,也可以是软件),它接收到一个 vxlan 网络报文之后解压,根据特定的逻辑添加上另外一个 vxlan 头部转发出去。
因为并不是所有的网络设备都支持多播,再加上多播方式带来的报文浪费,在实际生产中这种方式很少用到。
从多播的流程可以看出来,其实 vtep 发送报文最关键的就是知道对方虚拟机的 MAC 地址和虚拟机所在主机的 vtep IP 地址。如果能够事先知道这两个信息,直接告诉 vtep,那么就不需要多播了。
在虚拟机和容器的场景中,当虚拟机或者容器启动还没有进行网络通讯时,我们就可以知道它的 IP 和 MAC(可能是用某种方式获取,也有可能是事先控制这两个地址),分布式控制中心保存了这些信息。除此之外,控制中心还保存了每个 vxlan 网络有哪些 vtep,这些 vtep 的地址是多少。有了这些信息,vtep 就能发送报文时直接查询并添加头部,不需要多播去满网络地问了。
一般情况下,在每个 vtep 所在的节点都会有一个 agent,它会和控制中心通信,获取 vtep 需要的信息以某种方式告诉 vtep。具体的做法取决于具体的实现,每种实现可能会更新不同的信息给 vtep,比如 HER(Head End Replication)只是把多播组替换成多个单播报文,也就是把多播组所有的 VTEP IP 地址告诉 vtep,这样查询的时候不是发送多播,而是给组内每个 vtep 发送一个单播报文;有些实现只是告诉 vtep 目的虚拟机的 MAC 地址信息;有些实现告诉 MAC 地址对应的 vtep IP 地址。
此外,什么时候告诉 vtep 这些信息也是有区别的。一般有两种方式:常见的是一旦知道了虚拟机的三元组信息就告诉 vtep(即使某个 vtep 用不到这个信息,因为它管理的虚拟机不会和这个地址通信),一般这时候第一次通信还没有发生;另外一种方式是在第一次通信时,当 vtep 需要这些信息的时候以某种方式通知 agent,然后 agent 这时候才告诉 vtep 信息。
分布式控制的 vxlan 是一种典型的 SDN 架构,也是目前使用最广泛的方式。因为它的实现多样,而且每种实现都有些许差距,这里不便来具体的例子来说明,只要明白了上面的原理,不管是什么样的实现,都能很快上手。
vxlan 协议给虚拟网络带来了灵活性和扩展性,让云计算网络能够像计算、存储资源那样按需扩展,并灵活分布。和计算机领域所有技术一样,这也是一种 tradeoff,相对于经典网络来说,vxlan 主要的问题是它的复杂性和额外的开销。
这一点可容易看出来,每个 vxlan 报文都有额外的 50 字节开销,如果加上 vlan 字段,开销要到 54 字节。这对于小报文的传输是非常昂贵的操作,试想如果某个报文应用数据才几个字节,原来的网络头部加上 vxlan 报文头部都能有 100 字节的控制信息。
额外的报文也带来了额外的计算量,每个 vxlan 报文的封包和解包操作都是必须的,如果用软件来实现这些步骤,额外的计算量也是不可以忽略的影响。
vxlan 另外一个缺点是复杂度,虽然经典网络在应对云计算时捉紧见拙,但是经典网络模型已经发展了很久,所有的部署、监控、运维都比较成熟。如果使用 vxlan 网络,那么所有的这些都要重新学习,时间和人力成本必然会大大提高。