Overlay网络和VXLAN

1 基于多租户的云计算Overlay网络

http://www.h3c.com.cn/About_H3C/Company_Publication/IP_Lh/2013/04/Home/Catalog/201309/796466_30008_0.htm

文/刘新民

云计算已经成为当前企业IT建设的常规形态,而在云计算中大量采用和部署的虚拟化几乎成为一个基本的技术模式。

服务器虚拟化技术的广泛部署,极大增加了数据中心的计算密度,而且,因为虚拟机本身不受物理计算环境的约束,基于业务的灵活性变更要求,需要在网络中无限制地迁移到目的物理位置,(如图1所示)虚机增长的快速性以及虚机迁移成为一个常态性业务。

图1 虚拟化的快速增长及带来的密集迁移效应.jpg

图1 虚拟化的快速增长及带来的密集迁移效应

1 云计算虚拟化网络的挑战与革新

在云中,虚拟计算负载的高密度增长及灵活性迁移在一定程度上对网络产生了压力,然而当前虚拟机的规模与可迁移性受物理网络能力约束,云中的业务负载不能与物理网络脱离。

ž 虚拟机迁移范围受到网络架构限制

由于虚拟机迁移的网络属性要求,其从一个物理机上迁移到另一个物理机上,要求虚拟机不间断业务,则需要其IP地址、MAC地址等参数维保持不变,如此则要求业务网络是一个二层网络,且要求网络本身具备多路径多链路的冗余和可靠性。传统的网络生成树(STPSpaning Tree Protocol)技术不仅部署繁琐,且协议复杂,网络规模不宜过大,限制了虚拟化的网络扩展性。基于各厂家私有的的IRF/vPC等设备级的(网络N:1)虚拟化技术,虽然可以简化拓扑简化、具备高可靠性的能力,但是对于网络有强制的拓扑形状限制,在网络的规模和灵活性上有所欠缺,只适合小规模网络构建,且一般适用于数据中心内部网络。而为了大规模网络扩展的TRILL/SPB/FabricPath/VPLS等技术,虽然解决了上述技术的不足,但对网络有特殊要求,即网络中的设备均要软硬件升级而支持此类新技术,带来部署成本的上升。

ž 虚拟机规模受网络规格限制

在大二层网络环境下,数据流均需要通过明确的网络寻址以保证准确到达目的地,因此网络设备的二层地址表项大小((即MAC地址表)),成为决定了云计算环境下虚拟机的规模的上限,并且因为表项并非百分之百的有效性,使得可用的虚机数量进一步降低,特别是对于低成本的接入设备而言,因其表项一般规格较小,限制了整个云计算数据中心的虚拟机数量,但如果其地址表项设计为与核心或网关设备在同一档次,则会提升网络建设成本。虽然核心或网关设备的MAC与ARP规格会随着虚拟机增长也面临挑战,但对于此层次设备能力而言,大规格是不可避免的业务支撑要求。减小接入设备规格压力的做法可以是分离网关能力,如采用多个网关来分担虚机的终结和承载,但如此也会带来成本的上升。

ž 网络隔离/分离能力限制

当前的主流网络隔离技术为VLAN(或VPN),在大规模虚拟化环境部署会有两大限制:一是VLAN数量在标准定义中只有12个比特单位,即可用的数量为4000个左右,这样的数量级对于公有云或大型虚拟化云计算应用而言微不足道,其网络隔离与分离要求轻而易举会突破4000;二是VLAN技术当前为静态配置型技术(只有EVB/VEPA的802.1Qbg技术可以在接入层动态部署VLAN,但也主要是在交换机接主机的端口为常规部署,上行口依然为所有VLAN配置通过),这样使得整个数据中心的网络几乎为所有VLAN被允许通过(核心设备更是如此),导致任何一个VLAN的未知目的广播数据会在整网泛滥,无节制消耗网络交换能力与带宽。

对于小规模的云计算虚拟化环境,现有的网络技术如虚拟机接入感知(VEPA/802.1Qbg)、数据中心二层网络扩展(IRF/vPC/TRILL/FabricPath)、数据中心间二层技术(OTV/EVI/TRILL)等可以很好的满足业务需求,上述限制不成为瓶颈。然而,完全依赖于物理网络设备本身的技术改良,目前看来并不能完全解决大规模云计算环境下的问题,一定程度上还需要更大范围的技术革新来消除这些限制,以满足云计算虚拟化的网络能力需求。在此驱动力基础上,逐步演化出Overlay的虚拟化网络技术趋势。

2 Overlay虚拟化网络的技术标准及比较

2.1 Overlay技术形态

Overlay在网络技术领域,指的是一种网络架构上叠加的虚拟化技术模式,其大体框架是对基础网络不进行大规模修改的条件下,实现应用在网络上的承载,并能与其它网络业务分离,并且以基于IP的基础网络技术为主(如图2所示)。其实这种模式是以对传统技术的优化而形成的。早期的就有标准支持了二层Overlay技术,如RFC3378(Ethernet in IP),就是早期的在IP上的二层Overlay技术。并且基于Ethernet over GRE的技术,H3C与Cisco都在物理网络基础上发展了各自的私有二层Overlay技术——EVI(Ethernet Virtual Interconnection)与OTV(Overlay Transport Virtualization)。EVI与OTV都主要用于解决数据中心之间的二层互联与业务扩展问题,并且对于承载网络的基本要求是IP可达,部署上简单且扩展方便。

图2 Overlay网络模型.jpg

图2 Overlay网络模型

随着云计算虚拟化的驱动,基于主机虚拟化的Overlay技术出现,在服务器的Hypervisor内vSwitch上支持了基于IP的二层Overlay技术,从更靠近应用的边缘来提供网络虚拟化服务,其目的是使虚拟机的部署与业务活动脱离物理网络及其限制,使得云计算的网络形态不断完善。(如图3所示)主机的vSwitch支持基于IP的Overlay之后,虚机的二层访问直接构建在Overlay之上,物理网不再感知虚机的诸多特性,由此,Overlay可以构建在数据中心内,也可以跨越数据中心之间。

图3 hypervisor支持的二层Overlay.jpg

图3 hypervisor支持的二层Overlay

2.2 Overlay如何解决当前的主要问题

针对前文提出的三大技术挑战,Overlay在很大程度上提供了全新的解决方式。

ž 针对虚机迁移范围受到网络架构限制的解决方式

Overlay是一种封装在IP报文之上的新的数据格式,因此,这种数据可以通过路由的方式在网络中分发,而路由网络本身并无特殊网络结构限制,具备良性大规模扩展能力,并且对设备本身无特殊要求,以高性能路由转发为佳,且路由网络本身具备很强的的故障自愈能力、负载均衡能力。采用Overlay技术后,企业部署的现有网络便可用于支撑新的云计算业务,改造难度极低(除性能可能是考量因素外,技术上对于承载网络并无新的要求)。

ž 针对虚机规模受网络规格限制的解决方式

虚拟机数据封装在IP数据包中后,对网络只表现为封装后的的网络参数,即隧道端点的地址,因此,对于承载网络(特别是接入交换机),MAC地址规格需求极大降低,最低规格也就是几十个(每个端口一台物理服务器的隧道端点MAC)。当然,对于核心/网关处的设备表项(MAC/ARP)要求依然极高,当前的解决方案仍然是采用分散方式,通过多个核心/网关设备来分散表项的处理压力。(另一种更分散的方式便是虚拟网络路由服务方式,详见后文描述)。

ž 针对网络隔离/分离能力限制的解决方式

针对VLAN数量4000以内的限制,在Overlay技术中引入了类似12比特VLAN ID的用户标识,支持千万级以上的用户标识,并且在Overlay中沿袭了云计算“租户”的概念,称之为Tenant ID(租户标识),用24或64比特表示。针对VLAN技术下网络的TRUANK ALL(VLAN穿透所有设备)的问题,Overlay对网络的VLAN配置无要求,可以避免网络本身的无效流量带宽浪费,同时Overlay的二层连通基于虚机业务需求创建,在云的环境中全局可控。

2.3 Overlay主要技术标准及比较

目前,IETF在Overlay技术领域有如下三大技术路线正在讨论,为简单起见,本文只讨论基于IPv4的Overlay相关内容(如图4所示)。

ž VXLAN。VXLAN是将以太网报文封装在UDP传输层上的一种隧道转发模式,目的UDP端口号为4798;为了使VXLAN充分利用承载网络路由的均衡性,VXLAN通过将原始以太网数据头(MAC、IP、四层端口号等)的HASH值作为UDP的号;采用24比特标识二层网络分段,称为VNI(VXLAN Network Identifier),类似于VLAN ID作用;未知目的、广播、组播等网络流量均被封装为组播转发,物理网络要求支持任意源组播(ASM)。

ž NVGRE。NVGRE是将以太网报文封装在GRE内的一种隧道转发模式;采用24比特标识二层网络分段,称为VSI(Virtual Subnet Identifier),类似于VLAN ID作用;为了使NVGRE利用承载网络路由的均衡性,NVGRE在GRE扩展字段flow ID,这就要求物理网络能够识别到GRE隧道的扩展信息,并以flow ID进行流量分担;未知目的、广播、组播等网络流量均被封装为组播转发。

ž STT。STT利用了TCP的数据封装形式,但改造了TCP的传输机制,数据传输不遵循TCP状态机,而是全新定义的无状态机制,将TCP各字段意义重新定义,无需三次握手建立TCP连接,因此称为无状态TCP;以太网数据封装在无状态TCP;采用64比特Context ID标识二层网络分段;为了使STT充分利用承载网络路由的均衡性,通过将原始以太网数据头(MAC、IP、四层端口号等)的HASH值作为无状态TCP的源端口号;未知目的、广播、组播等网络流量均被封装为组播转发。

 

图片7图片8图片9

VXLAN NVGRE SST

图4 三种数据详细封装

这三种二层Overlay技术,大体思路均是将以太网报文承载到某种隧道层面,差异性在于选择和构造隧道的不同,而底层均是IP转发。如表1所示为这三种技术关键特性的比较:VXLAN和STT对于现网设备对流量均衡要求较低,即负载链路负载分担适应性好,一般的网络设备都能对L2-L4的数据内容参数进行链路聚合或等价路由的流量均衡,而NVGRE则需要网络设备对GRE扩展头感知并对flow ID进行HASH,需要硬件升级;STT对于TCP有较大修改,隧道模式接近UDP性质,隧道构造技术属于革新性,且复杂度较高,而VXLAN利用了现有通用的UDP传输,成熟性极高。总体比较,VLXAN技术相对具有优势。

表1 IETF三种Overlay技术的总体比较.jpg

表1 IETF三种Overlay技术的总体比较

IETF讨论的Overlay技术,主要聚焦在数据转发层面的实现上,控制层面并无涉及,因此在基本实现上依赖于不同厂家的控制层面设计,IETF讨论稿《draft-pfaff-ovsdb-proto-02.pdf》则针对Open vSwitch提供了一种控制管理模型的建议(如图5所示),但在细节实现上仍不是很明确。

图5 IETF draft讨论的OVS管理方式

3 多租户的Overlay网络架构

3.1 数据中心虚拟化网络的发展阶段

随着虚拟化技术在数据中心、云计算中的不断深入应用,伴随着网络技术的发展,数据中心的二层组网结构出现了阶段性的架构变化(如图6所示)。

图6 阶段性网络与虚拟化的匹配.jpg

图6 阶段性网络与虚拟化的匹配

ž 分层结构化网络

早期的数据中心网络,虚拟化需求非常少,并没有强烈的大二层技术要求,多是面向一定的业务应用系统构建网络模块,并且规模一般不大,性能要求也不高。数据中心使用多层架构,网关层面比较低,业务的二层访问基本可以在网络模块内解决,只需要通过基础的生成树技术来支撑模块内的二层网路可靠性运行即可。

ž 扁平化网络

随着虚拟化在X86架构服务器上的流行及广泛部署,模块化的数据中心网络结构已经不能满足虚拟机大范围迁移要求,而生成树协议的复杂性也严重影响大规模网络的稳定运行。由此网络本身技术出现适应虚拟化的变革,包含TRILL/FabricPath/VSS/vPC/IRF等新的技术出现并大量部署,同时为了使得网络进一步感知虚让你因为机的业务生命周期,IEEE还制订了802.1Qbg(即VEPA技术)与802.1BR来配合二层网络技术增强对虚拟机的感知能力。为了保证网络的高性能业务要求,出现了应对高密虚拟化云计算环境的CLOS网络架构。

ž Overlay网络虚拟化

当进入云计算时代,云的业务需求与网络之间出现了前文提到的挑战,网络技术再次发生变革,以Overlay的虚拟化方式来支撑云与虚拟化的建设要求,并实现大规模的多租户能力,网络进入Overlay虚拟化架构阶段。

3.2 Overlay网络的组成模式

Overlay的本质是L2 Over IP的隧道技术,在服务器的vSwitch、物理网络上技术框架已经就绪,并且从当前的技术选择来看,虽然有多种隧道同时实现,但是以L2 over UDP模式实现的VXLAN技术具备较大优势,并且在ESXi和Open vSwitch、当前网络的主流芯片已经实现,预计会成为主流的Overlay技术选择,因此后文的Overlay网络均参考VXLAN相关的技术组成描述,其它NVGRE、STT等均类似。

Overlay网络架构有多种实现,就纯大二层的实现,可分为主机实现方式和网络实现方式;而在最终实现Overlay与网络外部数据连通的连接方式上,则更有多种实现模式,并且对于关键网络部件将有不同的技术要求。

3.2.1 基于主机的Overlay虚拟化网络

(如图7所示)目前的虚拟化主机软件在vSwitch内支持VXLAN,使用VTEP(VXLAN Tunnel End Point)封装和终结VXLAN的隧道。

图7 基于主机的Overlay虚拟化网络.jpg

图7 基于主机的Overlay虚拟化网络

VXLAN运行在UDP上,物理网络只要支持IP转发,则所有IP可达的主机即可构建一个大范围二层网络。这种vSwitch的实现,屏蔽了物理网络的模型与拓扑差异,将物理网络的技术实现与计算虚拟化的关键要求分离开来,几乎可以支持以太网在任意网络上的透传,使得云的计算资源调度范围空前扩大。

特别的,为了使得VXLAN Overlay网络更加简化运行管理,便于云的服务提供,各厂家使用集中控制的模型,将分散在多个物理服务器上的vSwitch构成一个大型的、虚拟化的分布式Overlay vSwitch(如图8所示),只要在分布式vSwitch范围内,虚拟机在不同物理服务器上的迁移,便被视为在一个虚拟的设备上迁移,如此大大降低了云中资源的调度难度和复杂度。

图8 分布式Overlay vSwitch.jpg

图8 分布式Overlay vSwitch

基于主机的Overlay网络数据流量出入物理网络,需要实现VXLAN的Overlay流量与传统的以太网数据流量之间的封装与解封装过程,而执行这个过程操作的功能点,被称为Overlay/VXLAN Gateway(如图9所示)。因为VXLAN网络的VTEP功能点本身就是VXLAN的封装与解封装隧道点,因此VXLAN Gateway首先需要具备VTEP功能,形态可以是vSwitch、物理交换机等,只是对于网络中的虚机或其它设备地址表项的处理有所差异。

图9 Overlay Gateway(VXLAN).jpg

图9 Overlay Gateway(VXLAN)

VXLAN Ovelay网络与物理网络连通有以下三种组网方案(如图10所示)。

ž 方案一:Overlay虚拟化网络+vSwitch GW+vRouter

Overlay的vSwitch本身具备隧道的封装与解封装能力,因此,H3C提供一种虚拟路由器来配合这种基本方式。将在硬件路由器中运行的软件vSR(基于H3C Comware平台的路由软件包)作为虚拟机运行在主机中,提供Overlay网络的虚拟路由功能(即vRouter能力),vRouter的接口同时连接到VXLAN的网络和VLAN基本功能的物理网络。从vSwitch接收到的VXLAN数据包被解除封装后,进入vRouter路由接口,可以被路由到外部网络;反之,vRouter接收到外部网络的数据可以进入VXLAN网络。

该方案的好处是:涉及Overlay的功能均在主机虚拟化环境vSwitch实现,并且虚拟路由功能使得Overlay网络部署更加灵活,极大降低外部物理网络要求。

ž 方案二:Overlay虚拟化网络+vSwitch GW+pRouter

本方案使用服务器中的vSwitch专门用作VXLAN的Gateway功能,而数据的路由功能,则由外部网络物理路由器承担。该方案除了不具备虚拟路由能力,Overlay的功能也都在主机虚拟化环境vSwitch实现,同时可以支持虚机与非虚拟化的物理服务器之间的二层数据通信要求。

ž 方案三:Overlay虚拟化网络+pSwitch GW+pRouter

当物理交换机支持VXLAN功能,则pSwitch与vSwicth可以实现Overlay的统一虚拟化组网,物理交换机执行VXLAN Gateway功能,不仅可以实现Overlay网络在物理网络上的终结,也可以支持虚机与非虚拟化服务器的混合组网业务,因为基于物理实现(物理交换机+物理路由器),整体网络可以达到极高性能。

图10 VXLAN Overlay网络与物理网络的连通方案.jpg

图10 VXLAN Overlay网络与物理网络的连通方案

 

3.2.2 基于物理网络的Overlay虚拟化

(如图11所示)该方案在网络架构上与TRILL/FabricPath等技术类似,但是因为对于非VTEP要求的网络只需要IP转发,它比TRILL/FabricPath构建的成本更低,技术要求也更加简单,同时也容易构建多个数据中心之间的网络连接。

为了解决网络对虚拟机的感知与自动化控制,结合IEEE的802.1Qbg/VEPA技术,可以使得网络的Overlay与计算虚拟化之间产生关联,这样既可以保持服务器内部网络的简化,使用基本的VEPA,利用外部网络强化来保证高能力的控制要求,又在物理网络Overlay的虚拟化基础上增强了虚机在云中大范围调度的灵活性。

图11 物理网络的Overlay+VEPA.jpg

图11 物理网络的Overlay+VEPA

3.3 基于Overlay网络的多租户与网络服务——H3Cloud云网融合路线

对于计算资源丰富的数据中心,Overlay网络使得虚拟机不再为物理网络所限制,但是对于网络的L4-L7深度服务,在云计算环境下需求更为强烈,资源动态调度的计算环境,需要动态可调度的网络服务支撑。因此将传统的L4-L7服务转换为可云化的、可动态调度的服务资源,成为Overlay网络环境下的必须集成框架(如图12所示)。H3C基于Comware V7软件平台的L4-L7产品系列,可在虚拟化网络环境下资源化,以虚拟服务单元运行,分别提供对应路由器、防火墙、负载均衡、深度防御的vSR/vRouter、vFW、vLB、vIPS,利用数据中心计算资源与Overlay网络集成,提供等同于传统的L4-L7网络服务能力。

图12 Overlay网络集成服务虚拟化.jpg

图12 Overlay网络集成服务虚拟化

在Overlay环境下的虚拟化网络服务,必须具备灵活的可分配性、可扩展性及可调度性,因此,自动化的编排组织能力显得非常重要(如图13所示)。除了将虚拟服务资源化,还要具备业务逻辑的组合关联,这些与物理网络L4-L7服务的固定配置管理不同,所有的网络服务资源也是在计算池中,要实现相应的业务关联和逻辑,难以通过物理网络实现,在Overlay网络的连通与编排下则相对易于实现。这种集成思路也将是H3C服务虚拟化的主要模式。

图13 基于Overlay虚拟化网络的服务编排.jpg

图13 基于Overlay虚拟化网络的服务编排

H3C云计算解决方案核心的架构是云网融合。在当前的特色方案系列均充分利用了云计算与物理网络融合、结合的特点,如:

ž VEPA——提供网络计算自动化的感知关联与自动化部署;

ž FCoE——统一交换的计算、存储网络;

ž DRX——基于H3C LB与虚拟机管理平台关联的虚机资源动态扩展;

ž PoC(Point of Cloud)——借助云端网络连通云计算中心与路由器集成X86虚拟化计算部件的统一云分支扩展;

ž 分级云——通过层级化网络构建纵向层次化云架构。

针对云计算即将进入Overlay阶段,H3C的技术路线目标是在H3Cloud架构中进一步实现Overlay虚拟化网络的融合(如图14所示)。新一阶段的云网融合,不仅包含分布式的Overlay、多租户的虚拟化网络,还将不断集成逐步产品化的虚拟网络服务部件(目前已经可提供vSR/vFW的服务部件),而对于原有的VEPA/FCoE/DRX/PoC/分级云等方案,将在基于Overlay的虚拟化网络架构下重新构建和集成,实现技术演进和延续的完整性。

图14 云网融合:H3Cloud从物理网络到Overlay虚拟网络的集成.jpg

图14 云网融合:H3Cloud从物理网络到Overlay虚拟网络的集成

4 结束语

Overlay的网络架构是物理网络向云和虚拟化的深度延伸,云的资源化能力可以脱离物理网络的多种限制,但两个网络本身却是需要连通交互才能实现云的服务能力,随着技术的发展,主机的Overlay技术也将向硬件化发展,并逐步会成为物理网络的一部分。但Overlay尚没有深度成熟,还需要较长时间发展和应用,其中的问题会逐步暴露和解决。

 

 

2 Vxlan基础理解

一 . 为什么需要Vxlan
 
1. vlan的数量限制
   4096个vlan远不能满足大规模云计算数据中心的需求
 
2. 物理网络基础设施的限制
   基于IP子网的区域划分限制了需要二层网络连通性的应用负载的部署
 
3. TOR交换机MAC表耗尽
    虚拟化以及东西向流量导致更多的MAC表项
 
4. 多租户场景
    IP地址重叠?
二. 什么是Vxlan
 
1. Vxlan报文
    vxlan(virtual Extensible LAN)虚拟可扩展局域网,是一种overlay的网络技术,使用MAC in UDP的方法进
行封装,共50字节的封装报文头。具体的报文格式如下:

 
(1) vxlan header
    共计8个字节,目前使用的是Flags中的一个8bit的标识位和24bit的VNI(Vxlan Network identifier),
其余部分没有定义,但是在使用的时候必须设置为0x0000。
 
(2) 外层的UDP报头
     目的端口使用4798,但是可以根据需要进行修改。同事UDP的校验和必须设置成全0。
 
(3) IP报文头
     目的IP地址可以是单播地址,也可以是多播地址。单播情况下,目的IP地址是Vxlan Tunnel End Point
(VTEP)的IP地址。在多播情况下引入VXLAN管理层,利用VNI和IP多播组的映射来确定VTEPs。???
  • protocol:设置值为0x11,显示说明这是UDP数据包
  • Source ip: 源vTEP_IP;
  • Destination ip: 目的VTEP IP。
(4) Ethernet Header
  • Destination Address:目的VTEP的Mac 地址,即为本地下一跳的地址(通常是网关Mac 地址);
  • VLAN: VLAN Type被设置为0x8100, 并可以设置Vlan Id tag(这就是vxlan的vlan 标签)。
  • Ethertype:设置值为0x8000,指明数据包为IPv4的。
补充:VTEP的作用?    
     用于对VXLAN报文进行封装/解封装,包括ARP请求报文和正常的VXLAN数据报文,在一段封装报文
后通过隧道向另一端VTEP发送封装报文,另一端VTEP接收到封装的报文解封装后根据封装的MAC地址
进行装法。VTEP可由支持VXLAN的硬件设备或软件来实现。
 
   从封装的结构上来看,VXLAN提供了将二层网络overlay在三层网络上的能力,VXLAN Header中的VNI有
24个bit,数量远远大于4096,并且UDP的封装可以穿越三层网络,比VLAN有更好的扩展性。
 
2. Vxlan的数据和控制平面
  (1) 数据平面---隧道机制
     已经知道,VTEP为虚拟机的数据包加上了层包头,这些新的报头之有在数据到达目的VTEP后才会被去掉。
中间路径的网络设备只会根据外层包头内的目的地址进行数据转发,对于转发路径上的网络来说,一个Vxlan
数据包跟一个普通IP包相比,出了个头大一点外没有区别。
     由于VXLAN的数据包在整个转发过程中保持了内部数据的完整,因此VXLAN的数据平面是一个基于隧道
的数据平面。
 
(2) 控制平面----改进的二层协议
     VXLAN不会在虚拟机之间维持一个长连接,所以VXLAN需要一个控制平面来记录对端地址可达情况。控制
平面的表为(VNI,内层MAC,外层vtep_ip)。Vxlan学习地址的时候仍然保存着二层协议的特征,节点之间不会
周期性的交换各自的路由表,对于不认识的MAC地址,VXLAN依靠组播来获取路径信息(如果有SDN Controller,
可以向SDN单播获取)。
    另一方面,VXLAN还有自学习的功能,当VTEP收到一个UDP数据报后,会检查自己是否收到过这个虚拟机的
数据,如果没有,VTEP就会记录源vni/源外层ip/源内层mac对应关系,避免组播学习。
 
 
3. VxlanARP请求
 
(1) vxlan初始化
 
 VM1和VM2连接到VXLAN网络(VNI)100,两个VXLAN主机加入IP多播组239.119.1.1
 
(2) ARP请求
 
   1) VM1以广播的形式发送ARP请求;
   2) VTEP1封装报文。打上VXLAN标识为100,外层IP头DA为IP多播组(239.119.1.1),SA为IP_VTEP1.
   3) VTEP1在多播组内进行多播;
   4) VTEP2解析接收到多播报文。填写流表(VNI, 内层mac地址,外层Ip地址),并在本地VXLAN标识为100的范围内
       广播(是VXLAN的用武之地)。
   5) VM2对接收到的ARP请求进行响应;
 
(3) ARP应答

  1) VM2准备ARP响应报文后向VM1发送响应报文

       2)VTEP2接收到VM2的响应报文后把它封装在ip单播报文中(VXLAN标识依然为100),然 后向VM1发送单播

       3)VTEP1接收到单播报文后,学习内层MAC到外层ip地址的映射,解封装并根据被封装内容的目的MAC地址转发给VM1

       4)VM1接收到ARP应答报文,ARP交互结束
 
4  数据传输
    (1)  ARP请求应答之后,VM1知道了VM2的Mac地址,并且要向VM2通信(注意,VM1是以TCP的方法向VM2发送数据的)。
VTEP1 收到VM1发送数据包,用MAC地址从流表中检查VM1与VM2是否属于用一个VNI。两个VM不但位于同一个VNI中
(不在同一个VNI中出网关),并且VTEP1已经知道了VM2的所有地址信息(MAC和VTEP2_IP)。VTEP1封装新的数据包。然后
交给上联交换机。
   (2) 上联交换机收到服务器发来的UDP包,对比目的IP地址和自己的路由表,然后将数据报转发给相应的端口。
   (3) 目的VTEP收到数据包后检查器VNI,如果UDP报中VNI与VM2的VNI一致,则将数据包解封装后交给VM2进一步处理。至此
一个数据包传输完成。整个Vxlan相关的行为(可能穿越多个网关)对虚拟机来说是透明的,虚拟机不会感受传输的过程。
 
    虽然VM1与VM2之间启动了TCP来传输数据,但数据包一路上实际是以UDP的形式被转发,两端的VTEP并不会检查数据是否
正确或者顺序是否完整,所有的这些工作都是在VM1和VM2在接收到解封装的TCP包后完成的。也就是说如果说如果被UDP封装
的是TCP连接,那么UDP和TCP将做为两个独立的协议栈各自工作,相互之间没有交互。
    
5 Vxlan网关
 如果需要VXLAN网络和非VXLAN网络连接,必须使用VXLAN网关才能把VXLAN网络和外部网络进行桥接和
完成VXLAN ID和VLAN ID之间的映射和路由,和VLAN一样,VXLAN网络之间的通信也需要三层设备的支持,
即VXLAN路由的支持。同样VXLAN网关可由硬件和软件来实现。
 
 从封装的结构上来看,VXLAN提供了将二层网络overlay在三层网络上的能力,VXLAN Header中的VNI有
24个bit,数量远远大于4096,并且UDP的封装可以穿越三层网络,比VLAN有更好的扩展性。
 
6.部署
(1) 纯VXLAN部署场景
  对于连接到VXLAN内的虚拟机,由于虚拟机的VLAN信息不再作为转发的依据,虚拟机的迁移也就
不再受三层网关的限制,可以实现跨越三层网关的迁移。
 
 
(2) VXLAN与VLAN混合部署
 
   为了实现VLAN和VXLAN之间互通,VXLAN定义了VXLAN网关。VXLAN网关上同时存在两种类型的端口:VXLAN端口
和普通端口。
   当收到从VXLAN网络到普通网络的数据时,VXLAN网关去掉外层包头,根据内层的原始帧头转发到普通端口上;当有数据
从普通网络进入到VXLAN网络时,VXLAN网关负责打上外层包头,并根据原始VLAN ID对应到一个VNI,同时去掉内层包头
的VLAN ID信息。相应的如果VXLAN网关发现一个VXLAN包的内层帧头上还带有原始的二层VLAN ID,会直接将这个包丢弃。
之所以这样,是VLAN ID是一个本地信息,仅仅在一个地方的二层网络上其作用,VXLAN是隧道机制,并不依赖VLAN ID进行
转发,也无法检查VLAN ID正确与否。因此,VXLAN网关连接传统网络的端口必须配置ACCESS口,不能启用TRUNK口。

 

 

3 overlay网络技术之VXLAN详解

 

 

作为网络虚拟化的重要技术,VXLAN备受关注,该协议是如何运作的?如何通过数据与控制层面的分离实现SDN网络?如何部署?本博文将为您详细介绍...

 

一 . 为什么需要Vxlan

1. vlan的数量限制

4096个vlan远不能满足大规模云计算数据中心的需求

2. 物理网络基础设施的限制

基于IP子网的区域划分限制了需要二层网络连通性的应用负载的部署

3. TOR交换机MAC表耗尽

虚拟化以及东西向流量导致更多的MAC表项

4. 多租户场景

IP地址重叠?

二. 什么是Vxlan

1. Vxlan报文

vxlan(virtual Extensible LAN)虚拟可扩展局域网,是一种overlay的网络技术,使用MAC in UDP的方法进行封装,共50字节的封装报文头。具体的报文格式如下:

(1) vxlan header

共计8个字节,目前使用的是Flags中的一个8bit的标识位和24bit的VNI(Vxlan Network identifier),其余部分没有定义,但是在使用的时候必须设置为0x0000。

(2) 外层的UDP报头

目的端口使用4798,但是可以根据需要进行修改。同事UDP的校验和必须设置成全0。

(3) IP报文头

目的IP地址可以是单播地址,也可以是多播地址。单播情况下,目的IP地址是Vxlan Tunnel End Point(VTEP)的IP地址。在多播情况下引入VXLAN管理层,利用VNI和IP多播组的映射来确定VTEPs。

protocol:设置值为0x11,显示说明这是UDP数据包

Source ip: 源vTEP_IP;

Destination ip: 目的VTEP IP。

(4) Ethernet Header

Destination Address:目的VTEP的Mac 地址,即为本地下一跳的地址(通常是网关Mac 地址);

VLAN: VLAN Type被设置为0x8100, 并可以设置Vlan Id tag(这就是vxlan的vlan 标签)。

Ethertype:设置值为0x8000,指明数据包为IPv4的。

补充:VTEP的作用?

用于对VXLAN报文进行封装/解封装,包括ARP请求报文和正常的VXLAN数据报文,在一段封装报文后通过隧道向另一端VTEP发送封装报文,另一端VTEP接收到封装的报文解封装后根据封装的MAC地址进行装法。VTEP可由支持VXLAN的硬件设备或软件来实现。

从封装的结构上来看,VXLAN提供了将二层网络overlay在三层网络上的能力,VXLAN Header中的VNI有24个bit,数量远远大于4096,并且UDP的封装可以穿越三层网络,比VLAN有更好的扩展性。

2. Vxlan的数据和控制平面

(1) 数据平面---隧道机制

已经知道,VTEP为虚拟机的数据包加上了层包头,这些新的报头之有在数据到达目的VTEP后才会被去掉。中间路径的网络设备只会根据外层包头内的目的地址进行数据转发,对于转发路径上的网络来说,一个Vxlan数据包跟一个普通IP包相比,出了个头大一点外没有区别。

由于VXLAN的数据包在整个转发过程中保持了内部数据的完整,因此VXLAN的数据平面是一个基于隧道的数据平面。

(2) 控制平面----改进的二层协议

VXLAN不会在虚拟机之间维持一个长连接,所以VXLAN需要一个控制平面来记录对端地址可达情况。控制平面的表为(VNI,内层MAC,外层vtep_ip)。Vxlan学习地址的时候仍然保存着二层协议的特征,节点之间不会周期性的交换各自的路由表,对于不认识的MAC地址,VXLAN依靠组播来获取路径信息(如果有SDN Controller,可以向SDN单播获取)。

另一方面,VXLAN还有自学习的功能,当VTEP收到一个UDP数据报后,会检查自己是否收到过这个虚拟机的数据,如果没有,VTEP就会记录源vni/源外层ip/源内层mac对应关系,避免组播学习。

三. VxlanARP请求

(1) vxlan初始化

VM1和VM2连接到VXLAN网络(VNI)100,两个VXLAN主机加入IP多播组239.119.1.1

(2) ARP请求

1) VM1以广播的形式发送ARP请求;

2) VTEP1封装报文。打上VXLAN标识为100,外层IP头DA为IP多播组(239.119.1.1),SA为IP_VTEP1.

3) VTEP1在多播组内进行多播;

4) VTEP2解析接收到多播报文。填写流表(VNI, 内层mac地址,外层Ip地址),并在本地VXLAN标识为100的范围内

广播(是VXLAN的用武之地)。

5) VM2对接收到的ARP请求进行响应;

(3) ARP应答

1) VM2准备ARP响应报文后向VM1发送响应报文

2)VTEP2接收到VM2的响应报文后把它封装在ip单播报文中(VXLAN标识依然为100),然 后向VM1发送单播

3)VTEP1接收到单播报文后,学习内层MAC到外层ip地址的映射,解封装并根据被封装内容的目的MAC地址转发给VM1

4)VM1接收到ARP应答报文,ARP交互结束

四:数据传输

(1) ARP请求应答之后,VM1知道了VM2的Mac地址,并且要向VM2通信(注意,VM1是以TCP的方法向VM2发送数据的)。

VTEP1 收到VM1发送数据包,用MAC地址从流表中检查VM1与VM2是否属于用一个VNI。两个VM不但位于同一个VNI中(不在同一个VNI中出网关),并且VTEP1已经知道了VM2的所有地址信息(MAC和VTEP2_IP)。VTEP1封装新的数据包。然后交给上联交换机。

(2) 上联交换机收到服务器发来的UDP包,对比目的IP地址和自己的路由表,然后将数据报转发给相应的端口。

(3) 目的VTEP收到数据包后检查器VNI,如果UDP报中VNI与VM2的VNI一致,则将数据包解封装后交给VM2进一步处理。至此一个数据包传输完成。整个Vxlan相关的行为(可能穿越多个网关)对虚拟机来说是透明的,虚拟机不会感受传输的过程。虽然VM1与VM2之间启动了TCP来传输数据,但数据包一路上实际是以UDP的形式被转发,两端的VTEP并不会检查数据是否正确或者顺序是否完整,所有的这些工作都是在VM1和VM2在接收到解封装的TCP包后完成的。也就是说如果说如果被UDP封装的是TCP连接,那么UDP和TCP将做为两个独立的协议栈各自工作,相互之间没有交互。

五:Vxlan网关

如果需要VXLAN网络和非VXLAN网络连接,必须使用VXLAN网关才能把VXLAN网络和外部网络进行桥接和完成VXLAN ID和VLAN ID之间的映射和路由,和VLAN一样,VXLAN网络之间的通信也需要三层设备的支持,即VXLAN路由的支持。同样VXLAN网关可由硬件和软件来实现。从封装的结构上来看,VXLAN提供了将二层网络overlay在三层网络上的能力,VXLAN Header中的VNI有24个bit,数量远远大于4096,并且UDP的封装可以穿越三层网络,比VLAN有更好的扩展性。

六.部署

(1) 纯VXLAN部署场景

对于连接到VXLAN内的虚拟机,由于虚拟机的VLAN信息不再作为转发的依据,虚拟机的迁移也就不再受三层网关的限制,可以实现跨越三层网关的迁移。

(2) VXLAN与VLAN混合部署

为了实现VLAN和VXLAN之间互通,VXLAN定义了VXLAN网关。VXLAN网关上同时存在两种类型的端口:VXLAN端口和普通端口。

当收到从VXLAN网络到普通网络的数据时,VXLAN网关去掉外层包头,根据内层的原始帧头转发到普通端口上;当有数据从普通网络进入到VXLAN网络时,VXLAN网关负责打上外层包头,并根据原始VLAN ID对应到一个VNI,同时去掉内层包头的VLAN ID信息。相应的如果VXLAN网关发现一个VXLAN包的内层帧头上还带有原始的二层VLAN ID,会直接将这个包丢弃。

之所以这样,是VLAN ID是一个本地信息,仅仅在一个地方的二层网络上其作用,VXLAN是隧道机制,并不依赖VLAN ID进行转发,也无法检查VLAN ID正确与否。因此,VXLAN网关连接传统网络的端口必须配置ACCESS口,不能启用TRUNK口。

 

原文链接:http://blog.csdn.net/freezgw1985/article/details/16354897

 

 

 

4 深入理解 VXLAN

 

VXLAN 是非常新的一个 tunnel 技术,它是一个 L2 tunnel。Linux 内核的 upstream 中也刚刚加入 VXLAN 的实现。相比 GRE tunnel 它有着很的扩展性,同时解决了很多其它问题。

一,GRE tunnel 的不足

网络很多介绍 VXLAN 的文章都没有直接告诉你相比较 GRE tunnel,VXLAN 的优势在哪里,或者说 GRE tunnel 的不足在哪里。为了更好的了解 VXLAN,我们有必要看一下 GRE tunnel 的不足。

在我前面写的介绍 GRE tunnel 的文章中,其实并不容易看出 GRE tunnel 的不足之处。根本原因是图中给出的例子不太好,只有两个网络的话 GRE tunnel 的不足凸显不出来,让我们看看有三个网络的情况如何用 GRE tunnel 互联,如下图所示:

这下子就很明显了,要让这三个网络互联,我们需要建立三个 GRE tunnel。如果网络数量再增长,那么需要的 tunnel 数量更多。换句话说,GRE tunnel 的扩展性太差,从根本上讲还是因为它只是一个 point to point 的 tunnel。

二,VLAN 的不足

其实 VLAN 在某种程度上也可以看作一个 L2 over L2 的 tunnel,只不过它多了一个新的 VLAN header,这其中有12 bit 是 VLAN tag。所以 VLAN 的第一个不足之处就是它最多只支持 4096 个 VLAN 网络(当然这还要除去几个预留的),对于大型数据中心的来说,这个数量是远远不够的。

第二个不足就是,VLAN 这个所谓的 tunnel 是基于 L2 的,所以很难跨越 L2 的边界,在很大程度上限制了网络的灵活性。同时,VLAN 操作需手工介入较多,这对于管理成千上万台机器的管理员来说是难以接受的。

三,VXLAN 的引入

VXLAN 是 Virtual eXtensible LANs 的缩写,所以顾名思义,它是对 VLAN 的一个扩展,但又不仅限于此。

从数量上讲,它确实把 12 bit 的 VLAN tag 扩展成了 24 bit,所以至少暂时够用的了。从实现上讲,它是 L2 over UDP,它利用了 UDP 同时也是 IPv4 的单播和多播,可以跨 L3 边界,很巧妙地解决了 GRE tunnel 和 VLAN 存在的不足,让组网变得更加灵活。

四,VXLAN 的实现

VXLAN 的配置可以参考内核文档 Documentation/networking/vxlan.txt,本人目前还没有环境测试,所以只能做一些代码分析了。

Linux 内核中对 VXLAN 的实现是在 drivers/net/vxlan.c 源文件中,是由 Stephen Hemminger (iproute2 的维护者)完成的。代码质量相当高,所以可读性也很好,强烈推荐阅读一下。

看代码之前先看 VXLAN 的头是一个怎样的结构,如下图所示(图片来自参考资料4):

好了,现在我们可以看代码了。先看发送端,vxlan_xmit() 函数。首先需要说的是发送之前内核会检查目的地址,如果是L2 multicast,那么应该发送到 VXLAN group 组播地址,否则,如果 MAC 地址是已知的,直接单播到对应的 IP;如果未知,则广播到组播地址。代码如下,比文档还要好读。:-)

C:
  1. static __be32 vxlan_find_dst (  struct vxlan_dev  * vxlan,  struct sk_buff  * skb )
  2. {
  3.          const  struct ethhdr  * eth  = (  struct ethhdr  * ) skb  - >data;
  4.          const  struct vxlan_fdb  * f;
  5.  
  6.         if ( is_multicast_ether_addr ( eth  - >h_dest ) )
  7.                 return vxlan  - >gaddr;
  8.  
  9.         f  = vxlan_find_mac ( vxlan, eth  - >h_dest ) ;
  10.         if ( f )
  11.                 return f  - >remote_ip;
  12.         else
  13.                 return vxlan  - >gaddr;
  14.  
  15. }

 

剩下的基本上就是一层一层的往外添加头了,依次添加 VXLAN header,UDP header,IP header:

C:
  1. //...
  2.         vxh  = (  struct vxlanhdr  * ) __skb_push ( skb,  sizeof (  * vxh ) ) ;
  3.         vxh  - >vx_flags  = htonl ( VXLAN_FLAGS ) ;
  4.         vxh  - >vx_vni  = htonl ( vxlan  - >vni << 8 ) ;
  5.  
  6.         __skb_push ( skb,  sizeof (  * uh ) ) ;
  7.         skb_reset_transport_header ( skb ) ;
  8.         uh  = udp_hdr ( skb ) ;
  9.  
  10.         uh  - >dest  = htons ( vxlan_port ) ;
  11.         uh  - >source  = htons ( src_port ) ;
  12.  
  13.         uh  - >len  = htons ( skb  - >len ) ;
  14.         uh  - >check  = 0 ;
  15.  
  16.         __skb_push ( skb,  sizeof (  * iph ) ) ;
  17.         skb_reset_network_header ( skb ) ;
  18.         iph              = ip_hdr ( skb ) ;
  19.         iph  - >version      = 4 ;
  20.         iph  - >ihl          =  sizeof (  struct iphdr ) >> 2 ;
  21.         iph  - >frag_off    = df;
  22.         iph  - >protocol    = IPPROTO_UDP;
  23.         iph  - >tos          = vxlan_ecn_encap ( tos, old_iph, skb) ;
  24.         iph  - >daddr        = dst;
  25.         iph  - >saddr        = fl4.  saddr ;
  26.         iph  - >ttl          = ttl ?  : ip4_dst_hoplimit (  & rt  - >dst ) ;
  27.  
  28.         vxlan_set_owner ( dev, skb ) ;

 

正如 GRE tunnel,比较复杂的地方是在接收端。因为 VXLAN 利用了 UDP,所以它在接收的时候势必需要有一个 UDP server 在监听某个端口,这个是在 VXLAN 初始化的时候完成的,即 vxlan_init_net() 函数:

C:
  1. static __net_init  int vxlan_init_net (  struct net  * net )
  2. {
  3.      struct vxlan_net  * vn  = net_generic ( net, vxlan_net_id ) ;
  4.      struct sock  * sk;
  5.      struct sockaddr_in vxlan_addr  = {
  6.         .  sin_family  = AF_INET,
  7.         .  sin_addr .  s_addr  = htonl ( INADDR_ANY ) ,
  8.     } ;
  9.      int rc;
  10.      unsigned h;
  11.  
  12.      /* Create UDP socket for encapsulation receive. */
  13.     rc  = sock_create_kern ( AF_INET, SOCK_DGRAM, IPPROTO_UDP,  & vn - >sock ) ;
  14.     if ( rc < 0 ) {
  15.         pr_debug ( "UDP socket create failed  \n ") ;
  16.         return rc;
  17.     }
  18.      /* Put in proper namespace */
  19.     sk  = vn  - >sock  - >sk;
  20.     sk_change_net ( sk, net ) ;
  21.  
  22.     vxlan_addr.  sin_port  = htons ( vxlan_port ) ;
  23.  
  24.     rc  = kernel_bind ( vn  - >sock, (  struct sockaddr  * )  & vxlan_addr,
  25.                sizeof ( vxlan_addr ) ) ;
  26.     if ( rc < 0 ) {
  27.         pr_debug ( "bind for UDP socket %pI4:%u (%d)  \n " ,
  28.                & vxlan_addr.  sin_addr , ntohs ( vxlan_addr.  sin_port ) , rc ) ;
  29.         sk_release_kernel ( sk ) ;
  30.         vn  - >sock  =  NULL ;
  31.         return rc;
  32.     }
  33.  
  34.      /* Disable multicast loopback */
  35.     inet_sk ( sk )  - >mc_loop  = 0 ;
  36.  
  37.      /* Mark socket as an encapsulation socket. */
  38.     udp_sk ( sk )  - >encap_type  = 1 ;
  39.     udp_sk ( sk )  - >encap_rcv  = vxlan_udp_encap_recv;
  40.     udp_encap_enable ( ) ;
  41.  
  42.     for ( h  = 0 ; h <VNI_HASH_SIZE;  ++ h )
  43.         INIT_HLIST_HEAD (  & vn  - >vni_list [ h ] ) ;
  44.  
  45.     return 0 ;
  46. }

 

由此可见内核内部创建 socket 的 API 是sock_create_kern(),bind() 对应的是 kernel_bind()。注意到这里实现了一个hook,vxlan_udp_encap_recv(),这个正是接收端的主要代码。

发送端是一层一层往外填,那么接收端一定就是一层一层外里剥:

C:
  1. /* pop off outer UDP header */
  2.     __skb_pull ( skb,  sizeof (  struct udphdr ) ) ;
  3.  
  4.      /* Need Vxlan and inner Ethernet header to be present */
  5.     if (  ! pskb_may_pull ( skb,  sizeof (  struct vxlanhdr ) ) )
  6.         goto error;
  7.  
  8.      /* Drop packets with reserved bits set */
  9.     vxh  = (  struct vxlanhdr  * ) skb  - >data;
  10.     if ( vxh  - >vx_flags  != htonl ( VXLAN_FLAGS ) ||
  11.         ( vxh  - >vx_vni  & htonl ( 0xff ) ) ) {
  12.         netdev_dbg ( skb  - >dev, "invalid vxlan flags=%#x vni=%#x  \n " ,
  13.                ntohl ( vxh  - >vx_flags ) , ntohl ( vxh  - >vx_vni ) ) ;
  14.         goto error;
  15.     }
  16.  
  17.     __skb_pull ( skb,  sizeof (  struct vxlanhdr ) ) ;
  18.  
  19.      /* Is this VNI defined? */
  20.     vni  = ntohl ( vxh  - >vx_vni ) >> 8 ;
  21.     vxlan  = vxlan_find_vni ( sock_net ( sk ) , vni ) ;
  22.     if (  ! vxlan ) {
  23.         netdev_dbg ( skb  - >dev, "unknown vni %d  \n " , vni ) ;
  24.         goto drop;
  25.     }
  26.  
  27.     if (  ! pskb_may_pull ( skb, ETH_HLEN ) ) {
  28.         vxlan  - >dev  - >stats.  rx_length_errors  ++ ;
  29.         vxlan  - >dev  - >stats.  rx_errors  ++ ;
  30.         goto drop;
  31.     }

 

在重新入栈之前还要做一些准备工作:

C:
  1. /* Re-examine inner Ethernet packet */
  2.     oip  = ip_hdr ( skb ) ;
  3.     skb  - >protocol  = eth_type_trans ( skb, vxlan  - >dev ) ;
  4.  
  5.      /* Ignore packet loops (and multicast echo) */
  6.     if ( compare_ether_addr ( eth_hdr ( skb )  - >h_source,
  7.                    vxlan  - >dev  - >dev_addr )  == 0 )
  8.         goto drop;
  9.  
  10.     if ( vxlan  - >learn )
  11.         vxlan_snoop ( skb  - >dev, oip  - >saddr, eth_hdr ( skb )  - >h_source ) ;
  12.  
  13.     __skb_tunnel_rx ( skb, vxlan  - >dev ) ;
  14.     skb_reset_network_header ( skb ) ;
  15.     skb  - >ip_summed  = CHECKSUM_NONE;

 

另外需要特别指出的是:1) 加入和离开组播地址是在 vxlan_open() 和 vxlan_stop() 中完成的;2) Linux 内核已经把 bridge 的 L2 learn 功能给抽出来了,所以 VXLAN 也实现了对 L2 地址的学习和转发:

C:
  1. static  const  struct net_device_ops vxlan_netdev_ops = {
  2.     .  ndo_init        = vxlan_init,
  3.     .  ndo_open        = vxlan_open,
  4.     .  ndo_stop        = vxlan_stop,
  5.     .  ndo_start_xmit      = vxlan_xmit,
  6.     .  ndo_get_stats64      = vxlan_stats64,
  7.     .  ndo_set_rx_mode      = vxlan_set_multicast_list,
  8.     .  ndo_change_mtu      = eth_change_mtu,
  9.     .  ndo_validate_addr    = eth_validate_addr,
  10.     .  ndo_set_mac_address      = eth_mac_addr,
  11.     .  ndo_fdb_add          = vxlan_fdb_add,
  12.     .  ndo_fdb_del          = vxlan_fdb_delete,
  13.     .  ndo_fdb_dump        = vxlan_fdb_dump,
  14. } ;

附注:openvswitch 中的 VXLAN 的实现: http://openvswitch.org/pipermail/dev/2011-October/012051.html

参考资料:

1. http://tools.ietf.org/html/draft-mahalingam-dutt-dcops-vxlan-02
2. http://blogs.cisco.com/datacenter/digging-deeper-into-vxlan/
3. http://www.yellow-bricks.com/2012/11/02/vxlan-use-cases/
4. http://www.borgcube.com/blogs/2011/11/vxlan-primer-part-1/
5. http://www.borgcube.com/blogs/2012/03/vxlan-primer-part-2-lets-get-physical/
6. http://it20.info/2012/05/typical-vxlan-use-case/

 

5 叠加网络技术:VXLAN/NVGRE

网络工程师一般都很熟悉的通用路由封装(GRE),比较容易理解叠加的概念。一个数据包(或帧)封装在另一个数据包内;被封装的包转发到隧道端点后再被拆装。原来的包就发送到了目的地。叠加网络就是使用这种所谓“包内之包”的技术安全地将一个网络隐藏在另一个网络中,然后将网络区段进行迁移。2层扩展和多租户就是比较流行的叠加网络实例。

在过去几年间,个标准化组织已发布了不少的叠加协议,这是因为虚拟化数据中心需要在任意时间、任意地点移动主机的需求所致。有些SDN控制器使用叠加作为其传输选项,在散布于数据中心内的各个主机之间架起了一座桥。而软交换机通常被用作隧道的另一端。虚拟可扩展局域网(VXLAN)是目前获得业界最广泛支持的协议,思科、博科和VMware都支持叠加网络。在硬件方面支持VXLAN隧道端点的是Arista和博科的交换机。VXLAN的硬件端点正给业界带来一场剧变,因为叠加通常都是由软件交换机作为端点的。

VXLAN在3层UDP包内封装2层帧。这样做可以让一个VXLAN段内的主机彼此通信,只要它们处在同一个2层网络上,即便这些主机可能被一个或多个3层网络所隔离。

此外,由于VXLAN保留了全部的2层帧、还有VLAN标识,所以在一个VXLAN段内可允许多个3层网络存在。在该VXLAN段内的客户(也可叫做租户)会觉得这个网络很像他们以前所用过的VLAN,但底层网络只能用一个段ID来区分VXLAN的包。

每个VXLAN网络是用VXLAN包头内的段ID来区分的。这个ID有24位,也就是说可允许1600万个租户共享同一个网络基础架构,同时又可以彼此间相互隔离。

和VXLAN相似,利用GRE实现网络虚拟化(NVGRE)使用一个24位的标识符来定义租户的网络。NVGRE主要是微软开发的技术,也是其Hyper-V所使用的叠加方法。

尽管VMware坚定地支持VXLAN,但是它的叠加网络仍被称为无状态传输隧道(STT)。属于VMware旗下的Nicira。STT是 Nicira网络虚拟化平台的一个组成部分,尤其需要指出的是,STT的封装格式充分利用了先进网卡的硬件能力,可以将较大的数据块分解成较小的数据块。

这被称为TCP分段卸载(TSO),一块有TSO功能的网卡可以承担分段卸载的任务,从而释放出服务器的CPU给其他任务。STT的未来尚无法确定,但VXLAN已经有了VMware的支持以及来自行业的普遍支持。

除了VXLAN、NVGRE和STT,另一个值得关注的叠加网络技术是网络虚拟化叠加(NVO3)。NVO3是由IETF的一个工作组开发的。关于 NVO3的问题说明与上面已经讨论过的其他叠加技术很相像,也就是说,流量孤立、租户可自由使用所选择的寻址方案,可将虚拟机在网络内自由移动,不必考虑底层核心中3层网络的分隔等等。NVO3未来会怎么演进,如何封装尚有待观察,但NVO3工作组成员所提交的用例线路已经基本成形。

 

6 SDN之叠加网络

叠加(Overlay) 在SDN讨论中经常会出现的另一个术语就是叠加网络。简而言之,叠加是用来创建虚拟的网络容器,这些容器之间在逻辑上彼此隔离,但可共享相同的底层物理网络。该类方案的主要思想可被归纳为解耦、独立、控制三个方面。

解耦是指将网络的控制从网络物理硬件中脱离出来,交给虚拟化的网络层处理。这个虚拟化的网络层加载在物理网络之上,屏蔽掉底层的物理差异,在虚拟的空间重建整个网络。因此,物理网络资源将被泛化成网络能力池,正如服务器虚拟化技术把服务器资源转化为计算能力池一样,它使得网络资源的调用更加灵活,满足用户对网络资源的按需交付需求。

独立是指该类方案承载于IP网络之上,因此只要IP可达,那么相应的虚拟化网络就可以被部署,而无需对原有物理网络架构(例如原有的网络硬件、原有的服务器虚拟化解决方案、原有的网络管理系统、原有的IP地址等等)做出任何改变。该类方案可以便捷地在现网上部署和实施,这是它最大的优势。

控制是指叠加的逻辑网络将以软件可编程的方式被统一控制。通过应用该方案,网络资源可以和计算资源、存储资源一起被统一调度和按需交付。以虚拟交换机为代表的虚拟化网络设备可以被整合在服务器虚拟化管理程序(Hypervisor)中统一部署,也可以以软件方式部署在网关中实现与外部物理网络的整合。各种虚拟化网络设备协同工作,在资源管理平台的统一控制下,通过在节点间按需搭建虚拟网络,实现网络资源的虚拟化。

基于叠加网络的方案并不是新近才被提出的,VLAN(虚拟局域网)就是典型的代表。但是,随着云计算等新兴业务对网络要求的提升,传统的技术已经难以满足要求,例如业务只局限于同一二层网络、VLAN数量有限影响多租户业务规模等等。在当前的基于叠加网络的SDN实现领域,隧道(tunneling)技术被广泛应用,它可以基于现行的IP网络进行叠加部署,消除传统二层网络的限制。很多新兴的协议都采用了隧道的原理进行网络通信,例如VXLAN、NVGRE等,它们均利用叠加在三层网络之上的虚拟网络传递二层数据包,实现了可以跨越三层物理网络进行通信的二层逻辑网络,突破了传统二层网络中存在的物理位置受限、VLAN数量有限等障碍,同时还使得网络支持服务的可移动性,大幅度降低管理的成本和运营的风险。

该类方案主要由虚拟化技术厂商主导,例如VMware在其虚拟化平台中实现了VXLAN技术、微软在其虚拟化平台中实现了NVGRE技术,而其中最典型的代表是Nicira公司提出的NVP(Network Virtualization Platform,网络虚拟化平台)方案。NVP支持在现有的网络基础设施上利用隧道技术屏蔽底层物理网络的实现细节,实现了网络虚拟化,并利用逻辑上集中的软件进行统一管控,实现网络资源的按需调度。该类解决方案与虚拟化管理的整合较便捷,但是在实际实施和应用中,其效果会受到底层网络质量的影响。同时,基于网络叠加的技术会增加网络架构的复杂度,并降低数据的处理性能。

 

 

7 openstack 网络模块neutron多节点配置详解

实验逻辑结构:

 

99381395059455.jpguploading.4e448015.gif转存失败重新上传取消openstack 网络模块neutron多节点配置详解<二>的照片 - 1

 


说明:
br-ex  : public network interface
br-int : private network interface

节点说明:
controller节点:neutron 的 server , 和 openvswitch 服务节点
compute多节点:neutron 网络多节点, 运行 dhcp/l3/metadata agent 服务

经过“neutron多节点手动部署配置详解-Havana版本Vlan模式 (1)”中关于控制节点上neutron的相关设置和调试,现在我们开始在计算节点上设置netron网络(节点):

二、计算节点上的neutron网络(节点设置)

1.准备工作

首先确定内核
# uname -r
2.6.32-358.123.2.openstack.el6.x86_64
如果不是,那么安装先关包
# yum install kernel-*openstack.el6.x86_64 -y
防火墙打开端口
# iptables -A INPUT -p tcp -m multiport –dports 9696 -j ACCEPT
# service iptables save

安装相关包
# yum install -y openstack-neutron
  openstack-neutron-openvswitch
  openstack-utils
  openstack-selinux

2.复制配置文档

接下来就比较简单了,将“neutron多节点手动部署配置详解-Havana版本Vlan模式 (1)”一文中控制节点相关的配置文件拷贝过来
所需要的配置文件是:(拷贝到对应的目录)
拷贝前先执行
# ln -s /etc/neutron/plugins/openvswitch/ovs_neutron_plugin.ini
/etc/neutron/plugin.ini

 

然后开始拷贝如下文件
/etc/neutron/neutron.conf 
/etc/neutron/plugins/openvswitch/ovs_neutron_plugin.ini
/etc/neutron/dhcp_agent.ini
/etc/neutron/metadata_agent.ini
/etc/neutron/l3_agent.ini

3.配置OpenvSwitch-Plugin-Agent

启动openvswitch服务,并设置为自启动
# service openvswitch start
# chkconfig openvswitch on

创建ovs内部网络网桥
新建如下文件/etc/sysconfig/network-scripts/ifcfg-br-int
键入内容:
DEVICE=br-int
DEVICETYPE=ovs
TYPE=OVSBridge
ONBOOT=yes
BOOTPROTO=none

命令创建br-int网桥
# ovs-vsctl add-br br-int

添加OVS网桥:
# ovs-vsctl add-br br-eth1
添加接口:
# ovs-vsctl add-port br-eth1  eth1

启动服务:
# service neutron-openvswitch-agent start
设置服务开机启动:
# chkconfig neutron-openvswitch-agent on


4.配置L3 Agent

创建ovs外部网络网桥
创建配置文件
/etc/sysconfig/network-scripts/ifcfg-br-ex
内容如下:
DEVICE=br-ex
ONBOOT=yes
BOOTPROTO=none
NM_CONTROLLED=no
IPV6INIT=no
IPADDR=192.168.1.43
NETMASK=255.255.255.0
GATEWAY=192.168.1.1 
DNS1=192.168.1.1
(此处的IP网络等信息和你的eth0一样)

 

修改eth0配置:
/etc/sysconfig/network-scripts/ifcfg-eth0
改为如下:
DEVICE=eth0
ONBOOT=yes
NM_CONTROLLED=no
IPV6INIT=no
NAME="System eth0"
HWADDR=00:0c:29:bf:98:5f

创建网桥,并添加接口
# service openvswitch restart
# service neutron-openvswitch-agent restart
# ovs-vsctl add-br br-ex
# ovs-vsctl add-port br-ex eth0 ; service network restart
(以上一条命令务必连续执行,否则添加接口的时候网络会断开)

启动服务:
# service neutron-l3-agent start
# service neutron-metadata-agent start
# service neutron-dhcp-agent restart
并设为开机启动
# chkconfig neutron-l3-agent on
# chkconfig neutron-metadata-agent on
# chkconfig neutron-dhcp-agent on

5.检查

 

查看OVS网桥链接情况:
# ovs-vsctl show
f5d7ec60-6bd7-499a-993b-f2e81188d685
    Bridge br-ex
        Port br-ex
            Interface br-ex
                type: internal
        Port "eth0"
            Interface "eth0"
    Bridge "br-eth1"
        Port "phy-br-eth1"
            Interface "phy-br-eth1"
        Port "br-eth1"
            Interface "br-eth1"
                type: internal
        Port "eth1"
            Interface "eth1"
    Bridge br-int
        Port "int-br-eth1"
            Interface "int-br-eth1"
        Port br-int
            Interface br-int
                type: internal
    ovs_version: "1.11.0"

查看服务情况
# service neutron-l3-agent status ; service neutron-openvswitch-agent status ; service neutron-l3-agent status ; service neutron-metadata-agent status ; service neutron-dhcp-agent status

 

neutron-l3-agent (pid  1547) is running…
neutron-openvswitch-agent (pid  1563) is running…
neutron-l3-agent (pid  1547) is running…
neutron-metadata-agent (pid  1555) is running…
neutron-dhcp-agent (pid  1539) is running…

 

 

 

至此,整个neutron网络部分手动部署完成。
 

 

如果你还不清楚具体配置,请查看本文的上半部分:

 

neutron多节点手动部署配置详解-Havana版本Vlan模式 (1)
 

 

75101395059455.jpguploading.4e448015.gif转存失败重新上传取消openstack 网络模块neutron多节点配置详解<二>的照片 - 2

 

29351395059457.jpguploading.4e448015.gif转存失败重新上传取消openstack 网络模块neutron多节点配置详解<二>的照片 - 3

 

openstack 网络模块neutron多节点配置详解<二>的照片 - 4

 

38211395059458.jpguploading.4e448015.gif转存失败重新上传取消openstack 网络模块neutron多节点配置详解<二>的照片 - 5

 

57751395059459.jpguploading.4e448015.gif转存失败重新上传取消openstack 网络模块neutron多节点配置详解<二>的照片 - 6

 

61021395059461.jpguploading.4e448015.gif转存失败重新上传取消openstack 网络模块neutron多节点配置详解<二>的照片 - 7

 

 

8 关于VXLAN与异构云之间的集成 ( by quqi99 )

 

作者:张华  发表于:2013-06-25
版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明

( http://blog.csdn.net/quqi99 )

 

 

          我们知道,IBM最近收购了SoftLayer公司,SoftLayer是一个有些年头的数据中心,以前没有云的概念,所以它主要是通过裸机来提供服务,后来有了CloudStack就开始用CloudStack,今后也将支持OpenStack。那么SoftLayer看起来更像一个API网关,在CloudStack和OpenStack两类云中部署虚机。但是今天上午我一直在想一个需求,即使它通过API网关可以在两类云中部署虚机,但两类云中的虚机从网络上不能互通啊。所以我一直在想能不能通过SDN像OpenDaylight之间的技术解决这个问题。

         我之前听说过VXLAN这个名词,但仅仅是知道这么个名词而已,它究竟是干什么的我并不清楚。在下午的google search中,居然发现VXLAN就是来解决我这类需求的。原来是有这类技术的,呵呵想法撞车了看来我专利的想法泡汤了。

         那么我们来谈谈VXLAN的技术本质是什么呢?

         1)首先它和SDN的思想一样通过重新自定义帧格式,采用基于2.5层UDP的socket走3层将这种自定义的2层帧跨数据中心传过去再解析出来。

         2)在这种自定义帧中可以加入原有的VLAN和tenant的概念来隔离网络,这个vlan的大小可以轻易突破0-4094的限制。

         3)这样的好处是虚机可以跨数据中心迁移。

         4) VMware是通过这种软件的VXLAN方式来解决这类问题;Cisco玩硬件的它当然通过硬件的方式来解决,但原理是一样的也是Mac in IP的方式;微软又搞了一个标准NVGRE,一样的故事,但区别在于VXLAN是VMware更私有的封装,NVGRE的封装采用了标准的GRE遂道,但GRE的性能可能是一个问题。

         5) IBM也有类似的产品Dove, Dove的遂道协议是私有的,但它使用VXLAN的帧格式进行封装,这意味着它可以支持任何VXLAN的底层网络硬件。Dove的那个虚拟交换机名称叫DVS5000v, 参考http://www.ileader.com.cn/html/2012/11/28/57227.htm

 

           下面是VXLAN的示意图:

 

             下面说说VXLAN的缺点,

         对于实现更为动态和更具可扩展性的私有云网络而言,VXLAN和NVGRE的出现是一个很大的进步,但是它们也不是完整的解决方案。它们是封装的协议,还不具备控制面板。相反,它们还依赖于其他的网络功能。例如,VXLAN依赖于与协议无关的多路广播(UDP PIM),而且建立VM之间的通信必须通过2层淹没和动态MAC地址学习实现

   而且,VXLAN和NVGRE还无法解决在核心网络扩展2层域所面对的基础问题:“网络长号”。即使两个VM位于同一个交换机上,流量仍然需要先转发到核心网络,然后到达目的地,感觉就像是乐器长号的管子一样。这就像是在使用学生火车优惠票一样,原先住在城市A,后来搬家到城市B,但是如果一定要享受优惠,您也只能先买到城市A的票,然后再去新家所在的城市B。这样的架构效率很低,而且无法扩展。最后,VXLAN是一个虚拟结构,无法连接到一些物理设备,如防火墙负载均衡器等。关于这个问题,目前已有VXLAN网关产品来解决,它能把负载均衡和防火墙这样的网络服务扩展到VXLAN流量中。网关的作用在于解封闭和重新封闭,在数据中心到云环境,需要检查WAN优化,应用交付控制器、防火墙,入侵防御和入侵检测,没有人能够预见VXLAN流量的发展,所以须在所有地方建立网关。所以Vxlan网关用于实现VXLAN的Overlay流量与传统的以太网数据流量之间的封装与解封装过程(一是剥离/封装VXLAN, 二是映射VXLAN-VLAN),因为VXLAN网络的VTEP功能点本身就是VXLAN的封装与解封装隧道点,因此VXLAN Gateway首先需要具备VTEP功能,形态可以是vSwitch、物理交换机等,只是对于网络中的虚机或其它设备地址表项的处理有所差异(见: 基于多租户的云计算Overlay网络)

 

        关于openflow,它并不是像传统网络那样一层层剥包抽取出MAC在L2层转发,抽取出IP在L3层转发。它是根据:端口号、VLAN、L2/L3/L4信息的10个关键字在控制器层通过字符串匹配进行转发的,所以openflow并不是传统上的L2层设备。特别是,对于L3设备,各类IGP/EGP路由也是运行在OpenFlow Controller之上的。它处理L2层的转发好理解,它怎么和L3层的这些路由设置打交道呢,它怎么与运行VLAN、MPLS,以及BGP、OSPF 和IS-IS等路由协议的传统以太网交换机和谐共存呢

这里有一篇论文http://cseweb.ucsd.edu/~vahdat/papers/b4-sigcomm13.pdf , 目前的OpenFlow能够实现对L2-L4层字段的转发。由于OpenFlow是通过软件实现对整个网络的控制,因此包括BGP协议这些所谓的“控制”功能,理论上都是能够在控制器上通过软件方式实现的,不过目前尚没有看到这样的软件,因为传统的路由信息表和控制器管理的全局网络信息之间需要如何转换,都是跟特定的控制器相关的,而不同的控制器存储的网络全局信息有可能是不一样的。觉得根源在于目前SDN的北向接口还未标准化,各个控制器的API标准未统一。
       谷歌的这篇论文(https://www.opennetworking.org/images/stories/downloads/sdn-resources/customer-case-studies/cs-googlesdn.pdf),其实它里面就实现了BGP协议,不过它不是直接通过控制器软件实现,而是通过Quagga实现对BGP报文的处理从而生成RIB,然后通过控制器Onix上开发的软件RAP实现RIB(路由转发表)前缀到NIB(openflow转发表的名字)的转换。OpenFlow交换机没有任何“控制”功能,所有的控制逻辑都在控制器上实现,明白这一点就很好理解它怎么和L3层交互了。通过OpenFlow实现两个数据中心L2层网络互通,貌似能够通过FlowVisor实现(FlowVisor是用来管理多个openflow控制器的),不过会增加网络部署的复杂度了. 可参考这篇文章《Inside Google's Software-Defined Network,http://www.networkcomputing.com/data-networking-management/inside-googles-software-defined-network/240154879)

 

 

对上图的相关解释如下:

1, Network Controller Servers (NCSs)

2, ISIS是类似于OSPF的一种基于路径状态的内部路由协议

3, Paxos是一个分布式一致性算法的协议

4, Quagga是一个实现了像RIP,OSPF, BGP等动态路由算法的软件,它可以动态地学习BGP报文生成路由规则表RIB

5, RAP是google基于google的openflow controls (Onix,也即上面的NCSs)的一个软件,用于将RIB生成NIB(openflow的转发表),这样openflow switch根据它作转发。

不过上面的路由转发完全不同于传统的包转发,而是基于流转发的,那么具体到openstack中,它怎么和l3-agent协作呢?还是另起灶炉

 

 

再科普一下BGP的两种邻居IBGP和EBGP:

BGP在路由器上运行主要有两种邻居:IBGP(Internal BGP)和EBGP(External BGP)。如果两个交换BGP报文的对等体属于同一个自治系统,那么这两个对等体就是IBGP对等体(Internal BGP),如果两个交换BGP报文的对等体属于不同的自治系统,那么这两个对等体就是EBGP对等体 (External BGP)。

 

 

如上图所示,RTB和RTD为IBGP对等体,RTA和RTB是EBGP对等体。

虽然BGP是运行于自治系统之间的路由协议,但是一个AS的不同边界路由器之间也要建立BGP连接,只有这样才能实现路由信息在全网的传递,如RTB和RTD,为了建立AS100和AS300之间的通信,我们要在它们之间建立IBGP连接。

IBGP对等体之间不一定是物理上直连的,但必须保证逻辑上全连接。(TCP连接能够建立即可)。为了IBGP对等体路由通告的可靠性,我们一般都是采用loopback接口建立IBGP邻居关系,同时必须指定路由更新报文的源接口。

peer { group-name | peer-address } connect-interface interface-name

一般的路由器(包括Quidway系列路由器)都默认要求EBGP对等体之间是有物理上的直连链路,同时他们一般也提供改变这个缺省设置的配置命令。允许同非直连相连网络上的邻居建立EBGP连接。

peer { group-name | peer-address } ebgp-max-hop [ ttl ]

EBGP的邻居要求必须是直连的(除非做了特别的配置),

而IBGP不必非要是直连的(因为它使用TCP协议且单播),这样RTB通过EBGP收到RTA的路由信息之后,只会将这些路由信息发往RTD,RTD到发给RTE。

 

 

         我的一些关于SDN的暂不清晰的不成熟想法:

      1)基于sFlow的VXLAN流量分析工具?

        2) 基于OpenVswitch中的VXLAN的三层来做WAN的异构云(像openstack和cloudstack)的集成,再上之上整一个TE(Traffic Engine),参见谷歌的论文,

            Inter-Datacenter WAN with centralized TE using SDN and OpenFlow,https://www.opennetworking.org/images/stories/downloads/sdn-resources/customer-case-studies/cs-googlesdn.pdf

           或者用Dove ?

        3)具有网络感知能力的应用能够根据需要对逻辑网络进行动态定义的应用

        4)流量工程ECMP, 怎么能实现GRE遂道的多路径传输?

        5)VXLAN之类的流量可视化工具?

        6) 在openstack neutron中集成VXLAN网关?

        7) 基于vxlan的异构云集成?目前openstack有vxlan插件,但云一般有三层网络(虚机用的服务网络,物理机用的管理网络,外网网络),现有的vxlan插件应该是将两端的物理机的管理网络IP作为遂道的端点的,但如果跨数据中心的话,我觉得应该再给物理机分一个浮动IP作为遂道端点, 但是浮动IP是加在网络结节上的,可行吗?想法未验证

       也附一篇文章,有关 OpenFlow/SDN 的小总结 http://richardzhao.me/?p=775
 

 

        

附录,

1)OpenVswitch使用GRE的命令:

ovs-vsctl add-port br0 tep0 -- set interface tep0 type=internal
ifconfig tep0 192.168.1.11 netmask 255.255.255.0

ovs-vsctl add-int br2 gre0 -- set interface gre1 type=gre options:remote_ip=192.168.1.11
ovs-vsctl add-int br2 gre0 -- set interface gre1 type=gre options:remote_ip=192.168.1.10

 

2) linux bridge中的vxlan

 

brctl addbr br.4090

ip link add vxlan4090 type vxlan id 4090 group 239.1.1.1 dev eth0

ip link set vxlan4090 up

ip link set br.4090 up

brctl addif br.4090 vxlan4090

然后将虚机的tap设备插入到上述网桥即可.

 

3) OpenVswitch中使用VXLAN的命令:

ovs-vsctl add-int br2 vx1 -- set interface vx1 type=vxlan options:remote_ip=192.168.1.10
ovs-vsctl add-int br2 vx1 -- set interface vx1 type=vxlan options:remote_ip=192.168.1.11

 

参见资料:http://blog.scottlowe.org/2013/05/07/using-gre-tunnels-with-open-vswitch/

 

像GRE,VXLAN这类overlay的遂道都有一个很大的重要,它在虚拟层面将L2层打通了,如果再采用广播来做ARP的话可能会造成广播风暴,所以可以采用ARP Proxy的方式自己用程序实现cache来给虚机提供ip到mac的映射。另一方面也可以使用其他overlay的技术,如STT,它不使用广播,它也是一种mac over ip的协议,和vxlan, nvgre类似,都是把二层的帧封装在一个ip报文的payload中,在ip报文的payload中,除了虚拟网络的二层包以外,还要把构造的一个tcp头(这样硬件网卡误以为它是一个TCP包,这样就会用硬件来分片了,这是STT的最大优点),和一个stt头加在最前面。见:http://tools.ietf.org/html/draft-davie-stt-01, NTT与VXLAN的区别见:http://blog.ipspace.net/2012/03/do-we-really-need-stateless-transport.html

 

发布了4 篇原创文章 · 获赞 28 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/z136370204/article/details/105174915
今日推荐