VXLAN简介

VXLAN简介

作为一个网络盲程序猿,要整理这样的文章还是稍稍有点吃力。文章中有不对的地方,还望路过的大神斧正,感激不尽!

1、前菜

VXlAN是搭建在三层网络上的虚拟二层网络。呃,暂停一下,我这里有几个问题需要回答一下:首先,什么是二层网络和三层网络?然后,为什么要在三层网络上搭建虚拟二层网络?

1.1、什么是二层网络、三层网络

二层网络通常是指能直接使用Mac地址进程通讯的网络,比如:几台计算机和一台二层交换机组成的局域网就是一个典型的二级网络。是不是很简单,三层网络更简单:由几个二层网络和路由器组成的网络就是三层网络。(手动滑稽)

image-20190301083705871

以上图为例来做一个简单的说明:A、B、C、D四台主机属于一个子网,192.168.1.0/24网段,网关是路由器端口2的IP地址192.168.1.254;E、F、G、H四台主机属于另一个子网,192.168.2.0/24网段,网关是路由器端口3的IP地址192.168.2.254;

A、B、C、D和二层交换机-1、二层交换机-2组成一个二层网络区域-A;E、F、G、H和二层交换机-3、二层交换机-4组成另一个二层网络区域-B。区域-A、区域-B和路由器组成一个三层网络。

以太网协议中规定,在同一个局域网内的主机直接通讯必须知道对方的MAC地址。而TCP/IP协议中,网络层与传输层只关系目标主机的IP地址。这就导致在以太网中使用IP协议时,数据链路层的以太网协议接到上层IP协议提供的数据中,只包含目的主机的IP地址。于是需要一种方法,根据目的主机的IP地址,获得其MAC地址。这就是ARP协议要做的事情。所谓地址解析(address resolution)就是主机在发送帧前将目标IP地址转换成目标MAC地址的过程。

另外,当发送主机和目的主机不在同一个局域网中时,即便的MAC地址,两者也不能直接通信,必须经过路由转发才可以。所以此时,发送主机通过ARP协议获得的将不是目的主机的真实MAC地址,而是一台可以通往局域网外的路由器的MAC地址。于是此后发送主机发往目的主机的所有帧,都将发往该路由器,通过它向外发送。

  • 二层网络通讯过程

先来看在同一子网内的情况,A向C发送报文:A发现C的IP与本机处于同一网段,于是A查询本地ARP缓存。由于在初始状态下,ARP缓存为空,根据C的IP地址192.168.1.3无法匹配上对应的数据。于是A发起ARP广播,试图在局域网内找到IP地址为192.168.1.3的主机C,ARP报文如下(ff:ff:ff:ff:ff:ff 是广播时用的MAC地址):

源MAC目标MAC源IP目标IP
xx…xx:aaff:ff:ff:ff:ff:ff192.168.1.1192.168.1.3

接下来,二层交换机-1收到ARP报文,了解到和端口1连接到是主机A,于是二层交换机-1将端口1连接主机A的信息缓存到本地MAC地址列表(MAC Address-Table)中:

MAC地址端口
xx…xx:aaFE0/1

紧接着,二层交换机-1将ARP报文转发到端口1之外的所有端口。主机B收到端口之后,发现目标IP与本地IP不一样,丢弃ARP报文;二层交换机-2收到ARP报文之后,处理方式与二层交换机一致:缓存并转发;主机D和路由器收到ARP报文,比对后直接丢弃。只有主机C收到ARP报文之后,发现与本地IP一致,于是将主机A的IP地址和MAC地址保存到本地ARP缓存,然后响应ARP请求,因为本地ARP缓存中已经有主机C的信息,所以ARP响应以单播的方式发出,报文如下:

源MAC目标MAC源IP目标IP
xx…xx:ccxx…xx:aa192.168.1.3192.168.1.1

在ARP响应报文发往主机A的过程中,二层交换机-1和二层交换机-2又以同样的方式学习了主机C的MAC地址和端口信息。

之后,主机A和主机C之间就可以直接通过MAC地址进程通讯了,通讯流程与ARP响应流程类似。

  • 三层网络通讯过程

再来看一下跨网络如何进行通信,A向E发送报文:AE的IP地址与本地IP不在同一个局域网内,于是A查询本地路由表,根据目标地址192.168.2.1进行匹配,没有与之匹配的记录,于是返回默认网关192.168.1.254。然后主机A发起ARP请求,以获得网关的MAC地址,ARP只会在同一个局域网内转发,路由器并不会将ARP报文转发到其他端口。获得网关的MAC地址之后,主机A会将数据报文发给网关:

源MAC目标MAC源IP目标IP
xx…xx:aaxx…xx:22192.168.1.1192.168.2.1

注意:与ARP不同,这里的目标MAC地址的网关的MAC地址,但是目标IP地址是主机E的IP地址!

数据报文进入路由器的端口2之后,路由器发现报文内的目标MAC地址为本地端口2的MAC地址,而目标IP地址为192.168.2.1,所以会根据本地路由表查询192.168.2.1的下一跳。

路由器的寻址协议尚未研究,姑且认为路由器直接找到下一跳为192.168.2.254,出口为端口3~

路由器在寻址的过程中,也会发送ARP广播,从而获得主机E的MAC地址~

于是路由器将修改原始报文,将源MAC地址修改为端口3的MAC地址,将目标MAC地址修改为主机E的MAC地址:

源MAC目标MAC源IP目标IP
xx…xx:33xx…xx:ee(下一跳)192.168.1.1192.168.2.1

路由器在修改报文的过程中,源IP和目标IP是不会变的~

接下来,路由器将修改过的数据报文发往主机E,发送过程与二层子网内数据报文发送过程相同。这样就实现了跨网络的数据报文转发。

1.2、为什么需要在三层上虚拟二层

随着云计算时代的来临,为了提高计算资源的利用率,虚拟化技术被广泛应用。同时,为了保证服务的稳定性,虚拟机需要能够在网络中不受限制的迁移。这里就面临着两个问题:

  • 保证服务稳定性,虚拟主机在不同节点之间迁移时,IP地址和MAC地址等网络标识信息不能改变。也就是迁移范围需要在同一个二层网络中。
  • 虚拟化广泛部署,传统的二层网络受到MAC地址缓存列表容量的限制,无法支撑日益增长的接入需求。也就是同一个二层网络接入层容量不够。

为了解决这两个问题,出现了很多值得一提的技术:堆叠、SVF、TRILL,可以从物理上增加二层网络的容量,也就是大二层的概念。和这些大二层技术一样,VXLAN也是为了解决二层网络容量不够的问题而生的。只不过前者需要对物理网络结构做巨大调整,而VXLAN是构建在三层网络之上的,可以对现有网络资源加以利用

此外,为了避免大量广播在局域网内大肆传播,消耗网络资源,通常使用VLAN技术来划分广播域。但是VLAN仅允许划分4000个左右的广播域,对于公有云或其它大型虚拟化云计算服务这种动辄上万甚至更多租户的场景而言,VLAN的隔离能力显然已经力不从心。

2、正餐

VXLAN全称Virtual eXtensible Local Area Network——虚拟扩展局域网,采用L2 over L4(MAC-in-UDP)的报文封装模式,将二层报文用三层协议进行封装,可实现二层网络在三层范围内进行扩展,同时满足数据中心大二层虚拟迁移和多租户的需求。

简单点说:VXLAN就是使用UDP连接多个二层网络,使之成为一个更大的二层网络的技术。

2.1、网络模型

5652c940898f4

核心概念如下:

  • VTEP:VXLAN Tunnel Endpoints,VXLAN的边缘设备。负责将MAC打包为UDP,或者将UDP拆包为MAC。左边VM在一个真实的二层网络中,MAC协议报文传递给VTEP之后,VTEP将其作为原始报文打包到UDP报文里面,通过三层网络传递到右侧VTEP,右侧VTEP收到UDP报文之后,将其拆包,获得原始MAC报文,传递给右侧VM。
  • VXLAN隧道:隧道是一个逻辑概念。对于两边的VM来说,中间的三层网络是透明的,好像有一条隧道将两个二层网络打通一样,可以直接通讯。隧道两端的VTEP需要知道彼此的IP地址,UDP报文会根据这个IP地址发送出去。
  • VNI:VNI配置在VTEP上,类似VLAN ID,用来划分VXLAN的广播域,不同VNI的VXLAN不能直接进行二层通讯。且相比VLAN ID的12字节空间(4096),VNI支持海量区域的隔离。VNI所代表的广播域称之为Bridge-Domain。

2.2、报文格式

先来看一下VXLAN的报文格式:

vnet-vxlan

  • VXLAN Header:增加VXLAN头(8字节),其中包含24比特的VNI字段,用来定义VXLAN网络中不同的租户。此外,还包含VXLAN Flags(8比特,取值为00001000)和两个保留字段(分别为24比特和8比特)。
  • UDP Header:VXLAN头和原始以太帧一起作为UDP的数据。UDP头中,目的端口号(VXLAN Port)固定为4789,源端口号(UDP Src. Port)是原始以太帧通过哈希算法计算后的值。
  • Outer IP Header:封装外层IP头。其中,源IP地址(Outer Src. IP)为源VM所属VTEP的IP地址,目的IP地址(Outer Dst. IP)为目的VM所属VTEP的IP地址。
  • Outer MAC Header:封装外层以太头。其中,源MAC地址(Src. MAC Addr.)为源VM所属VTEP的MAC地址,目的MAC地址(Dst. MAC Addr.)为到达目的VTEP的路径上下一跳设备的MAC地址。

前面说过,VXLAN是在二层外面包三层,从报文内容也可以看出来:首先,是二层网络的实际报文,经过VTEP之后,现在前面增加VXLAN头;然后,VTEP使用UDP协议在外面的三层网络上传输,将VXLAN报文当作UDP报文的原始数据;最后,UDP就像正常的三层网络报文一样传递到目的地;

2.3、建立隧道

在同一个物理网络环境中会有很多的VTEP设备,隧道连接的VETP构成VXLAN网络。在VXLAN中,VM之间是在一个大二层使用MAC地址进行通讯,VETP需要将MAC包装到UDP中发送到目的地。那么源端VM就需要知道目标端VM的IP地址和MAC地址,远端VTEP也需要知道目标端VTEP的IP地址和MAC地址。VM的MAC地址可以通过ARP协议获得,关键问题在于,如何让大二层的ARP协议传播到目标端。也就是如何让ARP借助UDP在三层网络中传播。

为了让物理网络中的VTEP设备可以相互访问,正确的找到彼此,需要为每个VTEP设备配置对端的IP地址列表,配置VTEP的IP地址列表也称之为建立隧道,建立隧道有两种方式:手动、组播、自动。

  • 手动方式:也就是使用命令行手工维护每个VTEP需要连接的远端IP列表
  • 组播方式:为需要相互访问的VTEP分配相同的组播IP,通过组播实现相互发现。与广播类似,但是由于广播无法穿透三层,所以只能使用组播。
  • 自动方式:为VTEP设备配置中心化的配置中心,VTEP通过访问配置中心获得目标VM所在的VTEP地址。

对于手动和组播,会在下文中演示操作步骤,自动配置暂且虐过~

2.4、转发流程

和前菜一样,我们先来个完整的网络拓扑图,然后谈一下同广播域和跨广播域的报文传递流程。拓扑图如下:

image-20190304135006392

这张图是根据上文中的A、C、E、G四台服务器加一个VXLAN三层网关构成,然后在A、C、E、G四台服务器上分别创建虚拟机、网桥和VTEP等虚拟设备。上文中的网关、路由器和其他服务器简单的用L3 Network代替。

上图中的VTEP设备未必会有独立的IP地址,可能直接使用宿主机的IP地址,这样画便于理解,VETP连接的物理网络~

对上图简单说明一下:

  • 在A服务器上创建了两个VTEP设备,分别配置不同的VNI,然后使用虚拟网桥为每个VTEP连接三台虚拟机。
  • 在C服务器上创建一个VTEP设备,配置与A服务器上VTEP-A-2相同的VNI,然后使用虚拟网桥为其连接三个虚拟机。
  • 在E服务器上创建一个VTEP设备,配置与A服务器上VTEP-A-1相同的VNI,然后使用虚拟网桥为其连接三个虚拟机。
  • 在G服务器上创建一个VTEP设备,配置与A服务器上VTEP-A-1相同的VNI,因此,VTEP-A-1、VTEP-E-1和VTEP-G-1将处于同一个VXLAN广播域内。
  • 在L3 Network增加一个VXLAN三层网关设备,用于VXLAN不同VNI的子网之间相互访问,以及VXLAN访问非VXLAN。
  • VTEP隧道配置信息如下(笛卡尔积):
源端IP源端MAC远端IP远端MACVNI
192.168.1.101xx…xx:v1192.168.1.102xx…xx:v2vni-1
192.168.1.101xx…xx:v1192.168.1.103xx…xx:vcvni-1
192.168.1.101xx…xx:v1192.168.2.101xx…xx:vevni-1
192.168.1.101xx…xx:v1192.168.2.102xx…xx:vgvni-1
192.168.1.101xx…xx:v1192.168.3.254xx…xx:00vni-1
192.168.1.102xx…xx:v2192.168.1.101xx…xx:v1vni-2
192.168.1.102xx…xx:v2192.168.1.103xx…xx:vcvni-2
192.168.1.102xx…xx:v2192.168.2.101xx…xx:vevni-2
192.168.1.102xx…xx:v2192.168.2.102xx…xx:vgvni-2
192.168.1.102xx…xx:v2192.168.3.254xx…xx:00vni-2
192.168.1.103xx…xx:vc192.168.1.101xx…xx:v1vni-2
192.168.1.103xx…xx:vc192.168.1.102xx…xx:v2vni-2
192.168.1.103xx…xx:vc192.168.2.101xx…xx:vevni-2
192.168.1.103xx…xx:vc192.168.2.102xx…xx:vgvni-2
192.168.1.103xx…xx:vc192.168.3.254xx…xx:00vni-2
192.168.2.101xx…xx:ve192.168.1.101xx…xx:v1vni-1
192.168.2.101xx…xx:ve192.168.1.102xx…xx:v2vni-1
192.168.2.101xx…xx:ve192.168.1.103xx…xx:vcvni-1
192.168.2.101xx…xx:ve192.168.2.102xx…xx:vgvni-1
192.168.2.101xx…xx:ve192.168.3.254xx…xx:00vni-1
192.168.2.102xx…xx:vg192.168.1.101xx…xx:v1vni-1
192.168.2.102xx…xx:vg192.168.1.102xx…xx:v2vni-1
192.168.2.102xx…xx:vg192.168.1.103xx…xx:vcvni-1
192.168.2.102xx…xx:vg192.168.2.101xx…xx:vevni-1
192.168.1.102xx…xx:vg192.168.3.254xx…xx:00vni-1
  • VXLAN三层网关配置信息
远端IP下一跳IP下一跳MACVNI逻辑接口
10.1.1.0/2410.1.1.254xx…xx:b1vni-1BDIF-1
10.1.2.0/2410.1.2.254xx…xx:b2vni-2BDIF-2

接下来,利用上图推演一些同子网数据报文转发和不同子网数据报文转发到过程:

####2.4.1、同子网互通

假设VA-1发送数据报文到VE-1,流程如下:

VA-1根据IP地址10.1.1.4向VE-1发送报文。VA-1发现VE-1的IP与本地IP地址10.1.1.1处于同一网段,但是初始状态下,VA-1上没有VE-1的MAC地址,所以VA-1发起ARP,企图通过广播获得VE-1的MAC地址,ARP报文如下:

源端IP源端MAC远端IP远端MAC
10.1.1.1xx…xx:a110.1.1.4ff:ff:ff:ff:ff:ff

ARP报文通过网桥传递给VTEP-A-1,VTEP-A-1收到报文后,首先学习VA-1的MAC地址、VNI和接入端口三者的对应关系,然后VTEP-A-1根据头端复制列表对报文进行复制,并分别进行封装,封装后的UDP报文如下:

源端IP源端MAC远端IP远端MACVNI数据报文
192.168.1.101xx…xx:v1192.168.2.1xx…xx:ee(下一跳)vni-1原始ARP报文
192.168.1.101xx…xx:v1192.168.2.3xx…xx:gg(下一跳)vni-1原始ARP报文
192.168.1.101xx…xx:v1192.168.3.254xx…xx:00(下一跳)vni-1原始ARP报文
  • VTEP 会根据VNI对原始ARP报文进行复制,添加VXLAN头,然后分别封装到UDP报文中进行传输

UDP报文到达VTEP-E-1、VTEP-G-1和VTEP-0之后,将UDP报文拆包,获得原始ARP报文,学习VA-1的MAC地址、VTEP-A-1的IP地址和VNI三者的对应关系。然后VTEP将拆包得到的ARP报文在本地广播域内广播。

VE-1、VE-2、VE-3和VG-1、VG-2、VG-3五台虚拟机以及VXLAN三层网关会收到ARP广播,然后与本地IP进行比对。VE-1与ARP报文中的目标IP地址匹配,学习VA-1的IP地址和MAC地址,作出ARP响应。其他VM与三层网关丢弃ARP报文。

由于VE-1已经缓存VA-1的IP地址与MAC地址,所以ARP响应以单播形式发出,报文如下:

源端IP源端MAC远端IP远端MAC
10.1.1.4xx…xx:e110.1.1.1xx…xx:a1

ARP响应报文通过网桥传递给VTEP-E-1,VTEP-E-1学习VE-1的MAC地址、VNI和接入端口三者的对应关系,然后在ARP响应报文头部添加VXLAN头,包装到UDP报文内转发,UDP报文如下:

源端IP源端MAC远端IP远端MACVNI数据报文
192.168.2.101xx…xx:ve192.168.1.101xx…xx:v1(下一跳)vni-1原始ARP响应报文

UDP报文根据远端IP地址192.168.1.101到达VTEP-A-1之后,被拆包,得到原始ARP响应报文,然后学习VE-1的MAC地址、VETP-E-1的IP地址和VNI三者的对应关系。之后根据原始报文内的目标MAC地址,将原始ARP报文发送给VA-1。

之后VA-1与VE-1都通过ARP请求获得了对方的MAC地址,之后的数据报文将通过单播进行传递,传递流程与ARP类似~

####2.4.2、不同子网互通

假设VA-1发送数据报文到VC-1,流程如下:

VA-1根据IP地址10.1.2.1向VC-1发送数据报文。VA-1发现VC-1的IP地址与本地IP地址不在同一个网段内,所以查询路由表,找到与之对应的网关,没有与之匹配的网关信息,获得默认网关:10.1.1.254。

由于是初始状态,VA-1本地没有默认网关的MAC地址,所以发起ARP广播,试图获得默认网关的MAC地址,ARP报文如下:

源端IP源端MAC远端IP远端MAC
10.1.1.1xx…xx:a110.1.1.254ff:ff:ff:ff:ff:ff

ARP报文通过网桥传递给VTEP-A-1,然后VTEP-A-1根据头端复制列表对报文进行负责,并分别进行封装,封装后的UDP报文如下:

源端IP源端MAC远端IP远端MACVNI数据报文
192.168.1.101xx…xx:v1192.168.2.1xx…xx:ee(下一跳)vni-1原始ARP报文
192.168.1.101xx…xx:v1192.168.2.3xx…xx:gg(下一跳)vni-1原始ARP报文
192.168.1.101xx…xx:v1192.168.3.254xx…xx:00(下一跳)vni-1原始ARP报文

UDP报文到达VTEP-E-1、VTEP-G-1和VTEP-0之后,将UDP报文拆包,获得原始ARP报文,然后VTEP将拆包得到的ARP报文在本地广播域内广播。五台虚拟机收到原始ARP报文之后,经过比对,直接丢弃。VXLAN三层网关收到ARP报文,比对发现目标IP与本地BDIF-1的IP地址匹配,学习VA-1的MAC地址、VTEP-A-1IP和VNI的三者的对应关系之后,以单播响应ARP请求,VA-1因此获得三层网关接口BDIF-1的MAC地址。

VA-1获得网关的MAC地址之后,将数据报文以单播形式发给默认网关,数据报文如下:

源端IP源端MAC远端IP远端MAC
10.1.1.1xx…xx:a110.1.2.1xx…xx:b1

VTEP-A-1收到原始数据报文后,添加VXLAN头,包装到UDP报文内,UDP报文如下:

源端IP源端MAC远端IP远端MACVNI数据报文
192.168.1.101xx…xx:v1192.168.3.254xx…xx:00(下一跳)vni-1原始数据报文

VTEP-0收到原始数据报文之后,对比发现,原始报文内的远端MAC地址为本地BDIF-1端口的MAC地址,远端IP地址为VC-1的IP地址10.1.2.1。所以根据路由表,决定下一跳为BDIF-2端口;通过ARP广播,获得远端IP地址10.1.2.1对应的MAC地址。VTEP-0将修改原始数据报文:

源端IP源端MAC远端IP远端MAC
10.1.1.1xx…xx:b210.1.2.1xx…xx:c1

VTEP-0修改后的原始数据报文从BDIF-2端口流出前,VTEP-0根据ARP广播,得知目的IP地址为VTEP-C-1的IP地址,BDIF-2将为其配置VXLAN头并包装为UDP报文,格式如下:

源端IP源端MAC远端IP远端MACVNI数据报文
192.168.3.254xx…xx:00192.168.1.103xx…xx:vc(下一跳)vni-2VTEP-0修改后的报文

VTEP-C-1收到数据报文之后,拆包,获得原始数据报文。然后,根据原始数据报文中的远端MAC地址,将数据报文抓发给VC-1。

到此,完成VXLAN跨域转发~

3、甜品

在之前关于Linux namespace的文章中,利用bridge和veth pair实现了单机环境下不同namespace之间相互通讯。接下来的内容将尝试在不同节点上创建network namespace,利用VXLAN实现跨节点的network namespace之间相互通讯。

  • 实验环境
操作系统IPhostname
CentOS Linux release 7.5.1804 (Core)172.16.7.100node-0
CentOS Linux release 7.5.1804 (Core)172.16.7.101node-1
  • 点对点配置
### 创建三个network namespace ###
[root@node-0 ~]# ip netns add container-0
[root@node-0 ~]# ip netns add container-1
[root@node-0 ~]# ip netns add container-2
[root@node-0 ~]# ip netns list
container-2
container-1
container-0

### 创建brodge设备 ###
[root@node-0 ~]# ip link add type bridge

### 创建三对veth pair ###
[root@node-0 ~]# ip link add type veth
[root@node-0 ~]# ip link add type veth
[root@node-0 ~]# ip link add type veth

### 检查创建结果 ###
[root@node-0 ~]# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 00:50:56:2d:4b:f6 brd ff:ff:ff:ff:ff:ff
3: bridge0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 82:76:89:91:df:3e brd ff:ff:ff:ff:ff:ff
4: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether e2:fe:90:f7:70:c0 brd ff:ff:ff:ff:ff:ff
5: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether de:15:00:f8:6c:ac brd ff:ff:ff:ff:ff:ff
6: veth2@veth3: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether ba:c4:88:b8:ef:f5 brd ff:ff:ff:ff:ff:ff
7: veth3@veth2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 5a:7e:f1:9b:ff:17 brd ff:ff:ff:ff:ff:ff
8: veth4@veth5: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 9e:bf:09:a8:6c:0c brd ff:ff:ff:ff:ff:ff
9: veth5@veth4: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether da:12:08:18:f3:be brd ff:ff:ff:ff:ff:ff

### 使用veth pair将network namespace与bridge连接起来 ###
[root@node-0 ~]# ip link set dev veth0 netns container-0
[root@node-0 ~]# ip link set dev veth2 netns container-1
[root@node-0 ~]# ip link set dev veth4 netns container-2
[root@node-0 ~]# ip link set dev veth1 master bridge0
[root@node-0 ~]# ip link set dev veth3 master bridge0
[root@node-0 ~]# ip link set dev veth5 master bridge0

### 为各个network namespace下的veth设备配置IP地址,启动lo和veth设备 ###
[root@node-0 ~]# ip netns exec container-0 ip addr add 10.1.1.1/24 dev veth0
[root@node-0 ~]# ip netns exec container-0 ip link set dev lo up
[root@node-0 ~]# ip netns exec container-0 ip link set dev veth0 up
[root@node-0 ~]# ip link set dev veth1 up

[root@node-0 ~]# ip netns exec container-1 ip addr add 10.1.1.2/24 dev veth2
[root@node-0 ~]# ip netns exec container-1 ip link set dev lo up
[root@node-0 ~]# ip netns exec container-1 ip link set dev veth2 up
[root@node-0 ~]# ip link set dev veth3 up

[root@node-0 ~]# ip netns exec container-2 ip addr add 10.1.1.3/24 dev veth4
[root@node-0 ~]# ip netns exec container-2 ip link set dev lo up
[root@node-0 ~]# ip netns exec container-2 ip link set dev veth4 up
[root@node-0 ~]# ip link set dev veth5 up

### 启动网桥 ###
[root@node-0 ~]# ip link set dev bridge0 up

### 查看设备信息 ###
[root@node-0 ~]# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 00:50:56:2d:4b:f6 brd ff:ff:ff:ff:ff:ff
3: bridge0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 5a:7e:f1:9b:ff:17 brd ff:ff:ff:ff:ff:ff
5: veth1@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master bridge0 state UP mode DEFAULT group default qlen 1000
    link/ether de:15:00:f8:6c:ac brd ff:ff:ff:ff:ff:ff link-netnsid 0
7: veth3@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master bridge0 state UP mode DEFAULT group default qlen 1000
    link/ether 5a:7e:f1:9b:ff:17 brd ff:ff:ff:ff:ff:ff link-netnsid 1
9: veth5@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master bridge0 state UP mode DEFAULT group default qlen 1000
    link/ether da:12:08:18:f3:be brd ff:ff:ff:ff:ff:ff link-netnsid 2

### 测试单节点上network namespace之间的联通性 ###
[root@node-0 ~]# ip netns exec container-0 ping -c 3 10.1.1.2
PING 10.1.1.2 (10.1.1.2) 56(84) bytes of data.
64 bytes from 10.1.1.2: icmp_seq=1 ttl=64 time=0.047 ms
64 bytes from 10.1.1.2: icmp_seq=2 ttl=64 time=0.078 ms
64 bytes from 10.1.1.2: icmp_seq=3 ttl=64 time=0.070 ms

--- 10.1.1.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 0.047/0.065/0.078/0.013 ms

接下来在node-1上进行同样的操作,设置network namespace对应的IP地址为4、5、6。

### 创建点对点的vxlan网络,VNI:1000、对端IP:172.16.7.101、本地ID:ens33的IP、对端UDP监听端口:4789 ###
[root@node-0 ~]# ip link add type vxlan id 1000 remote 172.16.7.101 dev ens33 dstport 4789

### 查看vxlan设备详细信息 ###
[root@node-0 ~]# ip -d link show dev vxlan0
10: vxlan0: <BROADCAST,MULTICAST> mtu 1450 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 7a:00:03:80:12:a6 brd ff:ff:ff:ff:ff:ff promiscuity 0 
    vxlan id 1000 remote 172.16.7.101 dev ens33 srcport 0 0 dstport 4789 ageing 300 noudpcsum noudp6zerocsumtx noudp6zerocsumrx addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 

### 连接vxlan设备与网桥 ###
[root@node-0 ~]# ip link set dev vxlan0 master bridge0

### 启动vxlan设备 ###
[root@node-0 ~]# ip link set dev vxlan0 up
[root@node-0 ~]# ip link show dev vxlan0
10: vxlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master bridge0 state UNKNOWN mode DEFAULT group default qlen 1000
    link/ether 7a:00:03:80:12:a6 brd ff:ff:ff:ff:ff:ff

在node-1上进行同样的操作,node-1上创建vxlan时,对端设备IP为node-0的IP地址:172.16.7.100。

### 测试:尝试在node-0上ping node-1上的network namespace内的IP ###
[root@node-0 ~]# ip netns exec container-0 ping -c 3 10.1.1.4
PING 10.1.1.4 (10.1.1.4) 56(84) bytes of data.
From 10.1.1.1 icmp_seq=1 Destination Host Unreachable
From 10.1.1.1 icmp_seq=2 Destination Host Unreachable
From 10.1.1.1 icmp_seq=3 Destination Host Unreachable

--- 10.1.1.4 ping statistics ---
3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 2002ms
pipe 3

### 测试失败,尝试排查一下问题,首先查看iptables规则 ###
[root@node-0 ~]# iptables -L -v --line-numbers
[root@node-0 ~]# iptables -L -v --line-numbers
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1     2542  181K ACCEPT     all  --  any    any     anywhere             anywhere             ctstate RELATED,ESTABLISHED
2        2   142 ACCEPT     all  --  lo     any     anywhere             anywhere            
3       17  2160 INPUT_direct  all  --  any    any     anywhere             anywhere            
4       17  2160 INPUT_ZONES_SOURCE  all  --  any    any     anywhere             anywhere            
5       17  2160 INPUT_ZONES  all  --  any    any     anywhere             anywhere            
6        0     0 DROP       all  --  any    any     anywhere             anywhere             ctstate INVALID
7        8   936 REJECT     all  --  any    any     anywhere             anywhere             reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 ACCEPT     all  --  any    any     anywhere             anywhere             ctstate RELATED,ESTABLISHED
2        0     0 ACCEPT     all  --  lo     any     anywhere             anywhere            
3        0     0 FORWARD_direct  all  --  any    any     anywhere             anywhere            
4        0     0 FORWARD_IN_ZONES_SOURCE  all  --  any    any     anywhere             anywhere            
5        0     0 FORWARD_IN_ZONES  all  --  any    any     anywhere             anywhere            
6        0     0 FORWARD_OUT_ZONES_SOURCE  all  --  any    any     anywhere             anywhere            
7        0     0 FORWARD_OUT_ZONES  all  --  any    any     anywhere             anywhere            
8        0     0 DROP       all  --  any    any     anywhere             anywhere             ctstate INVALID
9        0     0 REJECT     all  --  any    any     anywhere             anywhere             reject-with icmp-host-prohibited
<snip>

### 尝试删除INPUT和FORWARD中的最后两行DROP和REJECT,在两个节点上操作 ###
[root@node-0 ~]# iptables -D INPUT 6
[root@node-0 ~]# iptables -D INPUT 6
[root@node-0 ~]# iptables -D FORWARD 8
[root@node-0 ~]# iptables -D FORWARD 8

### 再次测试 ###
[root@node-0 ~]# ip netns exec container-0 ping -c 3 10.1.1.4
PING 10.1.1.4 (10.1.1.4) 56(84) bytes of data.
64 bytes from 10.1.1.4: icmp_seq=1 ttl=64 time=0.918 ms
64 bytes from 10.1.1.4: icmp_seq=2 ttl=64 time=0.877 ms
64 bytes from 10.1.1.4: icmp_seq=3 ttl=64 time=0.921 ms

--- 10.1.1.4 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 0.877/0.905/0.921/0.031 ms

这里测试的时候需要主要,有些操作系统默认的iptables规则会阻止某些流量的转发~

  • 组播配置

设置组播后,添加vxlan设备时,不需要再通过remote参数来指定对端IP来建立隧道,而是通过group参数来指定组播地址,操作方式与上面点对点的差别不大,不在继续演示。

##4、参考资料

https://blog.csdn.net/duhf_think/article/details/41483153

https://zhuanlan.zhihu.com/p/35616289

https://forum.huawei.com/enterprise/zh/thread-334207.html

https://zh.wikipedia.org/wiki/地址解析协议

https://blog.51cto.com/13770206/2122411

http://cizixs.com/2017/09/25/vxlan-protocol-introduction/

http://cizixs.com/2017/09/28/linux-vxlan/

https://www.zhihu.com/question/63497028

https://www.zhihu.com/question/58187639/answer/155994550

https://www.cnblogs.com/wipan/p/9220615.html

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页