易陆发现互联网技术论坛

 找回密码
 开始注册
查看: 3875|回复: 0
收起左侧

VLAN Trunk在OpenStack Neutron及SDN中的实现

[复制链接]
发表于 2018-12-4 10:15:57 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?开始注册

x
前言

本文先介绍一下VLAN Trunk的基本概念,以及openstack Neutron和OpenFlow based SDN是如何为Trunk port提供网络支持。OpenStack对VLAN Trunk的支持具体是什么?虽然OpenStack与容器,物理主机也做了集成,但是OpenStack最主要的应用还是虚机管理,而现代的操作系统,不论是Linux还是Windows,都支持将网卡配置成Trunk port。OpenStack对VLAN Trunk的支持就是指对OpenStack所管理的虚机的Trunk port,提供网络支持。
- j- z7 l2 i$ x3 i- a, N" \  S

0 s6 y' ]2 E- Z% w4 C
                               
登录/注册后可看大图

4 d5 l) e; J* f: N主机的Trunk port是指在主机的一块网卡上添加多个带有不同VLAN ID的子网卡。通过子网卡发送的数据,打上VLAN Tag,被发送出去。由于带了不同的VLAN Tag,子网卡可以认为连接在VLAN Tag标识的网络中。这样,不用增减主机的网卡,就可以将主机添加到新的网络中。更主要的是,这种方式的网络添加是动态的。

主机的Trunk port有什么用?一个应用是在NFV场景下,一个VNF(Virtual Networking Function)可能需要同时连接多个网络。当然最简单是一个网络对应一块网卡,但如果网络数量巨大,网卡数量也巨大,一方面这不现实。另一方面,连接的多个网络也是动态增减的,如果每次增减都插拔VNF的网卡,明显也是不能接受的。如果用Trunk port,当需要动态连接多个网络时,只需要动态的创建/删除相应的子网卡即可。
, H& Q: Y5 ^. |7 g) g- t" u' XVLAN Trunk在NFV中的应用

一、VLAN Trunk介绍1.1 VLAN简介

VLAN(Virtual LAN)由IEEE802.1Q定义。要讲VLAN要先从广播域(Broadcast Domain)开始说起。在下图中,假设PC1-5在一个广播域中,当PC1发出广播帧,例如ARP,DHCP,由于目的MAC地址是广播地址,同一个广播域内的所有设备都将收到相应的广播帧。如果PC1-5在一个子网中,那这本身也无可厚非,因为这正是ARP,DHCP的工作原理。0 ~( B1 _& @, t5 S  o4 @' p

" ]8 s9 d$ H0 N! [6 c
                               
登录/注册后可看大图
! Y/ E9 `$ i+ W
如果PC1-5不在一个子网中呢?例如上图中,PC1在橙色子网,PC2-3在绿色子网,PC4-5在红色子网。理论上,PC1发出的广播帧只应该在橙色子网内传播。但实际上,是由于PC1-5在一个广播域中,PC2-5还是会收到PC1的广播帧。虽然PC2-5会直接丢弃这个广播帧,但是这里存在安全问题和性能问题。首先,PC2-5虽然不会处理PC1发来的广播帧,但是数据还是发送过来了,通过侦听和伪装,可以达到劫持的目的,例如ARP spoof。其次,广播帧本来不用在整个网络传播,但现在就整个网络传播,这样占用了交换机的带宽,在大规模网络中,尤其会影响网络性能。解决这些问题的方法就是使用VLAN。

VLAN是一组网络端口的集合。实现了VLAN的交换机,会将二层的单播、组播、广播都局限在一个VLAN中,这样不同的VLAN中的主机,交换机就不会有其他VLAN的数据。只有交换机能看到VLAN,连接交换机的其他设备,例如Server、Router都感觉不到VLAN的存在。将不同的子网规划在不同的VLAN当中,可以实现子网的隔离。即使所有的设备都在一个交换机上,不同的VLAN之间通信也需要通过Router。4 A% H5 `% d5 z# k7 b, B) z


7 q+ p5 Q/ n6 f8 n1 l; q                               
登录/注册后可看大图

1.2 VLAN Trunk简介

VLAN的划分并非只能在一个交换机上,多个交换机可以共同组成VLAN。那多个交换机上的VLAN是怎么连接到一起的?有两种方法。

第一种方法是把每个交换机上的每个VLAN都连在一起。如下图所示:
) P; R+ P- y6 h5 `: @( y7 e3 r

( S6 l8 b! [+ X/ t# t# q4 U
                               
登录/注册后可看大图
: l) ~0 Z9 O, K; N
图中有两个交换机,各有两个VLAN,为了让VLAN能正常工作,将VLAN1和VLAN2分别连接起来。如果是两个交换机,两个VLAN还好,如果是100个VLAN,那么这里需要有100条线路,200个交换机端口。这么连接可以吗?可以,只要有钱,因为这里的线路和交换机端口都是钱。这种方法,运维和成本支出比较大,不实用。

第二种方法是通过VLAN Trunk连接交换机。VLAN Trunk是一种网络设备间的point-to-point的连接。一条VLAN Trunk线路可以同时传输多个甚至所有的VLAN数据。7 h$ O/ u. ?- Z5 s  r/ t

$ x; `$ c7 \# y0 e; \' D; l
                               
登录/注册后可看大图

* a- P+ }& Q0 f* b, G  h, M6 a由于VLAN Trunk可以传输多个VLAN数据,Ethernet Frame在VLAN Trunk上传输时,需要带上802.1Q定义的VLAN tag,这样交换机才能区分Ethernet Frame到底属于哪个VLAN。VLAN Trunk的具体使用过程如下:

  • 当最左侧服务器想要访问最右侧服务器,最左侧服务器将Ethernet Frame发送到左侧交换机
  • 左侧交换机本地没有目的MAC对应的转发信息,因此Ethernet Frame发送到了左侧交换机的VLAN Trunk port
  • 由于这是来自VLAN100的Ethernet Frame,交换机给Ethernet Frame打上VLAN 100的Tag,从自己的VLAN Trunk port发出,发送到右侧交换机的VLAN Trunk port
  • 右侧的VLAN Trunk port收到VLAN 100的Ethernet Frame,去除VLAN Tag,再在本地的VLAN 100端口中查找MAC转发
  • 找到对应的MAC/端口记录,最终Ethernet Frame发送到最右侧的服务器+ C! M6 ]1 V' i5 u. v; O

如果是VLAN200的数据,过程一样,只是VLAN Tag从100变成了200。

通过VLAN Trunk port,两个交换机之间不论需要连接多少个VLAN,只需要一个VLAN Trunk连接(一对Trunk port)即可。

如果有多个交换机需要连接,通常会用另外一个交换机连接它们,如下图所示,交换机之间都通过Trunk port相连。
& m" W5 {" R+ g5 V5 t+ b

) J+ B0 g) |1 V1 d2 E- S2 W, k
                               
登录/注册后可看大图

8 ]" F* |! \  \4 N& u红色框内的交换机的4个port都是Trunk port,任意的VLAN 标签的Ethernet Frame都可以在这个交换机内传输。可以把红色框内看成是一个Trunk network,一个Trunk network可以传输带VLAN标签的Ethernet Frame。虽然图中只有一个交换机,但是Trunk network可以更加复杂,由多个交换机组成。多个VLAN的网络数据共同在Trunk network上传输,通过VLAN Tag来识别VLAN。

如果把上图中下面四个交换机换成主机(虚机),那就是OpenStack VLAN Trunk希望支持的场景。为了支持这个场景,需要为虚机提供一个Trunk Network。

1.3 Linux VLAN Trunk

Windows也支持Trunk port,与Linux类似,这里只说明Linux系统下的Trunk port。

Linux系统可以通过内核模块8021q支持VLAN Trunk。这里有什么不一样?在一般情况下,主机是不感知VLAN Tag的,也就是说主机发送的网络数据都是不带VLAN Tag,所有VLAN Tag操作都是由交换机完成。但是实际上交换机也不知道自己连接的是什么,所以,如果在主机完成VLAN Tag的操作,再发送到交换机,交换机也能处理。基于这个前提,Linux能够将一块以太网卡配置成一个支持802.1q的Trunk port,使得这块网卡跟前面描述的交换机上的Trunk port一样,能够收发多个VLAN的网络数据包。并且通过配置Linux主机的子网卡,可以使得Linux主机内部完成VLAN Tag的操作(打上VLAN Tag,去除VLAN Tag)。有不止一种方法可以配置Linux VLAN Trunk,这里以ip命令为例,为eth0添加名为eth0.102的子网卡,其VLAN ID为102。

[color=rgb(51, 51, 51) !important]

# I: f+ v1 r% f! M% a1 ^

8 C& j/ o. t3 F" a4 U

" ^# T- A+ F& _5 \
$ v# O% v- _( S+ X
7 i: l) c7 S" b* t1 [5 L8 A
- U3 }5 X- g( |/ F0 S- h& ?. D2 g

/ Q& y& i( F! V0 A$ X/ D
7 h  ?2 f6 {8 @
6 p9 M: m+ h3 ^* D! D

4 Q( k$ y8 Y4 ^. }[color=rgb(153, 153, 153) !important]Java
) K2 T3 g' H0 G- m1 m
% J9 x& P% z0 {4 X, e

2 y& {/ F1 Q7 k6 i- v; }  A+ b, ^
1
4 k/ @; ?- T2 k

5 K- b$ S# S. [/ x
[color=rgb(51, 51, 51) !important]$[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]sudo [color=rgb(0, 78, 208) !important]ip [color=rgb(0, 78, 208) !important]link [color=rgb(0, 78, 208) !important]add [color=rgb(0, 78, 208) !important]link [color=rgb(0, 78, 208) !important]eth0 [color=rgb(0, 78, 208) !important]name [color=rgb(0, 45, 122) !important]eth0[color=rgb(51, 51, 51) !important].[color=rgb(206, 0, 0) !important]102[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]type [color=rgb(0, 78, 208) !important]vlan [color=rgb(0, 0, 0) !important]id[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]102

4 {( }2 s, o' Y! s6 v

. m0 m7 V. O# X5 u9 x# D; S
% V* e5 s* D1 U
! v8 i7 d7 M2 {5 c7 k9 q6 v3 }) P

就这么简单,之后可以看到一个新的网卡在系统的网卡列表中。Linux VLAN Trunk工作过程如下:

  • 外界传入的带VLAN Tag 102的包,到达了eth0,VLAN Tag 102被去除,然后不带VLAN Tag的Ethernet Frame被重新发往操作系统网络栈,再发送到eth0.102。
  • 从eth0.102发送出来的帧,被打上VLAN102的标签,再从eth0传出。) {2 p1 t( J9 q: O9 {

应用层面,收发的还是不带VLAN Tag的数据,只是经过Linux VLAN Trunk的处理,进出主机的的数据是带VLAN Tag的数据。

由于eth0配置成了VLAN Trunk port。为了让带有VLAN标签的Ethernet Frame能够在网络上传输。eth0所接入的网络必须是一个Trunk network。否则无法传输任意带VLAN Tag的Ethernet Frame。也就是说,需要将主机的Trunk port连接到红框内。接下来我们看看OpenStack是怎么做的。

二、OpenStack Neutron对VLAN Trunk的支持Neutron VLAN Transparency

这是OpenStack Kilo版本的特性,由VLAN trunking networks for NFV定义。这个特性为Neutron network增加一个属性“vlan-transparent”,当vlan-transparent为True时,表明在这个Neutron network是一个Trunk network。在这个Neutron network中的虚机可以使用Linux VLAN Trunk功能。接下来看看Neutron为了实现这个特性做了什么?

什么也没做!Neutron只是提供了这么一个属性,具体的实现交给底层的SDN。如果SDN不支持VLAN Transparency,可以在ML2中告知Neutron。那么用户在创建Neutron network时,如果指定了vlan-transparent=True,Neutron会返回“Backend does not support VLAN Transparency.”。例如OpenVSwitch,就不支持VLAN Transparency。

所以,并非所有的SDN都支持这个功能,就算实现了,每种SDN的实现方式不一样。不过本质上,都是将SDN控制的vSwitch配置成Trunk模式。需要注意的是,vSwitch最终还是要连接到Physical Switch,所以Physical Switch相应的端口也需要配置成Trunk port。

先来看看VLAN Transparency的问题,

  • 不支持OpenVSwitch
  • 要求Physical Switch也配置相应的Trunk port
      [- j% A1 Q3 I) e

VLAN aware VMs在支持相同功能的前提下,解决了上面两个问题。首先看看如何使用VLAN aware VMs这个功能。Neutron VLAN aware VMs是OpenStack Newton版本的特性,由VLAN aware VMs定义。VLAN aware VMs和VLAN Transparency说的其实是一件事情,就是如何传递VM发出来的带VLAN Tag的帧。

2.1 实验步骤

我用的是最新代码(Pike 2017-08-08)配合OpenVSwitch完成下面的操作。要使能VLAN aware VMs,只需要在/etc/neutron/neutron.conf中,在service_plugins后面加上trunk。

首先创建Trunk port所在的网络和VLAN子网卡所在的网络。

[color=rgb(51, 51, 51) !important]

8 z& u: B* ]& w, a' x0 F" j
$ a, u+ }2 ], w1 W+ J

4 {. i5 U1 {: p5 J  G' Z, U
0 v3 p$ f, K: m. f! N6 K

/ ~" n  K5 f: h7 R. C2 Y

5 V) ~2 V) r+ N. r
8 r6 D8 F7 e0 y  T; B

4 _) [9 y" {' L4 A. e

) R4 e+ p7 Y% k! C" S3 R

7 J2 r; ~0 A" s, M/ E/ h[color=rgb(153, 153, 153) !important]Java
" D5 G9 ?" I) U2 U& a, r

7 S; Z  X! J; _" ?
- h. j: s% v- a% f+ X* _- S, _
1

) u  }) [5 O6 f' ^$ @: K4 g9 d) G
[color=rgb(49, 124, 197) !important]2

5 i6 M# ^7 T4 i, j( T. X
3
& ?5 E0 _. s/ k& Z9 b1 o% P0 {
[color=rgb(49, 124, 197) !important]4

1 a; p) ?' G8 \/ F  e; s/ V6 h

2 X: N$ Q, d" L7 v% e/ O' ?# ~
[color=rgb(51, 51, 51) !important]$[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]openstack [color=rgb(0, 78, 208) !important]network [color=rgb(0, 78, 208) !important]create [color=rgb(128, 0, 128) !important]parent[color=rgb(0, 111, 224) !important]-[color=rgb(0, 0, 0) !important]net

: p2 L* l# b" z& R0 I
[color=rgb(51, 51, 51) !important]$[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]openstack [color=rgb(0, 78, 208) !important]subnet [color=rgb(0, 78, 208) !important]create [color=rgb(128, 0, 128) !important]parent[color=rgb(0, 111, 224) !important]-[color=rgb(0, 45, 122) !important]subnet[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]--[color=rgb(0, 78, 208) !important]network [color=rgb(128, 0, 128) !important]parent[color=rgb(0, 111, 224) !important]-[color=rgb(0, 45, 122) !important]net[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]--[color=rgb(0, 45, 122) !important]subnet[color=rgb(0, 111, 224) !important]-[color=rgb(0, 0, 0) !important]range[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]20.0.0.0[color=rgb(0, 111, 224) !important]/[color=rgb(206, 0, 0) !important]24

# B; i! `) I2 k: d- i; f
[color=rgb(51, 51, 51) !important]$[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]openstack [color=rgb(0, 78, 208) !important]network [color=rgb(0, 78, 208) !important]create [color=rgb(0, 45, 122) !important]sub[color=rgb(0, 111, 224) !important]-[color=rgb(0, 0, 0) !important]net

0 B" Q% W- K, n, _3 K
[color=rgb(51, 51, 51) !important]$[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]openstack [color=rgb(0, 78, 208) !important]subnet [color=rgb(0, 78, 208) !important]create [color=rgb(0, 45, 122) !important]sub[color=rgb(0, 111, 224) !important]-[color=rgb(0, 45, 122) !important]subnet[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]--[color=rgb(0, 78, 208) !important]network [color=rgb(0, 45, 122) !important]sub[color=rgb(0, 111, 224) !important]-[color=rgb(0, 45, 122) !important]net[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]--[color=rgb(0, 45, 122) !important]subnet[color=rgb(0, 111, 224) !important]-[color=rgb(0, 0, 0) !important]range[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]21.0.0.0[color=rgb(0, 111, 224) !important]/[color=rgb(206, 0, 0) !important]24

! j5 R2 t: f0 L7 Q2 r& W$ d$ v
/ v' }7 v% o0 E. V

* l  g/ E5 P2 e& ?: Z" ~* _) m
5 v7 k0 F- n7 r# V% e! @6 Y& u* h  A

注意这里我并没有指定网络的类型,网络可以不用是VLAN的,像在我的环境中,网络就是VXLAN类型。为什么会这样?在后面会说。

接下来创建Trunk port和subport。

[color=rgb(51, 51, 51) !important]
/ u" t# g1 }% W2 S
& i& _0 m5 m% N( ]7 U" p, U

5 L: V# q$ P2 K& L+ `
' ]* X3 r. U, {$ k) x+ Q& U

. a; P! c# S& [7 u, \/ D: P1 x

+ Y& s( c6 M/ Y2 s) u
7 l0 ^7 S3 u; @9 `$ S6 ?3 ]

) v. G: z4 y5 x: p  U0 R5 M

3 }! G( R& B, s4 p% H+ C) N

( ?1 l+ k0 h  C% j' [7 t4 l[color=rgb(153, 153, 153) !important]Java
1 G5 G4 S3 d4 ~0 y. s! _+ R+ Q7 I- X
% B( `. U& t, c9 q

7 {$ r0 S" Z; ?0 ~; _* G
1
! q4 x+ a+ g7 \2 o3 b
[color=rgb(49, 124, 197) !important]2

. A# S  U" i3 I, g: g  t2 k( s: X* t. e
3

5 U4 G1 v; ~9 i& v% M
[color=rgb(49, 124, 197) !important]4

: d, P% Z' p) n( Q. E5 l! v
5

" c6 Y! d' i# _, s  V/ ~* Q! @) e3 |, Z
[color=rgb(49, 124, 197) !important]6

- W7 E: [' J+ D
7
% S3 o" U+ o: \/ C/ K
[color=rgb(49, 124, 197) !important]8

! ~+ Q! h8 N9 N% j6 z6 L' r
* U9 H+ R/ o3 i0 [: I+ V
[color=rgb(51, 51, 51) !important]$[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]openstack [color=rgb(0, 78, 208) !important]port [color=rgb(0, 78, 208) !important]create [color=rgb(128, 0, 128) !important]parent[color=rgb(0, 111, 224) !important]-[color=rgb(0, 45, 122) !important]port1[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]--[color=rgb(0, 78, 208) !important]network [color=rgb(128, 0, 128) !important]parent[color=rgb(0, 111, 224) !important]-[color=rgb(0, 0, 0) !important]net
# P# Q: {( [6 y' s8 n4 O
[color=rgb(51, 51, 51) !important]$[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]openstack [color=rgb(0, 78, 208) !important]port [color=rgb(0, 78, 208) !important]create [color=rgb(0, 45, 122) !important]sub[color=rgb(0, 111, 224) !important]-[color=rgb(0, 45, 122) !important]port1[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]--[color=rgb(0, 78, 208) !important]network [color=rgb(0, 45, 122) !important]sub[color=rgb(0, 111, 224) !important]-[color=rgb(0, 0, 0) !important]net

! `, [' H2 M" z" w
[color=rgb(51, 51, 51) !important]$[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]openstack [color=rgb(0, 78, 208) !important]network [color=rgb(0, 78, 208) !important]trunk [color=rgb(0, 78, 208) !important]create [color=rgb(0, 45, 122) !important]trunk1[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]--[color=rgb(128, 0, 128) !important]parent[color=rgb(0, 111, 224) !important]-[color=rgb(0, 78, 208) !important]port [color=rgb(128, 0, 128) !important]parent[color=rgb(0, 111, 224) !important]-[color=rgb(0, 0, 0) !important]port1
% d7 ]7 F/ k0 T5 ~2 G9 Z
[color=rgb(51, 51, 51) !important]$[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]openstack [color=rgb(0, 78, 208) !important]network [color=rgb(0, 78, 208) !important]trunk [color=rgb(0, 78, 208) !important]set [color=rgb(0, 45, 122) !important]trunk1[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]--[color=rgb(0, 78, 208) !important]subport [color=rgb(0, 45, 122) !important]port[color=rgb(0, 111, 224) !important]=[color=rgb(0, 45, 122) !important]sub[color=rgb(0, 111, 224) !important]-[color=rgb(0, 45, 122) !important]port1[color=rgb(51, 51, 51) !important],[color=rgb(0, 45, 122) !important]segmentation[color=rgb(0, 111, 224) !important]-[color=rgb(0, 45, 122) !important]type[color=rgb(0, 111, 224) !important]=[color=rgb(0, 45, 122) !important]vlan[color=rgb(51, 51, 51) !important],[color=rgb(0, 45, 122) !important]segmentation[color=rgb(0, 111, 224) !important]-[color=rgb(0, 45, 122) !important]id[color=rgb(0, 111, 224) !important]=[color=rgb(206, 0, 0) !important]102
% C* w  P. S+ K% P. H& k
[color=rgb(51, 51, 51) !important]$[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]openstack [color=rgb(0, 78, 208) !important]port [color=rgb(0, 78, 208) !important]create [color=rgb(128, 0, 128) !important]parent[color=rgb(0, 111, 224) !important]-[color=rgb(0, 45, 122) !important]port2[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]--[color=rgb(0, 78, 208) !important]network [color=rgb(128, 0, 128) !important]parent[color=rgb(0, 111, 224) !important]-[color=rgb(0, 0, 0) !important]net
) y( {' }0 B. K1 l. O  a' `; Q3 [
[color=rgb(51, 51, 51) !important]$[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]openstack [color=rgb(0, 78, 208) !important]port [color=rgb(0, 78, 208) !important]create [color=rgb(0, 45, 122) !important]sub[color=rgb(0, 111, 224) !important]-[color=rgb(0, 45, 122) !important]port2[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]--[color=rgb(0, 78, 208) !important]network [color=rgb(0, 45, 122) !important]sub[color=rgb(0, 111, 224) !important]-[color=rgb(0, 0, 0) !important]net
/ d" x. e5 T. Y  O
[color=rgb(51, 51, 51) !important]$[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]openstack [color=rgb(0, 78, 208) !important]network [color=rgb(0, 78, 208) !important]trunk [color=rgb(0, 78, 208) !important]create [color=rgb(0, 45, 122) !important]trunk2[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]--[color=rgb(128, 0, 128) !important]parent[color=rgb(0, 111, 224) !important]-[color=rgb(0, 78, 208) !important]port [color=rgb(128, 0, 128) !important]parent[color=rgb(0, 111, 224) !important]-[color=rgb(0, 0, 0) !important]port2

$ N- l/ S. j" l7 i5 {9 t
[color=rgb(51, 51, 51) !important]$[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]openstack [color=rgb(0, 78, 208) !important]network [color=rgb(0, 78, 208) !important]trunk [color=rgb(0, 78, 208) !important]set [color=rgb(0, 45, 122) !important]trunk2[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]--[color=rgb(0, 78, 208) !important]subport [color=rgb(0, 45, 122) !important]port[color=rgb(0, 111, 224) !important]=[color=rgb(0, 45, 122) !important]sub[color=rgb(0, 111, 224) !important]-[color=rgb(0, 45, 122) !important]port2[color=rgb(51, 51, 51) !important],[color=rgb(0, 45, 122) !important]segmentation[color=rgb(0, 111, 224) !important]-[color=rgb(0, 45, 122) !important]type[color=rgb(0, 111, 224) !important]=[color=rgb(0, 45, 122) !important]vlan[color=rgb(51, 51, 51) !important],[color=rgb(0, 45, 122) !important]segmentation[color=rgb(0, 111, 224) !important]-[color=rgb(0, 45, 122) !important]id[color=rgb(0, 111, 224) !important]=[color=rgb(206, 0, 0) !important]102

! z9 Q0 A% F+ H! z. V, J

3 v& i" X" U. X% g

6 L  _6 }" ^& b

0 m( L' E+ n/ q5 ?. a

这里创建了两组4个port,并用trunk模型将它们关联起来了。除此之外,还为Trunk中的subport指定了segmentation-type和segmentation-id。VLAN是目前OpenVSwitch支持的唯一的segmentation type(也是大多数SDN唯一支持的类型),segmentation id就是在虚机中创建subport时指定的VLAN ID。

接下来用parent port创建两个虚机。

[color=rgb(51, 51, 51) !important]

4 ~5 i8 J) O2 e4 p& l' H" m) Z) ]
# Q! D# x& D: M% R/ e6 O" }. Z
, m$ F; K5 ?; V
( I1 w, x1 }* f, `  _. d, F

4 W, N4 z  z/ ?6 m! L
+ X9 s& o. F& h, |- p, W! v8 c8 n

: y6 f! b, i9 f, O8 K# l
) ]( ^; v  U) z

6 @8 M- Z/ D" d% r: C
! X) r1 T+ d1 R& X3 w
[color=rgb(153, 153, 153) !important]Java
6 V3 p9 F2 A+ ]! N  G9 m

1 Y; s8 s; x/ F  Z
7 [) M% q! V; |# @
1

, d+ U+ D% c9 L& E8 h* Y
[color=rgb(49, 124, 197) !important]2
( X5 ~6 I0 K/ G

3 V; j" g. N/ n8 o2 x" v
[color=rgb(51, 51, 51) !important]$[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]nova [color=rgb(0, 45, 122) !important]boot[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]--[color=rgb(0, 78, 208) !important]image [color=rgb(0, 45, 122) !important]ubuntu[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]--[color=rgb(0, 0, 0) !important]flavor[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]2[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]--[color=rgb(0, 78, 208) !important]nic [color=rgb(0, 45, 122) !important]port[color=rgb(0, 111, 224) !important]-[color=rgb(0, 45, 122) !important]id[color=rgb(0, 111, 224) !important]=[color=rgb(0, 111, 224) !important]<[color=rgb(128, 0, 128) !important]parent[color=rgb(0, 111, 224) !important]-[color=rgb(0, 78, 208) !important]port1 [color=rgb(0, 45, 122) !important]id[color=rgb(0, 111, 224) !important]>[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]--[color=rgb(0, 45, 122) !important]key[color=rgb(0, 111, 224) !important]-[color=rgb(0, 45, 122) !important]name[color=rgb(0, 111, 224) !important]=[color=rgb(0, 111, 224) !important]<[color=rgb(0, 78, 208) !important]your [color=rgb(0, 78, 208) !important]key [color=rgb(0, 45, 122) !important]name[color=rgb(0, 111, 224) !important]>[color=rgb(0, 111, 224) !important] [color=rgb(0, 0, 0) !important]vm1
. g# G: W) S4 N/ ~4 |) P! r
[color=rgb(51, 51, 51) !important]$[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]nova [color=rgb(0, 45, 122) !important]boot[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]--[color=rgb(0, 78, 208) !important]image [color=rgb(0, 45, 122) !important]ubuntu[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]--[color=rgb(0, 0, 0) !important]flavor[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]2[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]--[color=rgb(0, 78, 208) !important]nic [color=rgb(0, 45, 122) !important]port[color=rgb(0, 111, 224) !important]-[color=rgb(0, 45, 122) !important]id[color=rgb(0, 111, 224) !important]=[color=rgb(0, 111, 224) !important]<[color=rgb(128, 0, 128) !important]parent[color=rgb(0, 111, 224) !important]-[color=rgb(0, 78, 208) !important]port2 [color=rgb(0, 45, 122) !important]id[color=rgb(0, 111, 224) !important]>[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]--[color=rgb(0, 45, 122) !important]key[color=rgb(0, 111, 224) !important]-[color=rgb(0, 45, 122) !important]name[color=rgb(0, 111, 224) !important]=[color=rgb(0, 111, 224) !important]<[color=rgb(0, 78, 208) !important]your [color=rgb(0, 78, 208) !important]key [color=rgb(0, 45, 122) !important]name[color=rgb(0, 111, 224) !important]>[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]vm2

; i) L; ^- }- K; d$ m

' H0 s. H" v- u5 |$ F% t

, I+ V6 ^4 {# k5 Z! z& H
" ]& Y3 m6 |& P

因为Linux VLAN Trunk需要8021q内核模块的支持,这里用了一个Ubuntu16.04的image。

到此为止,OpenStack的操作完成了。接下来,在两个虚机内部,配置Linux VLAN Trunk。在vm1内部,做如下配置:

[color=rgb(51, 51, 51) !important]
; ?: F3 ~% X6 M% B0 _* l2 P: o

1 V  M! s5 F6 C8 _- Q  m8 {

8 d9 _5 V0 w3 t" O* N* b/ H9 \: v& `
. ~, w! |; g7 D9 y0 ?. b
1 F7 I" @- [7 b+ i

4 U- Q% `. w8 `5 c# ?( S6 F/ M, K

; F* v0 n- F' h' @  t& c' G. c3 ?
% D% a; \6 A- H! M

" h9 I  R, k- z

5 b, Q) ^2 O: ]) |# j6 F' E[color=rgb(153, 153, 153) !important]Java

% L1 ?" s; |2 S
9 g( F- f: g5 ?! |

; O- s3 q3 b% z
1

. o2 h8 o2 e' u4 q$ P8 ^
[color=rgb(49, 124, 197) !important]2

5 R+ `3 G& K) r6 u
3

9 q& X6 [& T. t0 c7 k  v" J9 m: y7 B
& e& h8 ]& K! ?# p7 p6 A
[color=rgb(0, 45, 122) !important]ubuntu[color=rgb(102, 102, 102) !important]@vm1[color=rgb(0, 111, 224) !important]:[color=rgb(0, 111, 224) !important]~[color=rgb(51, 51, 51) !important]$[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]sudo [color=rgb(0, 78, 208) !important]ip [color=rgb(0, 78, 208) !important]link [color=rgb(0, 78, 208) !important]add [color=rgb(0, 78, 208) !important]link [color=rgb(0, 78, 208) !important]ens3 [color=rgb(0, 78, 208) !important]name [color=rgb(0, 45, 122) !important]ens3[color=rgb(51, 51, 51) !important].[color=rgb(206, 0, 0) !important]102[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]type [color=rgb(0, 78, 208) !important]vlan [color=rgb(0, 0, 0) !important]id[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]102

" p) Z( L; a) T. y; U& Q
[color=rgb(0, 45, 122) !important]ubuntu[color=rgb(102, 102, 102) !important]@vm1[color=rgb(0, 111, 224) !important]:[color=rgb(0, 111, 224) !important]~[color=rgb(51, 51, 51) !important]$[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]sudo [color=rgb(0, 78, 208) !important]ip [color=rgb(0, 78, 208) !important]link [color=rgb(0, 78, 208) !important]set [color=rgb(0, 78, 208) !important]dev [color=rgb(0, 45, 122) !important]ens3[color=rgb(51, 51, 51) !important].[color=rgb(206, 0, 0) !important]102[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]address  

* a% C5 m* ~* @( R( ]
[color=rgb(0, 45, 122) !important]ubuntu[color=rgb(102, 102, 102) !important]@vm1[color=rgb(0, 111, 224) !important]:[color=rgb(0, 111, 224) !important]~[color=rgb(51, 51, 51) !important]$[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]sudo [color=rgb(0, 78, 208) !important]ip [color=rgb(0, 78, 208) !important]link [color=rgb(0, 78, 208) !important]set [color=rgb(0, 78, 208) !important]dev [color=rgb(0, 45, 122) !important]ens3[color=rgb(51, 51, 51) !important].[color=rgb(206, 0, 0) !important]102[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]up

0 M4 l1 v1 Y: Z* W3 A: p  y2 m# l

4 K! {9 Z2 P7 X5 k/ ^- i
. G+ M7 @' V' H. V* V. W
; f: h/ a! A7 ]. c' z/ \

这里给虚机的subport配置的VLAN ID是102,这是之前通过OpenStack命令创建Trunk时指定的segmentation-id。这里的ens3.102对应之前创建的sub-port1,为了让ens3.102能使用Neutron DHCP服务,这里将Neutron分配给sub-port1的MAC地址配置在ens3.102上。Linux子网卡默认会跟父网卡用同一个MAC地址,所以也可以在用OpenStack命令创建subport的时候,指定MAC地址。总之,这里我们让虚机内的子网卡的MAC地址与OpenStack Neutron中对应的subport的MAC地址一致。

在vm2内部做同样的操作,只是MAC地址换成成sub-port2的MAC地址。

2.2 验证连通性及DHCP服务

DHCP服务
3 F: @8 A- p5 r: `& u在两个虚机内部,通过dhclient命令获取子网卡IP地址。

[color=rgb(51, 51, 51) !important]
3 R% z1 \3 Z) P& Y! A

. P$ w3 G" b$ j. ^
2 V& a! F' X% P! I
' o# d- ?" G; Z' ^1 D
& q' Q: H5 O8 c! X1 F' ?
! T7 z1 Q& |4 c# ^: x, t7 |
( ^) ^) `* b* ^1 J3 R( Q3 V9 S+ c

* a% R+ ^) I' K  p) A6 Q

4 e& b0 k8 g0 a$ J% O+ X  p1 t+ J

% \' d3 R( `; L/ W( u" n[color=rgb(153, 153, 153) !important]Java

1 }( t" E" Z, z: @
  s3 o2 s! F: a7 L( M& p, h
2 q7 @1 r. y& L! z7 ?/ q  Y
1
1 i1 \2 b/ I+ \$ G6 B% V8 Y$ v# A
[color=rgb(49, 124, 197) !important]2

6 l7 @! f4 b& [) B
3
8 b9 @/ l8 r: w* V* h; F* V2 J
[color=rgb(49, 124, 197) !important]4

  _3 j" C0 o7 R" ~
5
' o( l( c! _2 `3 M2 M
[color=rgb(49, 124, 197) !important]6
, l7 w) B( E, w  r' H1 r

( ~6 {; Q' l6 O0 l! @* d4 Q
[color=rgb(0, 45, 122) !important]ubuntu[color=rgb(102, 102, 102) !important]@vm1[color=rgb(0, 111, 224) !important]:[color=rgb(0, 111, 224) !important]~[color=rgb(51, 51, 51) !important]$[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]sudo [color=rgb(0, 45, 122) !important]dhclient[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]-[color=rgb(0, 0, 0) !important]v[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]ens3[color=rgb(51, 51, 51) !important].[color=rgb(206, 0, 0) !important]102[color=rgb(0, 111, 224) !important]

7 |/ y2 s  h$ v; u) Q1 k* r# X' s
[color=rgb(0, 78, 208) !important]DHCPDISCOVER [color=rgb(0, 78, 208) !important]on [color=rgb(0, 45, 122) !important]ens3[color=rgb(51, 51, 51) !important].[color=rgb(206, 0, 0) !important]102[color=rgb(0, 111, 224) !important] [color=rgb(128, 0, 128) !important]to[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]255.255.255.255[color=rgb(0, 111, 224) !important] [color=rgb(0, 0, 0) !important]port[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]67[color=rgb(0, 111, 224) !important] [color=rgb(0, 0, 0) !important]interval[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]3[color=rgb(0, 111, 224) !important] [color=rgb(51, 51, 51) !important]([color=rgb(0, 45, 122) !important]xid[color=rgb(0, 111, 224) !important]=[color=rgb(206, 0, 0) !important]0x8e2bc124[color=rgb(51, 51, 51) !important])
/ F9 z! @* {$ v! t  s
[color=rgb(0, 78, 208) !important]DHCPREQUEST [color=rgb(0, 0, 0) !important]of[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]21.0.0.6[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]on [color=rgb(0, 45, 122) !important]ens3[color=rgb(51, 51, 51) !important].[color=rgb(206, 0, 0) !important]102[color=rgb(0, 111, 224) !important] [color=rgb(128, 0, 128) !important]to[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]255.255.255.255[color=rgb(0, 111, 224) !important] [color=rgb(0, 0, 0) !important]port[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]67[color=rgb(0, 111, 224) !important] [color=rgb(51, 51, 51) !important]([color=rgb(0, 45, 122) !important]xid[color=rgb(0, 111, 224) !important]=[color=rgb(206, 0, 0) !important]0x24c12b8e[color=rgb(51, 51, 51) !important])

( ^  {! F! g; x8 `. h3 i" @3 B
[color=rgb(0, 78, 208) !important]DHCPOFFER [color=rgb(0, 0, 0) !important]of[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]21.0.0.6[color=rgb(0, 111, 224) !important] [color=rgb(0, 0, 0) !important]from[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]21.0.0.2

' @$ P+ z- A/ h; c% c
[color=rgb(0, 78, 208) !important]DHCPACK [color=rgb(0, 0, 0) !important]of[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]21.0.0.6[color=rgb(0, 111, 224) !important] [color=rgb(0, 0, 0) !important]from[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]21.0.0.2
  c6 R1 `8 c2 ?9 O* Z, {( [/ ]
[color=rgb(0, 78, 208) !important]bound [color=rgb(128, 0, 128) !important]to[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]21.0.0.6[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]--[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]renewal [color=rgb(128, 0, 128) !important]in[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]42323[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]seconds[color=rgb(51, 51, 51) !important].

; U0 k# n+ B  l/ ~, |6 ?
+ @: k2 F- Q# `/ M1 ], E

2 i- j4 k& ^. K4 c8 q2 U% U

3 T; M& C  B, e2 K6 r

可以看到,子网卡也可以通过Neutron的DHCP服务获取IP地址。
, ], ~6 x* m. B# a) jVLAN互通 " x) t$ }; O# q) K8 C
在vm1内部,ping vm2.

[color=rgb(51, 51, 51) !important]
5 i6 U5 R, Q' l# a9 A1 X! N) i

, K' Q/ n. G! J4 F# O

% @# }" q- n  @. N# J

- Q) A$ e* X7 G2 Q' ]% g7 Z+ l: l5 P

$ x6 V7 C: q# Q

: M8 C# W" @$ _- |+ X& _* F  ^0 C
0 d8 S/ J3 t0 m! m. W+ J

# \4 p" x. L3 x( p

7 M0 D# m# J6 S+ X. g
  K4 r, x+ S2 A. c8 ]
[color=rgb(153, 153, 153) !important]Java
# y5 R" {7 ]* Q* k

; S5 J+ _; U* i1 Q6 C8 D& A: n

  n! X: s& g0 k3 X, Z/ p: o
1
  `( j" s1 B7 y2 O/ H
[color=rgb(49, 124, 197) !important]2

  J2 @7 {' L- a& ~1 P: F% r
3
& j6 G$ R1 e( a. q0 c, O6 p, V
[color=rgb(49, 124, 197) !important]4
" p3 f- [8 a: V0 a% \; Z1 @0 F
5
+ b6 J6 C: s8 l

5 \, [8 y0 n; z) v" M
[color=rgb(0, 45, 122) !important]ubuntu[color=rgb(102, 102, 102) !important]@vm1[color=rgb(0, 111, 224) !important]:[color=rgb(0, 111, 224) !important]~[color=rgb(51, 51, 51) !important]$[color=rgb(0, 111, 224) !important] [color=rgb(0, 0, 0) !important]ping[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]21.0.0.7
( C& S* q4 o; ~1 d( w/ L
[color=rgb(0, 0, 0) !important]PING[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]21.0.0.7[color=rgb(0, 111, 224) !important] [color=rgb(51, 51, 51) !important]([color=rgb(206, 0, 0) !important]21.0.0.7[color=rgb(51, 51, 51) !important])[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]56[color=rgb(51, 51, 51) !important]([color=rgb(206, 0, 0) !important]84[color=rgb(51, 51, 51) !important])[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]bytes [color=rgb(0, 78, 208) !important]of [color=rgb(0, 45, 122) !important]data[color=rgb(51, 51, 51) !important].

& M5 t; E4 _$ d7 Q1 t6 e
[color=rgb(206, 0, 0) !important]64[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]bytes [color=rgb(0, 0, 0) !important]from[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]21.0.0.7[color=rgb(0, 111, 224) !important]:[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]icmp_seq[color=rgb(0, 111, 224) !important]=[color=rgb(206, 0, 0) !important]1[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]ttl[color=rgb(0, 111, 224) !important]=[color=rgb(206, 0, 0) !important]64[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]time[color=rgb(0, 111, 224) !important]=[color=rgb(206, 0, 0) !important]10.2[color=rgb(0, 111, 224) !important] [color=rgb(0, 0, 0) !important]ms

2 N' z8 H! l! x2 F. j: c. ~
[color=rgb(206, 0, 0) !important]64[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]bytes [color=rgb(0, 0, 0) !important]from[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]21.0.0.7[color=rgb(0, 111, 224) !important]:[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]icmp_seq[color=rgb(0, 111, 224) !important]=[color=rgb(206, 0, 0) !important]2[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]ttl[color=rgb(0, 111, 224) !important]=[color=rgb(206, 0, 0) !important]64[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]time[color=rgb(0, 111, 224) !important]=[color=rgb(206, 0, 0) !important]0.979[color=rgb(0, 111, 224) !important] [color=rgb(0, 0, 0) !important]ms

# e. L7 T) k+ g- L! q: L) l
[color=rgb(206, 0, 0) !important]64[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]bytes [color=rgb(0, 0, 0) !important]from[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]21.0.0.7[color=rgb(0, 111, 224) !important]:[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]icmp_seq[color=rgb(0, 111, 224) !important]=[color=rgb(206, 0, 0) !important]3[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]ttl[color=rgb(0, 111, 224) !important]=[color=rgb(206, 0, 0) !important]64[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]time[color=rgb(0, 111, 224) !important]=[color=rgb(206, 0, 0) !important]0.817[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]ms
& \- D/ z* C  g9 V2 [

! V0 Z& G8 u3 Y2 R. \
1 Z9 i5 Q) {0 B( u7 i3 N+ M8 w
2 J' Q  N# I2 B( U( y% n; }

在vm2内部,查看收到的包。前面讲过Linux VLAN Trunk的工作过程,Ethernet Frame发送到ens3.102时,已经剥离了VLAN标签。为了查看VLAN信息,所以我们这里直接监听ens3

[color=rgb(51, 51, 51) !important]

' W* L7 }% `: T% V

3 _- w; P, t1 P+ d1 B0 G

! W9 f+ Q" M& Z  T& q
% }# O$ P1 |, c  ^. Q! ^, u
0 ?9 Z+ K1 C) |! z8 z* R
3 I! C* O6 ]$ ?4 A+ T: K+ M
  o( V5 t8 {3 w4 `; E
0 g; a7 j  `, t1 E( x
" M  E7 X7 H- F
% R& n8 U2 V- D& R# X: s* b$ p. X* t
[color=rgb(153, 153, 153) !important]Java
+ o+ j0 S. H& h+ n  |9 ^* j
1 Z. M! T% J7 C# d0 }7 z
0 U: V3 J: U% Q: G, {$ E
1
0 `9 ]1 }9 j: t
[color=rgb(49, 124, 197) !important]2

" {  M/ ?5 Q/ ]6 [. m
3

  z2 L% t; y' a5 X6 A% N: u

1 Z" \$ q# y: \& R( o. V
[color=rgb(0, 45, 122) !important]ubuntu[color=rgb(102, 102, 102) !important]@vm2[color=rgb(0, 111, 224) !important]:[color=rgb(0, 111, 224) !important]~[color=rgb(51, 51, 51) !important]$[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]sudo [color=rgb(0, 45, 122) !important]tcpdump[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]-[color=rgb(0, 78, 208) !important]nei [color=rgb(0, 78, 208) !important]ens3 [color=rgb(0, 0, 0) !important]icmp

+ G2 v* P9 V$ y1 V% _
[color=rgb(206, 0, 0) !important]08[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]42[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]24.256617[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]fa[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]16[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]3e[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]61[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]62[color=rgb(0, 111, 224) !important]:[color=rgb(0, 45, 122) !important]fa[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]>[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]fa[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]16[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]3e[color=rgb(0, 111, 224) !important]:[color=rgb(0, 45, 122) !important]da[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]61[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]99[color=rgb(51, 51, 51) !important],[color=rgb(0, 111, 224) !important] [color=rgb(0, 0, 0) !important]ethertype[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]802.1Q[color=rgb(0, 111, 224) !important] [color=rgb(51, 51, 51) !important]([color=rgb(206, 0, 0) !important]0x8100[color=rgb(51, 51, 51) !important])[color=rgb(51, 51, 51) !important],[color=rgb(0, 111, 224) !important] [color=rgb(0, 0, 0) !important]length[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]102[color=rgb(0, 111, 224) !important]:[color=rgb(0, 111, 224) !important] [color=rgb(0, 0, 0) !important]vlan[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]102[color=rgb(51, 51, 51) !important],[color=rgb(0, 111, 224) !important] [color=rgb(0, 0, 0) !important]p[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]0[color=rgb(51, 51, 51) !important],[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]ethertype [color=rgb(0, 45, 122) !important]IPv4[color=rgb(51, 51, 51) !important],[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]21.0.0.6[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]>[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]21.0.0.7[color=rgb(0, 111, 224) !important]:[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]ICMP [color=rgb(0, 78, 208) !important]echo [color=rgb(0, 45, 122) !important]request[color=rgb(51, 51, 51) !important],[color=rgb(0, 111, 224) !important] [color=rgb(0, 0, 0) !important]id[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]11731[color=rgb(51, 51, 51) !important],[color=rgb(0, 111, 224) !important] [color=rgb(0, 0, 0) !important]seq[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]388[color=rgb(51, 51, 51) !important],[color=rgb(0, 111, 224) !important] [color=rgb(0, 0, 0) !important]length[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]64[color=rgb(0, 111, 224) !important]
* n" W$ m5 D( V4 ^4 T9 C! [: F
[color=rgb(206, 0, 0) !important]08[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]42[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]25.258424[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]fa[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]16[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]3e[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]61[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]62[color=rgb(0, 111, 224) !important]:[color=rgb(0, 45, 122) !important]fa[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]>[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]fa[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]16[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]3e[color=rgb(0, 111, 224) !important]:[color=rgb(0, 45, 122) !important]da[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]61[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]99[color=rgb(51, 51, 51) !important],[color=rgb(0, 111, 224) !important] [color=rgb(0, 0, 0) !important]ethertype[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]802.1Q[color=rgb(0, 111, 224) !important] [color=rgb(51, 51, 51) !important]([color=rgb(206, 0, 0) !important]0x8100[color=rgb(51, 51, 51) !important])[color=rgb(51, 51, 51) !important],[color=rgb(0, 111, 224) !important] [color=rgb(0, 0, 0) !important]length[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]102[color=rgb(0, 111, 224) !important]:[color=rgb(0, 111, 224) !important] [color=rgb(0, 0, 0) !important]vlan[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]102[color=rgb(51, 51, 51) !important],[color=rgb(0, 111, 224) !important] [color=rgb(0, 0, 0) !important]p[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]0[color=rgb(51, 51, 51) !important],[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]ethertype [color=rgb(0, 45, 122) !important]IPv4[color=rgb(51, 51, 51) !important],[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]21.0.0.6[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]>[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]21.0.0.7[color=rgb(0, 111, 224) !important]:[color=rgb(0, 111, 224) !important] [color=rgb(0, 78, 208) !important]ICMP [color=rgb(0, 78, 208) !important]echo [color=rgb(0, 45, 122) !important]request[color=rgb(51, 51, 51) !important],[color=rgb(0, 111, 224) !important] [color=rgb(0, 0, 0) !important]id[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]11731[color=rgb(51, 51, 51) !important],[color=rgb(0, 111, 224) !important] [color=rgb(0, 0, 0) !important]seq[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]389[color=rgb(51, 51, 51) !important],[color=rgb(0, 111, 224) !important] [color=rgb(0, 0, 0) !important]length[color=rgb(0, 111, 224) !important] [color=rgb(206, 0, 0) !important]64

) n" w, }: t' _2 J

# {/ `' Y1 I! E
- M" B$ Z2 U/ N+ S7 w7 \, k) B

: ~" g* c/ \& j' Z" {; I

可以看到,vm2收到的原始Ethernet Frame是带VLAN Tag的。

2.3 原理

注:这部分内容假设你对OpenStack Neutron已经有一定的了解了。
. I" J3 y* x4 u; V虽然上面完成了VLAN aware VMs的配置和Linux VLAN Trunk的验证,甚至虚机内的subport都可以使用Neutron的DHCP服务,但是这里留下了两个问题没有解答。

  • 首先,不用在vSwitch和Physical switch上打开trunk模式,就能支持带VLAN Tag的帧的传递,这中间发生了什么?
  • 其次,一个传输VLAN数据的subport如何能使用定义在VXLAN网络中的DHCP服务?$ l( o+ P) A8 r2 [, o- t

看完Neutron VLAN aware VMs的架构,这两个问题自然就能解决。首先我们看看计算节点上的OpenVSwitch网桥。可以发现,对每个Trunk port,对应的新增了一个网桥。9 b! M' Q, ?# S1 ?3 ~

3 l* I7 ]. u1 s! Z$ C
                               
登录/注册后可看大图

$ {9 [) Y, I8 O$ f2 V3 o, ^在这个网桥的端口中,qvo端口是用来连接虚机的,剩下的端口中,一个是bridge对应的端口,剩下两个都是patch port。其中一个还带了VLAN Tag 102,正是我们配置的segmentation-id。patch port都是成对出现,这里的patch port peer都挂在br-int上。具体的网桥和端口的关系如下图所示:
: F# W5 t& A$ q
3 o, Z( @6 v9 A; u1 l) h
                               
登录/注册后可看大图

, q- q: m9 I3 P/ V. ]左上角是正常的OpenVSwitch上连接的虚机,为什么不是虚机直接到OpenVSwitch网桥?这是历史遗留问题,这里不做解释,大家只需要知道qvo是br-int上用来连接虚机的端口。再看虚线框内,上半部分与原来虚机伸出的部分相同,下半部分就是之前展示的新增的网桥。网桥向上通过qvo连接虚机。向下通过patch port pair 连接parent port,从虚机出来的不带VLAN Tag的帧,从这对patch port走到br-int。同时向下通过patch port pair 连接subport,一个subport对应一对spt-spi,注意的是每个spt都带有相应的VLAN Tag,根据OVS的特性,所有从虚机出来的,带上相应VLAN Tag的帧都会发送到相应的spt,再通过spi发送到br-int。

所以,从虚机出来的Ethernet Frame,根据所携带的VLAN Tag(或者不带VLAN Tag),在tbr网桥上,可以分配到不同的patch port,进而转发到br-int上的不同端口。也就是说,在tbr上,从虚机里一块网卡发出来的Ethernet Frame被分流了。

在br-int上,其实不知道qvo、spi,tpi有什么区别,这些端口对于br-int来说地位是一样的。这些端口分别在不同的网络中(最开始为parent port和subport分别创建了网络),br-int根据端口所在的网络,将虚机发出来的Ethernet Frame打上Local network ID(又一个VLAN ID,类似于VTEP中VLAN ID与VXLAN ID对应中的VLAN),发往br-tun。在br-tun根据Local network ID转换成VXLAN数据发送出去。

在对端,经过br-tun发送到br-int,br-int根据不同的网络,将数据发送到相应的qvo,spi,tpi。这里看spi这条线路,因为patch port的相连,数据发送到了tbr网桥,再经由qvo发向虚机。由于qvo没有自己的VLAN Tag,所以它将保留入口端口的VLAN Tag,也就是VLAN 102,最后VLAN 102的帧发送给虚机。

总结一下Ethernet Frame的处理流程。从虚机发出来的VLAN数据,在tbr网桥通过相应的patch port 对,发送到br-int。在patch port对的传递过程中,VLAN Tag由虚机内定义的VLAN ID变成了br-int内部的Local network ID。br-int将数据发送给br-tun。br-tun根据自身记录的VLAN ID与VXLAN ID的对应,将VLAN数据中VLAN Tag去除,并将剩余的Ethernet Frame封装成VXLAN数据,在VXLAN tunnel上传输。

对端收到VXLAN数据,在br-tun转换成VLAN数据,VLAN Tag是Local network ID,再发送给br-int。br-int根据Local network ID和目的MAC地址,将VLAN数据从对应的端口(spi)发出。经过patch port 对的传输,VLAN Tag由Local network ID变成了spt上的VLAN Tag,最后通过qvo发送给虚机。虚机收到还是VLAN 102的数据,但是数据在中间是通过VXLAN网络传输。

所以为什么不需要vSwitch和Physical Switch对Trunk模式进行支持?因为VLAN数据换成了VXLAN数据,传输的都不是VLAN了,自然不需要交换机配置Trunk。为什么子网卡能使用Neutron的DHCP服务,因为数据被换成了Neutron network网络数据(VXLAN),接入到Neutron network,自然就能使用Neutron network内的服务。

三、SDN中VLAN的实现

Neutron在OpenVSwitch上实现的VLAN aware VMs原理在上面介绍过,不得不说,这个方案比较复杂,希望我已经说清楚了。虽然这个方案不依赖物理网络配置Trunk,但是需要创建额外的网桥和端口,对应的转换步骤也太多了。这么实现有Neutron的历史原因,也有Neutron轻度依赖OpenFlow的因素在里面。我们接下来看看在OpenFlow中,如何实现VLAN aware VMs。

VLAN aware VMs的核心思想是,用Neutron tenant network的overlay网络,来传输Linux VLAN Trunk发出来的各种VLAN数据。像上面的介绍,就是用VXLAN网络来传输虚机发出的VLAN数据,在进出虚机的时候再对VLAN Tag做相应的处理。相同的功能在OpenFlow中实现就简单的多,我们以Dragonflow项目的实现为例,具体介绍在Spec for VLAN aware VMs。只需要在网桥上添加几条OpenFlow流表,就能识别虚机发出的数据,并分发到不同的Neutron tenant network,进而通过Neutron tenant network传输。

在虚机的出口,添加下列流表:

[color=rgb(51, 51, 51) !important]
! y; @7 T/ E" t% G8 [

: M) a* r) B5 y1 G0 A" b

0 C1 j- L- H$ {1 n6 q/ V5 [

$ ^) [2 ^: h+ z+ m! O/ y

5 n/ `0 {  s0 d& I

: Q' q, G2 d: G
% q8 k* _3 B& c

% \% R# @6 Y- G$ {% x' M

( v& h% d6 a. {' Y! @7 G5 R- E$ u, l) B
0 L0 S- ?" |2 Q0 c0 ]  Q! P3 H
[color=rgb(153, 153, 153) !important]Java
$ ?( K# n! H: O3 X; M
( Y2 V) L/ t/ J, o

% p; p8 j, E, s# Z
1

* G1 D: v, _1 N4 w1 E- Q  [6 K$ z, W
[color=rgb(49, 124, 197) !important]2
8 F9 b7 f' v4 x
6 e' y- `, a8 L$ j
[color=rgb(0, 45, 122) !important]table[color=rgb(0, 111, 224) !important]=[color=rgb(206, 0, 0) !important]0[color=rgb(51, 51, 51) !important],[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]priority[color=rgb(0, 111, 224) !important]=[color=rgb(206, 0, 0) !important]150[color=rgb(51, 51, 51) !important],[color=rgb(0, 45, 122) !important]in_port[color=rgb(0, 111, 224) !important]=[color=rgb(206, 0, 0) !important]183[color=rgb(51, 51, 51) !important],[color=rgb(0, 45, 122) !important]vlan[color=rgb(51, 51, 51) !important],[color=rgb(0, 45, 122) !important]vlan_tag[color=rgb(0, 111, 224) !important]=[color=rgb(206, 0, 0) !important]102[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]actions[color=rgb(0, 111, 224) !important]=[color=rgb(0, 45, 122) !important]strip_vlan[color=rgb(51, 51, 51) !important],[color=rgb(0, 45, 122) !important]load[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]0x168[color=rgb(0, 111, 224) !important]->[color=rgb(0, 45, 122) !important]NXM_NX_REG6[color=rgb(51, 51, 51) !important][[color=rgb(51, 51, 51) !important][color=rgb(51, 51, 51) !important],[color=rgb(0, 45, 122) !important]load[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]0x2[color=rgb(0, 111, 224) !important]->[color=rgb(0, 45, 122) !important]OXM_OF_METADATA[color=rgb(51, 51, 51) !important][[color=rgb(51, 51, 51) !important][color=rgb(51, 51, 51) !important],[color=rgb(0, 78, 208) !important]resubmit[color=rgb(51, 51, 51) !important]([color=rgb(51, 51, 51) !important],[color=rgb(206, 0, 0) !important]5[color=rgb(51, 51, 51) !important])[color=rgb(0, 111, 224) !important]

) Q1 s* w, Q9 E9 q4 D  }. G
[color=rgb(0, 45, 122) !important]table[color=rgb(0, 111, 224) !important]=[color=rgb(206, 0, 0) !important]0[color=rgb(51, 51, 51) !important],[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]priority[color=rgb(0, 111, 224) !important]=[color=rgb(206, 0, 0) !important]100[color=rgb(51, 51, 51) !important],[color=rgb(0, 45, 122) !important]in_port[color=rgb(0, 111, 224) !important]=[color=rgb(206, 0, 0) !important]183[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]actions[color=rgb(0, 111, 224) !important]=[color=rgb(0, 45, 122) !important]load[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]0x166[color=rgb(0, 111, 224) !important]->[color=rgb(0, 45, 122) !important]NXM_NX_REG6[color=rgb(51, 51, 51) !important][[color=rgb(51, 51, 51) !important][color=rgb(51, 51, 51) !important],[color=rgb(0, 45, 122) !important]load[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]0x1[color=rgb(0, 111, 224) !important]->[color=rgb(0, 45, 122) !important]OXM_OF_METADATA[color=rgb(51, 51, 51) !important][[color=rgb(51, 51, 51) !important][color=rgb(51, 51, 51) !important],[color=rgb(0, 78, 208) !important]resubmit[color=rgb(51, 51, 51) !important]([color=rgb(51, 51, 51) !important],[color=rgb(206, 0, 0) !important]5[color=rgb(51, 51, 51) !important])
& q! o/ D. N: S& e5 f1 D' F
) o; |# S) z9 H2 o& Y
" E/ n8 Y" F3 A/ H  w- c$ j
. @" \& E# r) R6 q& Y. q$ Z* W8 P

这里的REG6表明入口端口,METADATA用来识别网络,可见,在table0就已经完成了将虚机中一块网卡发出的Ethernet Frame根据VLAN Tag分成不同的通道,并识别相应的网络。之后的传输不需要区分究竟是不是子网卡的数据,就是当成普通的overlay tenant network传输。

在虚机的入口,添加下列流表:

[color=rgb(51, 51, 51) !important]

" Z. H/ ~: i  t6 h$ X0 r) y

9 F/ x' C+ {% Z! b" B# _: E

/ h8 o! t1 [+ ^

) a4 a  Y" H; n& ]# Q
; u' Q. U6 o0 U9 A) K3 ^3 @
' t, D0 ~& X6 r+ ?7 i4 g

0 ]: B2 w$ b- b& J) {
2 _0 }9 g6 `0 K; Q

3 t$ M+ B9 f7 Q- H, a

7 [7 J% H' k) M& c) R4 s[color=rgb(153, 153, 153) !important]Java

) d9 d/ \* {1 `" V6 u1 o& B

3 R6 b/ I4 ?2 `" M: Q; @# o8 f2 L) \

4 X5 ]2 v: O& r
1
% M. A9 R  S8 j2 i7 Z* i
[color=rgb(49, 124, 197) !important]2
% i/ H4 O/ x! m

5 j- k" W2 i3 S1 m9 Z+ T  B6 x
[color=rgb(0, 45, 122) !important]table[color=rgb(0, 111, 224) !important]=[color=rgb(206, 0, 0) !important]115[color=rgb(51, 51, 51) !important],[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]priority[color=rgb(0, 111, 224) !important]=[color=rgb(206, 0, 0) !important]100[color=rgb(51, 51, 51) !important],[color=rgb(0, 45, 122) !important]reg7[color=rgb(0, 111, 224) !important]=[color=rgb(206, 0, 0) !important]0x168[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]actions[color=rgb(0, 111, 224) !important]=[color=rgb(0, 45, 122) !important]mod_vlan_vid[color=rgb(0, 111, 224) !important]:[color=rgb(0, 45, 122) !important]vlan_vid[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]0x10066[color=rgb(51, 51, 51) !important],[color=rgb(0, 45, 122) !important]output[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]183
; ]3 }  ^  Y  o8 t6 k2 F2 ~+ G* R
[color=rgb(0, 45, 122) !important]table[color=rgb(0, 111, 224) !important]=[color=rgb(206, 0, 0) !important]115[color=rgb(51, 51, 51) !important],[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]priority[color=rgb(0, 111, 224) !important]=[color=rgb(206, 0, 0) !important]100[color=rgb(51, 51, 51) !important],[color=rgb(0, 45, 122) !important]reg7[color=rgb(0, 111, 224) !important]=[color=rgb(206, 0, 0) !important]0x166[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]actions[color=rgb(0, 111, 224) !important]=[color=rgb(0, 45, 122) !important]output[color=rgb(0, 111, 224) !important]:[color=rgb(206, 0, 0) !important]183
/ G, R* X3 M4 o1 O/ G: W0 p! u

, @5 e+ O/ P$ x% }/ X

3 h. A5 z( i  E, \: B4 h8 t
) Q: _* c/ \/ a! y

“mod_vlan_vid:vlan_vid:0x10066”就是打上VLAN Tag102,可以看出不同网络的数据,打上不同的VLAN Tag(对于parent port不打VLAN Tag)发向了同一个端口183(虚机网卡)。
6 a) l: [8 p) J) f# A3 y' }( c没有多余的网桥,没有网桥上换来换去的VLAN ID,仅仅是在入口和出口处去除VLAN Tag和打上VLAN Tag,几条流表就实现了所有的功能。简单的实现一般意味着更高的效率和更少的错误,因此使用SDN方式实现VLAN aware VMs更具有优势。

四、VLAN Trunk在NFV中的应用

最后我们再看看VLAN Trunk在NFV中的应用吧,这个在最开头一些简单的介绍,这里来说个用例。一个多路复用设备,需要连接多个子设备,子设备的数目是不确定的,且有可能变化,并且要求子设备间网络是隔离的。当然,我也可以给多路复用设备配置多块网卡,但是由于子设备数目不确定,网卡数目是不确定的。这个时候可以将多路复用设备的一块Ethernet网卡配置成VLAN Trunk port,在之上创建相应的subport。子设备上的网卡也配置成VLAN Trunk port,并创建对应的subport。由于配置的VLAN不一样,不同子设备之间的网络是隔离的。并且多路复用设备的subport是可以动态删减的,这满足了子设备数据是不确定的要求。具体如下图所示:
( [. p: v( b# }  ?8 @. H


2 X: S* U4 H3 q: n) k0 I                               
登录/注册后可看大图

7 W* E9 a- O; h6 o- ~不论是VLAN Transparency还是VLAN aware VMs,都是为了使得OpenStack中的虚机能够使用Linux VLAN Trunk功能。VLAN Transparency依赖vSwitch和物理交换机的配置,不说实际物理交换机的复杂性,单就是vSwitch也不一定支持Trunk模式。VLAN aware VMs通过一系列的转换,摆脱了对vSwitch和物理交换机配置的依赖,走在网线上的数据甚至都可以不是VLAN数据,这比VLAN Transparency进了一步。而通过SDN实现VLAN aware VMs可以大大简化实现过程,又更进了一步。

您需要登录后才可以回帖 登录 | 开始注册

本版积分规则

关闭

站长推荐上一条 /4 下一条

北京云银创陇科技有限公司以云计算运维,代码开发

QQ|返回首页|Archiver|小黑屋|易陆发现技术论坛 ( 蜀ICP备2026014127号-1 )点击这里给我发消息

GMT+8, 2026-4-8 23:58 , Processed in 0.088566 second(s), 22 queries .

Powered by Discuz! X3.4 Licensed

© 2012-2025 Discuz! Team.

快速回复 返回顶部 返回列表