VXLAN, 一种叠加在L3网络上的L2网络

这几天看了下RFC7348,顺便翻译了一下,根据自己理解做了注解

虚拟化及租户隔离

服务器虚拟化增加了对物理网络基础设施的需求,服务器有多个虚机,要求交换机支持更大的MAC地址表。

在数据中心场景下,虚机按照VLAN分组,可能需要成千上万的VLAN,以便用来给为按照VLAN标签分组的虚机分隔流量。但是当前VLAN机制限制最多只能有4096个VLAN。

数据中心需要支持多个租户,每个租户需要分隔的网络域,单独实现分离的网络域不经济。管理员一般基于共享网络进行隔离。各租户独立进行VM的MAC和VLAN的分配,可能在共享的同一个物理网络上,出现MAC和VLAN的冲突。

在虚拟化场景下,还有一个需求是基于第二层在整个数据中心,或者跨数据中心进行扩展,扩展计算,存储和网络资源,此时传统的用来避免路径循环的STP协议,会使得更大数量的失效链路出现。此时,虽然更倾向于使用IP进行物理基础设施的链接,比如,为了实现多路径的扩展,使用ECMP避免生效链路,但是维持虚机间的L2通信依然是需要保留的。

以上场景导致了overlay叠加网络的需求,这个叠加网络用来将来自虚机的携带MAC的流量,封装后通过逻辑隧道传递。VXLAN就是这样的一种实现overlay网络的方式。

和VXLAN相关的常用术语有

ACL      Access Control List 访问控制表

ECMP     Equal-Cost Multipath 等价多路径

IGMP     Internet Group Management Protocol IGMP协议

IHL      Internet Header Length  Internet报文头长度

MTU      Maximum Transmission Unit  最大传输单元

PIM      Protocol Independent Multicast 协议无关的多播

SPB      Shortest Path Bridging  最短路径转发

STP      Spanning Tree Protocol 生成树协议

ToR      Top of Rack  机架交换机

TRILL    Transparent Interconnection of Lots of Links 多链路透明互联

VLAN     Virtual Local Area Network  虚拟LAN

VM       Virtual Machine  虚机

VNI      VXLAN Network Identifier (or VXLAN Segment ID) VXLAN网络标识符

VTEP     VXLAN Tunnel End Point.  An entity that originates and/or

terminates VXLAN tunnels  VXLAN隧道端点

VXLAN    Virtual eXtensible Local Area Network  VXLAN

VXLAN Segment    VXLAN段

VXLAN Layer 2 overlay network over which VMs communicate

VXLAN Gateway    VXLAN网关

an entity that forwards traffic between VXLANs

VXLAN应用场景

VXLAN主要聚焦于数据中心基础设施。

STP和VLAN导致的限制

当前L2网络主要使用802.1D STP协议在多路径基础上避免环路。但是数据中心管理员将之视为L2网络上的问题,因为STP,需要负担额外超过需要的端口和链路。STP模型下,失去了多路径的弹性。一般引入TRILL(RFC6325)或者SPB(802.1AQ)来帮助解决因为STP引起的多路径问题。STP的约束也可以通过将同一机架的服务器配置在相同的L3网络规避,机架内和机架间使用L3交换。但这和虚机之间的L2互联不兼容。

数据中心L2网络中普遍使用VLAN来隔离广播,以太网帧中的12bit VLANID用来将大的L2网络分隔为小的广播域。对小于4096 VLAN 的数据中心来说这样很好,随着虚拟化的流行,压力逐渐增大。更加的,因为STP,某些数据中心限制可以使用的VLAN数。再加上以上讨论的,多租户场景下,对大数量VLAN的需求。

多租户

多租户场景下,云计算要求资源的弹性呈现。最常见的云计算案例是共有云,云服务提供商基于同样的物理基础设施为多个租户提供弹性服务。

租户的网络流量分隔可以基于L2或者L3网络。对L2网络而言,常用VLAN分隔流量,这样租户以自己的VLAN标识。因为云服务租户的庞大数量,VLANID最大4096就不够用了。不仅如此,还有同一租户内不同VLAN的需求。

一个案例是跨POD扩展。一个POD是一个或者多个包含服务器的机架,以及相关的存储和网络组成。租户可能从一个POD起步,然后逐步需要其他POD上的VM,特别是这个‘其他’POD的租户没有充分使用POD中的资源。这个案例需要L2网络的伸缩性。

L3网络不是一个容易理解的多租户解决方案,两个租户可能各自使用同一套L3网络地址,需要云提供商支持其他形式的隔离,对于虚机间的通信,要求租户使用IP,但又不是不是信赖的直接L2网络,或者非IP的L3协议。

TOR交换机的ARP表容量

虚拟化场景对连接服务器的TOR交换机的MAC地址表容量提出了额外的要求。不是一个MAC对应一个服务器,TOR交换机需要学习一个服务器中可能多达上百的虚机的MAC。因为虚机流量会经过服务器和TOR之间的链路,传统TOR交换机,根据其面板端口数,可能连接24、48个服务器,数据中心可能包含很多个机架,每个TOR需要维护不同服务器之间通信的虚机的地址表,对比非虚拟化场景,这个对地址表空间的要求很高。

如果表空间满,交换机停止学习,直至表项超期。会导致大量未知单播帧。

VXLAN

VXLAN基于数据中心多租户场景下,聚焦以上需求,立足现有 网络基础设施,提供L2网络的伸缩。简单说,VXLAN是基于L3网络上的L2叠加网络,每一个叠加网络可称为VXLAN Segmeng,只有归属于同一个VXLAN Segment的虚机才能相互通信(这里应该是L2通信),每一个VXLAN Segment通过一个24bit的Segment ID标识,成为VXLAN Network Identifier(VNI),在同一个管理域中,最多有16M个VXLAN Segment段存在。

VNI标识了来自虚机的内部MAC帧的范围,因此跨VXLAN Segment,MAC是可以重叠的,但是(L2)流量不能,因为通过VNI分隔了。在封装来自VM的内部帧时,VNI封装在外部头中。

VXLAN Segment和VXLAN叠加网络是可以相互使用的术语。

因为封装,VXLAN是叠加在L3网络上的L2网络。隧道是无状态的,每一个帧按照一系列规则进行封装。隧道端点(VXLAN Tunnel End Point,VTEP)位于虚机宿主机的hypervisor层。这样VNI,和VXLAN相关的隧道,以及外部头封装仅为VTEP所知,虚机不感知。VTEP可以是物理交换机,或者物理服务器,可以软件或者硬件实现。

一种典型的VXLAN场景下的业务流控制是数据面学习,这里,通过源MAC地址学习,将虚机的MAC和VTEP的IP地址关联,多播则用于携带未知单播,广播和多播帧。

除了基于学习的业务流控制,其他还有分发虚机MAC和VTEP IP映射信息,可选项还包含一个基于认证或者基于目录的单个VTEP的集中查询机制,向VTEP分发这些映射信息,这个有时也被称为PUSH/PULL模型。基于学习的机制更加普遍。

虚机-虚机单播

设想,一个VXLAN网络中的虚机,不知道VXLAN,和其他服务器上的虚机通信,发送ARP查询,VTEP根据目的MAC查找这个虚机归属的VNI,以判断是否和源虚机处于相同VNI。是否需要目的MAC和对端VTEP的映射,如果答案为需要,则需要组装一个包含了外部帧头(MAC),外部IP头,VXLAN头的外部报文头。封装报文转发到对端VTEP。

对端VTEP检查VNI,判断本地对应VNI中是否有虚机匹配内部帧当中的目的MAC,如果是则报文去掉封装部分发送给目的虚机,后者不感知外部帧,以及VXLAN封装。

为了将报文转发给目的虚机,远端VTEP需要学习内部帧源MAC(本端虚机)和外部源IP(本端VTEP地址)的映射,也就是VTEP需要学习对端虚机MAC和对端VTEP的映射关系,实际上,这个VTEP可以通过广播ARP查询来实现。

VTEP将这个映射存储在表中,当目的虚机返回响应时,VTEP根据目的MAC查表,将报文封装后发给特定的(发出请求报文的虚机归属的)VTEP。这里无需未知目的泛洪。

实际传输之前,源虚机确定目的虚机的MAC地址,过程类似非VXLAN环境,略有一点不同,下文描述。广播帧封装在多播报文中发送。

广播和多播映射

虚机使用IP地址进行通信时,假定处于同一subnet中,源主机首先发送ARP广播,在非vxlan环境中,这个帧,携带VLAN,在所有交换机中广播。

Vxlan下,包含vni,ip头和udp头的数据段插入到报文的前部,这个报文会被广播到overlay所在的ip 多播组中。

为了实现这个效果,需要在vxlan vni和需要使用的ip多播组之间进行映射,这个在管理层实现,并通过管理通道发送给VTEP,使用这个映射,vtep可以在需要时,向上行流的交换机/路由器发送加入/离开IP多播组的IGMP成员报告。如此这般,可使用特定多播地址,基于主机上组播成员是否存在,维护特定的多播地址(rfc4541)。使用某些路由协议,比如PIM-SM(RFC4601),可在L3网络上提供足够的多播树。

VTEP使用(*.G)联合joins,在VXLAN隧道源未知或者经常变化的场景下(因为虚机常常在不同主机之间迁移),因为VTEP既可以作为多播数据报的源也可以作为目的,类似BIDIR-PIM(RFC5015)这样的协议效率更高。

目的虚机的ARP响应通过普通IP单播发送,到达和源虚机相连的VTEP,条件是先前已经学习了ARP响应的目的MAC地址到VTEP IP的映射。

多播帧和未知目的MAC帧,类似广播帧,使用多播树发送。

物理基础设施

在网络中使用IP多播时,网络中的L3设备,交换机/路由器会用到多播路由协议,比如PIM-SM,这样会构建有效的多播转发树,多播报文会发送到希望到达的主机处。

另外,并没有要求源和目的主机基于L3网络连接,VXLAN也可以基于L2网络,此时可通过IGMP snooping在L2网络上实现多播复制。

VTEP不能对VXLAN报文分片。中间路由器可能因为过大帧长的缘故对VXLAN封装报文分片。目的VTEP可能丢弃这些分片了的VXLAN报文,为了避免端到端流量的可能分片,推荐将所经过的物理设施的MTU设置为能容纳可能的最大VXLAN封装。其他技术,诸如Path MTU Discovery(RFC1191/RFC1981)可用来满足这个需求。

VXLAN场景

VXLAN一般应用于数据中心虚机,这些虚机分布在不同的机架,单个机架可能属于多个不同的L3网络,但可能属于同一个L2网络,VXLAN段叠加在这些L2或者L3网络上。

类似下图,两个虚拟服务器挂载于同一个L3网络,这两个服务器可能位于同一机架,也可能不同机架,或者是同一管理域的不同数据中心,有4个VXLAN 段,VNI22,34,74,98,Server1中的VM1-1和Server2中的VM2-4位于同一VNI22,虚机不知道叠加网络的存在,因为vxlan封装和解封装在vtep上发生,其他vni如表格

Vni  server1         server2

22    vm1-1           vm2-4

34    vm1-2            vm2-1

74    vm1-3            vm2-2

98    vm1-4            vm2-3

一个部署场景是,VTEP在一个感知vxlan网络的物理服务器中,另一种场景,VXLAN叠加网络中的节点,需要于传统网络,可能是VLAN,中的节点通信。此时需要部署VXLAN网关,在VXLAN和非VXLAN网络之间转发流量。

来自VXLAN网络接口的入向帧,网关去掉VXLAN头,根据内部帧目的MAC地址进行转发,包含内部帧VLAN ID的解封装报文,只能转发到非VXLAN接口,否则丢弃。相对的,来自非VXLAN 接口的报文,根据VLANID,映射到特定的VXLAN 叠加网络,除非显式配置通过封装的VXLAN传递,否则VLANID在封装为VXLAN报文前应当删除。

提供VXLAN隧道终结功能的网关,可以是TOR或者接入交换机,也可以是DC网络拓扑中的上层网络设备,比如核心或者WAN边缘设备,后一种场景,可能包含一个Provider Edge路由器用来在混合云环境中终结vxlan隧道,所有这些案例中,网关可能是软件或者实现。

网关或者VTEP处理包含VLANID的帧的规则:

解封装后包含VLANid的VXLAN帧,除非配置,否则丢弃。

VTEP封装VXLAN隧道报文时,内部不带VLANid,除非专门设置。就是说若一个带有vlan tag的报文准备进入vxla隧道时,除非显式配置,否则应该去掉vlan tag。(就是vni和vlan tag的映射)

时间: 2024-08-08 05:38:08

VXLAN, 一种叠加在L3网络上的L2网络的相关文章

目前网络上开源的网络爬虫以及一些简介和比较

目前网络上有不少开源的网络爬虫可供我们使用,爬虫里面做的最好的肯定是google ,不过google公布的蜘蛛是很早的一个版本,下面是几种开源的网络爬虫的简单对比表: 下面我们再对Nutch.Larbin.Heritrix这三个爬虫进行更细致的比较: Nutch 开发语言:Java http://lucene.apache.org/nutch/ 简介: Apache的子项目之一,属于Lucene项目下的子项目. Nutch是一个基于Lucene,类似Google的完整网络搜索引擎解决方案,基于H

JNDI提供了一种统一的方式,可以用在网络上查找和访问服务

JNDI提供了一种统一的方式,可以用在网络上查找和访问服务.通过指定一个资源名称,该名称对应于数据库或命名服务中的一个记录,同时返回数据库连接建立所必须的信息. JNDI主要有两部分组成:应用程序编程接口和服务供应商接口.应用程序编程接口提供了Java应用程序访问各种命名和目录服务的功能,服务供应商接口提供了任意一种服务的供应商使用的功能. 代码示例: try{ Context cntxt = new InitialContext(); DataSource ds = (DataSource)

【重磅】移动网络性能揭秘(上)--移动网络组件详解

简介 在过去的几年里我们在移动蜂窝网络性能方面取得了重大进展.但是由于网络延迟的膨胀导致许多应用并没有得到改善. 延迟问题长期以来一直制约着移动网络.尽管近年来已取得一些进展,但减少网络延迟没有跟上延迟的增长速度.正是由于这种不对等导致了延迟,而不是吞吐量,成为影响网络性能的最大因素. 这篇文章逻辑上主要包含两章.第一部分将讨论导致移动网络延迟的细节:第二部分介绍提高网络性能降低延迟的软件技术. 你在等待的是什么? 延迟表示一个数据包通过一个或一系列网络所需要的时间.由于很多因素,移动网络会使已

使用异步任务加载网络上json数据并加载到ListView中

Android中使用网络访问来加载网上的内容,并将其解析出来加载到控件中,是一种很常见的操作.但是Android的UI线程(也就是主线程)中是不允许进行耗时操作的,因为耗时操作会阻塞主线程,影响用户体验.而访问网络同样是一个耗时操作,并且Android3.0以后是不允许在主线程中访问网络的,所以我们这里用Android封装好的AsyncTask类来完成这些耗时操作. 项目的目录结构如下: AsyncTask是一个抽象类,实际上他是封装好的一个类,底层也是用handler和thread来实现的,我

ios学习(从网络上获取数据)

从网络上获取数据: 1.从网络上获取数据,采用如下这种方式会带来主线成阻塞现象,主线成主要是负责的是ui的交互(用户输入指令或数据,系统给一个反馈) 会进一步让ui停止交互 1)首先给我们将要下载的图片设置好位置 UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"地址"]]]; UIImageView *imageView = [[UIImageVie

Snail—iOS网络学习之得到网络上的数据

在开发项目工程中,尤其是手机APP,一般都是先把界面给搭建出来,然后再从网上down数据 来填充 那么网上的数据是怎么得来的呢,网络上的数据无非就常用的两种JSON和XML 现在 大部分都是在用JSON 网络上传输数据都是以二进制形式进行传输的 ,只要我们得到网上的二进制数据 如果它是JSON的二进制形式 那么我们就可以用JSON进行解析 如果是XML,那么我们可以用XML解析 关键是怎么得到网上的二进制数据呢 设计一个常用的工具类 很简单 给我一个接口(URL),那我就可以用这个类得到二进制文

网络上可供测试的Web Service

腾讯QQ在线状态 WEB 服务Endpoint: http://www.webxml.com.cn/webservices/qqOnlineWebService.asmx Disco: http://www.webxml.com.cn/webservices/qqOnlineWebService.asmx?discoWSDL: http://www.webxml.com.cn/webservices/qqOnlineWebService.asmx?wsdl通过输入QQ号码(String)检测QQ

网络上的各种端口

1 tcpmux TCP 端口服务多路复用 5 rje 远程作业入口 7 echo Echo 服务 9 discard 用于连接测试的空服务 11 systat 用于列举连接了的端口的系统状态 13 daytime 给请求主机发送日期和时间 17 qotd 给连接了的主机发送每日格言 18 msp 消息发送协议 19 chargen 字符生成服务:发送无止境的字符流 20 ftp-data FTP 数据端口 21 ftp 文件传输协议(FTP)端口:有时被文件服务协议(FSP)使用 22 ssh

android从网络上异步加载图像

研究了android从网络上异步加载图像: (1)由于android UI更新支持单一线程原则,所以从网络上取数据并更新到界面上,为了不阻塞主线程首先可能会想到以下方法. 在主线程中new 一个Handler对象,加载图像方法如下所示 [java] view plaincopyprint? private void loadImage(final String url, final int id) { handler.post(new Runnable() { public void run()