易陆发现互联网技术论坛

 找回密码
 开始注册
查看: 3880|回复: 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,提供网络支持。
8 `# q# j* T( i/ Z4 u0 B


7 b0 z) T& C- x" x$ u. J$ g& G                               
登录/注册后可看大图
; x- p! \/ g+ g( g
主机的Trunk port是指在主机的一块网卡上添加多个带有不同VLAN ID的子网卡。通过子网卡发送的数据,打上VLAN Tag,被发送出去。由于带了不同的VLAN Tag,子网卡可以认为连接在VLAN Tag标识的网络中。这样,不用增减主机的网卡,就可以将主机添加到新的网络中。更主要的是,这种方式的网络添加是动态的。

主机的Trunk port有什么用?一个应用是在NFV场景下,一个VNF(Virtual Networking Function)可能需要同时连接多个网络。当然最简单是一个网络对应一块网卡,但如果网络数量巨大,网卡数量也巨大,一方面这不现实。另一方面,连接的多个网络也是动态增减的,如果每次增减都插拔VNF的网卡,明显也是不能接受的。如果用Trunk port,当需要动态连接多个网络时,只需要动态的创建/删除相应的子网卡即可。
- L1 q8 S  Y& b2 t3 p/ M. w% g* WVLAN 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的工作原理。$ _( r: r; A' Q% S/ V

% O0 M" A( Z7 M9 `, A" K, n
                               
登录/注册后可看大图

/ s( G3 f$ ?% n+ l$ V8 m如果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。/ H* n; n) O9 U" ^! V


% O5 l, r: z' l- r- X                               
登录/注册后可看大图

1.2 VLAN Trunk简介

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

第一种方法是把每个交换机上的每个VLAN都连在一起。如下图所示:! Q- i7 _% ]2 K


$ m' Z/ e) N" X                               
登录/注册后可看大图
2 @+ M8 J. f  u# o( p
图中有两个交换机,各有两个VLAN,为了让VLAN能正常工作,将VLAN1和VLAN2分别连接起来。如果是两个交换机,两个VLAN还好,如果是100个VLAN,那么这里需要有100条线路,200个交换机端口。这么连接可以吗?可以,只要有钱,因为这里的线路和交换机端口都是钱。这种方法,运维和成本支出比较大,不实用。

第二种方法是通过VLAN Trunk连接交换机。VLAN Trunk是一种网络设备间的point-to-point的连接。一条VLAN Trunk线路可以同时传输多个甚至所有的VLAN数据。
* ^' X: y0 ]. a6 L' u, r& r  F1 o5 h

: G* @  I0 i  ?, V8 K2 S
                               
登录/注册后可看大图

8 L% R+ I3 d# q/ V8 v+ @8 c+ x8 n4 B由于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发送到最右侧的服务器5 P9 {3 J. O% E! {9 H! i

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

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

如果有多个交换机需要连接,通常会用另外一个交换机连接它们,如下图所示,交换机之间都通过Trunk port相连。! \3 B/ y2 |: ~" b  J


& X3 q, c( F9 v# L                               
登录/注册后可看大图

" l0 N! _& ~& ?. b红色框内的交换机的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]
/ _8 ], ~5 N  @  E1 P: I
( [5 {% O9 Q6 W
- M, ^8 X* j8 y- W  f4 C, T
& p9 ^2 K$ I7 h) C9 q
0 r+ x) `  v# ?6 B6 T* [1 `) q

7 C/ y3 s2 ^  y
1 [8 R1 i4 q1 a. ?+ W0 v5 `$ V1 J
2 P: \8 x4 E$ y! N' U: n' B# O/ c

* W  ~' D2 }. f1 w7 t1 _8 n
2 x1 m' l) U1 d
[color=rgb(153, 153, 153) !important]Java

' \9 T0 t! J- d* H4 o3 W2 |
5 X' W( G+ Q) S1 T

- J/ u+ I' s7 c1 Y7 Y
1
# S0 ^+ L& R0 _9 A9 F( _  I

# P% C2 D9 @7 V5 T" W% M; d
[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

0 h$ o' M' A% v8 C
( a2 ?# W1 `7 ^. G8 k5 a- _
: q7 v: m+ P+ e/ W

4 S/ m6 Y- W2 N3 d* c1 ^

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

  • 外界传入的带VLAN Tag 102的包,到达了eth0,VLAN Tag 102被去除,然后不带VLAN Tag的Ethernet Frame被重新发往操作系统网络栈,再发送到eth0.102。
  • 从eth0.102发送出来的帧,被打上VLAN102的标签,再从eth0传出。
    2 p, N5 i5 b+ [- O

应用层面,收发的还是不带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
    4 z' \9 V5 c$ }4 P1 T6 q4 h& z4 i2 Q

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]

; t7 n5 D; h. ^9 z

5 P- F( f! D% Y7 _. v1 l
% X; E3 Q" K( {% Q  N$ J5 S% r

& R  H  Y$ c9 f$ ~) Y

0 w$ k* j4 B7 n4 H( q9 _7 J

+ `7 v$ X$ x9 P  F2 C! h' s: A

( H+ N' m: D6 B: {7 t7 `1 r9 f3 h4 e
1 r) C) I9 l5 D6 w' K% e' w; R9 n
! E) N, z; e4 H

' `/ b  ]/ @$ N5 @: n[color=rgb(153, 153, 153) !important]Java

9 L0 ~- K; i3 ]" W9 P2 F9 l

- Q& n8 ^) o7 e, N. T& h2 w

5 u7 a8 P5 l) Q
1
& ]) e  ~- h" s" m
[color=rgb(49, 124, 197) !important]2

+ g9 t5 t6 \+ t9 N5 Z) N
3

! I$ T% ]  w1 q* u! m) [# Z! o
[color=rgb(49, 124, 197) !important]4
, ?$ ]  a: C1 S

& _. o4 q/ Y# u# g2 Y
[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

9 M! G; R; G# a, @" Q% T4 |
[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
% ^9 |2 t; i! S" D" o. _6 Y
[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
; Q) `# [3 f% `2 I3 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]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
. G  z8 O7 k- j+ l7 t& m
. ?" w9 [7 d6 o" ]7 m1 g
0 K: e  o. E( I% m
8 m1 x) ?# c; o. }! B

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

接下来创建Trunk port和subport。

[color=rgb(51, 51, 51) !important]
- t: n' R9 z  V' K
: X/ ~& w6 M  X# P6 r8 I0 Z' l

  e1 y, k% U( N
: q2 R2 m# M/ ?0 r0 M, i
! b: F' D% H$ U1 I" ?  C- I" [  {

  Q0 s6 D0 H7 x( I

8 l, X1 M; E/ v$ g$ L$ o* e6 \; O% y

! j; @) Z6 O2 e2 a" }+ Y

+ K( V. [4 v( _( G/ n

' B/ I0 e# E( H# w' Z6 L5 i# v[color=rgb(153, 153, 153) !important]Java
9 L- |' @1 f$ w7 c

+ |/ m: J: u8 A4 @6 @
* y7 q1 b. }( E* k* d; U
1

) d7 n9 x3 T+ V9 q
[color=rgb(49, 124, 197) !important]2
9 D* A0 |$ h5 w- T/ {
3

2 A  h- y6 d- Q
[color=rgb(49, 124, 197) !important]4
( n3 k; \) j. q) U% o7 E; P
5
! t8 @- M! j% X- Y$ `# _
[color=rgb(49, 124, 197) !important]6
) w& O2 n9 {: n+ R
7
% S. b) w: {$ r4 J! i- Y. c. {/ G( ^
[color=rgb(49, 124, 197) !important]8

8 l  N* O2 ]  n% Z8 H. n

+ k7 K8 R! `" v: K5 Q% M9 D
[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
, @, {3 u- v8 U; 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(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

5 ^  B  |, R8 S! R' M3 ^: G5 f. 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]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
9 H6 U  F/ u. V4 v; z! g
[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
0 b+ B' f- X6 S& `' L
[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
' W4 L8 e' n' _* c$ S+ w# y* 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(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
1 y  c9 \9 u  \9 h
[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

9 m( |1 m7 |( _
[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
  h* s1 v+ j/ w9 ]9 G2 b
1 W. t) Q( z. H: f0 |* }" C
0 P3 w6 _$ D7 D0 u& ]  Q
& B& b: g& a3 ?- Y) \" i. E8 E9 D8 P9 |

这里创建了两组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]
9 N0 T, m8 H4 N5 c

( O; ~5 L+ `, F6 m# c& D7 F/ C
% @* a3 R. N; R0 y' x8 I  R

, S- Z8 j3 d9 O/ _0 V4 @

6 k8 |% x; I& _4 Z

2 h- w1 x% K$ x' K! E2 g
( O: N! P4 {" ]7 ?/ I

# q, N# u- d8 C

! \1 ]/ c" C" o. q" G
2 R; w5 l+ c( O' {( }0 N# N
[color=rgb(153, 153, 153) !important]Java
1 K% k/ p9 z' {% `8 M8 W

/ B) x  W" b, s# J9 A/ g

! s. W1 A1 r6 c. K/ _& ]! ?8 L
1

) @4 |7 }5 `0 q
[color=rgb(49, 124, 197) !important]2

- X0 @% ]+ B0 c( n. m

; P8 u6 h* c) d" k( _& }
[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

% k% g. ~# w/ e
[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

$ k5 {1 b- g) D' p% h% }# N7 C; p

5 D2 t5 z9 [4 o3 z

. H! C  e. J4 J5 M; ^$ ~

1 }5 u+ T) b' H+ Y2 w( g5 B0 [. I; V

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

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

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

2 z* J2 Y. {0 \/ x1 {& _3 E& N
9 s5 P9 o$ S- k! w, {0 H# G

+ F( m4 t6 w! `. I+ L8 n! |, V+ Q
8 e7 e# J: n6 T1 j
! e3 C( e. Y8 |' W

1 p' Y2 R6 r4 i8 {

4 z* K6 B# G% S7 j# C

3 H, n$ s0 G0 u8 I! Z8 [5 ~
' W7 |+ P# G3 J; M+ [3 d- [

2 ~6 N# Z( m" ^' M( D[color=rgb(153, 153, 153) !important]Java

2 }/ [: p' V5 n$ u: Y( g1 m2 |

# Y1 o2 m) c) y% \$ R
4 @! o: g0 E3 j2 g0 G* L
1

& q: n  _8 D" r) ^8 y6 t, H1 |! Z8 x
[color=rgb(49, 124, 197) !important]2

3 i7 h, B( ?6 p8 E' H) o2 d: E
3
7 c; B  J- t8 B* u; a

  z" K# Q! Z, R2 C% M0 k
[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
8 ?4 U3 j( y5 s. E1 A* T6 |
[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  
2 w* Z  `3 P3 O4 [
[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

7 ?2 z& C- R; c8 |) J
* `: K) _' B8 L1 S% a

, s4 x9 }) x2 I8 O1 ?" S
- m" G9 H6 X! o8 u, Q

这里给虚机的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服务 & I3 O% k: H6 G
在两个虚机内部,通过dhclient命令获取子网卡IP地址。

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

, |/ G& m7 O- Q; n& R
2 j3 \8 `9 E5 ?1 W" _6 T4 H0 X

2 U; N7 J* K/ m* A" V' W
5 o, p7 |) Z2 t) i3 V

) ?5 L0 t, B) [. r6 N; P) u$ d

8 A( a1 D9 o0 H8 R7 ^3 k
$ `' w& H* X0 L9 X8 m% B
; M4 Z) @* {7 c/ H: P9 k- f

$ k2 C8 q8 v4 H0 ]1 Q

% i8 X; A6 Q' @+ }[color=rgb(153, 153, 153) !important]Java
( {- q* D) }6 }( w6 C; Q
; G9 ~! C/ B4 H9 `

. T5 o$ W; y' B( p$ Q- c" _  a
1
+ v' O0 W5 _1 X* ~
[color=rgb(49, 124, 197) !important]2
' G4 D* ]7 ]4 P# @, V" v- K
3

" K6 Y4 k" w2 y" |' z% m5 D
[color=rgb(49, 124, 197) !important]4
4 }5 y* g7 ^: \
5

% F( N& {7 V' Z
[color=rgb(49, 124, 197) !important]6
$ @3 V  w1 ~% C. R4 x/ X* J
* z/ `) r/ H8 l* C6 B5 @3 K
[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]
( H8 F) o5 A6 j- g' i  p, h
[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])
+ d# g' `' v0 X7 K1 i9 {0 d
[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])
1 O" T9 g7 v& A
[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
. V/ f" b9 g' P5 r
[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

/ f5 N6 `9 z0 \1 o2 J) |; @
[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].

- \. `3 e- ~: V; i

$ ~. Z. E& T! M  ~- ^$ e9 `

" U0 D+ D( _% ~( i4 |

0 [( \+ Y: b) m+ _  x0 v

可以看到,子网卡也可以通过Neutron的DHCP服务获取IP地址。
& w. Z+ W. Y8 L. i. L% B9 N8 q3 EVLAN互通 $ z  ?' m, W) v, h/ w+ K( U. B
在vm1内部,ping vm2.

[color=rgb(51, 51, 51) !important]
9 I" @3 z) T7 f" m8 r4 T

8 ~3 s/ u2 K  b3 O( f0 S
. m6 k; S* r8 p% `) O. H8 ^. l  p

# g% D- p  B1 i! n& I

: g; `' z' T: x% ~* R
4 E, ~+ \) t' e9 n. I' T
) F- J8 |' V# h6 ]
" r( Y3 }% k/ [5 s5 h' ]- A  ^
& ?% I/ H- \, O5 g4 s* ^& k% E" I
' a: s1 i7 X  N' p- z8 G9 @$ ?
[color=rgb(153, 153, 153) !important]Java
2 w( o0 _1 Y7 h; G3 \5 ~

- P* |7 O7 Z: L; U" I5 A

$ `& P8 a6 [( J" L' w- n# q- k
1

6 Z9 @$ |7 P* A  z& I# u7 X
[color=rgb(49, 124, 197) !important]2
4 E2 Z' |/ B6 B) K5 G) C
3

2 ?) [) \/ m0 }9 u. h0 l
[color=rgb(49, 124, 197) !important]4

: N2 x, J' H( x7 ?- j. L
5
& r9 y7 E$ S7 M3 b) d

% b5 G1 t% W* M3 o* S
[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
. G7 e1 e6 n) W2 [$ @
[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].
* d8 L# G1 z" t& H9 C9 }
[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
9 z) ]1 z4 C: z3 ]1 y
[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
& l# ?# D' e: q* P& c8 U
[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
7 G# @7 V8 d% U) U) V  F" h; `( m

! U, C, a- {5 t5 {

2 H3 S# M: r* ?$ `. d; N+ k
% I/ v/ [5 c; s$ x% n% c: ?- a

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

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

* l. |3 U, u8 m* ~& f1 V& n3 F( `# L

! }  N& u) u% @5 K
4 I5 n& i1 y8 L6 e
) u+ Q+ c$ R( r6 A
$ H% O7 a2 g& e

$ B  H1 [& n# w, A
6 V0 v  D* _  W, `5 {3 Z

# \9 ]5 ?: }! Q- T  N9 ?
9 g$ z, C7 B. P8 P1 Y% y0 V3 C- H$ r

' [" H' _& T* L( x3 h& b3 r5 f' B[color=rgb(153, 153, 153) !important]Java

# y6 u+ i- A6 A$ n& }4 l
8 m7 j3 I4 q; A& N1 d
2 _: Q$ Z* U% g! y
1

* r/ P: P8 I: p! R- [
[color=rgb(49, 124, 197) !important]2
" D: R, k( s9 d' U0 ?1 e$ C1 |0 b
3

# n3 I7 v8 V- B4 ~2 S/ y( b0 S7 Z! ~
+ B( c7 n- Z' J+ ^" 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

3 C- i( X5 G' k% n8 f' A
[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]

4 G4 n1 h- Y9 ?: N' g* u
[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
/ [4 [- t+ [' n8 L

" j9 Z+ }& c' Y6 v% _$ W& G" O

2 M6 n0 C9 {. [! n5 P2 K" R

# S( F: w& H, H& }- O" J+ m, o

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

2.3 原理

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

  • 首先,不用在vSwitch和Physical switch上打开trunk模式,就能支持带VLAN Tag的帧的传递,这中间发生了什么?
  • 其次,一个传输VLAN数据的subport如何能使用定义在VXLAN网络中的DHCP服务?
    % I# ]$ V& r& ]7 p- m

看完Neutron VLAN aware VMs的架构,这两个问题自然就能解决。首先我们看看计算节点上的OpenVSwitch网桥。可以发现,对每个Trunk port,对应的新增了一个网桥。
  i' C8 B. t, O# u1 N- O


7 ~9 V0 h  {% T* O: _                               
登录/注册后可看大图
7 d0 a) P9 M5 L
在这个网桥的端口中,qvo端口是用来连接虚机的,剩下的端口中,一个是bridge对应的端口,剩下两个都是patch port。其中一个还带了VLAN Tag 102,正是我们配置的segmentation-id。patch port都是成对出现,这里的patch port peer都挂在br-int上。具体的网桥和端口的关系如下图所示:
: Z4 T  C$ n9 Z7 j- N" \* y$ i: O

/ {1 R" r3 Q  M4 v( L, C, a4 p                               
登录/注册后可看大图
& y; t1 |1 l3 e$ u, b) I6 |3 a5 C* y1 J
左上角是正常的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]
- w/ _  O+ O# E8 J, w7 [$ ~/ T
( A+ S$ Z# j- R# d
$ q- ?3 x0 \1 S* ^5 x7 ?+ I1 s
# s! [/ `# {, n/ E/ b

( Z3 H7 q  f: c( i$ a6 @6 ]& K
4 t0 v4 M8 g" l: k+ T. @) h9 q- N
# p( I4 O& S% }" f9 j7 i( T4 H0 e

$ t9 b3 ~% b4 k) q% B" B0 {( y

# ?$ z8 Y( w; }( h: L# E# ^

% N! P& [% u; h. g" H[color=rgb(153, 153, 153) !important]Java

7 J  B* n5 J* y: R. o
; d4 j' i( m# T1 n3 ]3 `

: I  _+ ~  |- Y; L8 y9 G4 K
1
4 e' R0 ]7 [8 P( f* q9 M" z
[color=rgb(49, 124, 197) !important]2

+ c3 f  R3 Y9 {7 P2 A& @* Q

" G0 C. ~7 Y) m* O. j$ U: o* {
[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]
# a* M" M/ b& 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]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])

! R: u+ f& Y1 O# ]0 X0 g0 }! K" r

) \9 @, W3 x4 N, Y) a. t

) ~+ W% I' Q3 k7 G5 P
. }. p( h! }" b% H4 V$ m

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

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

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

6 {7 B* I; K) \9 @6 A

& ~8 H9 P6 f6 D  N* B
2 Z/ J3 B" i' P* w5 z

  ?6 ?, j; l$ a: n6 o: ?
, l+ o, A% p( x. v  e# m
& _% L' P5 ~3 k9 I! R. V

9 |6 p' W) D! U! j  V$ \! ~& n4 }

. p1 W0 ]2 ~7 d3 F
5 ?3 j  \% \* m
& J4 l4 ~0 ?$ b' ]
[color=rgb(153, 153, 153) !important]Java
0 O1 s, X$ O7 g6 ^
6 a* |; R3 I) X. g
* h( j/ K) \4 S8 }! J# f( p) a
1

* y- X$ j& A* Q% p. Q0 N, \
[color=rgb(49, 124, 197) !important]2
, V0 C7 e8 e5 W  {/ o0 J

8 b) C7 x+ w1 _
[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 n5 C# [% C/ }8 \
[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

6 o0 {$ T0 Q4 V
) d0 S. s! F7 i" D

% q1 D& S" z2 X! Y
& w9 A% d7 i7 I* W. v# z

“mod_vlan_vid:vlan_vid:0x10066”就是打上VLAN Tag102,可以看出不同网络的数据,打上不同的VLAN Tag(对于parent port不打VLAN Tag)发向了同一个端口183(虚机网卡)。
1 [- ?0 ]; a" x2 G没有多余的网桥,没有网桥上换来换去的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是可以动态删减的,这满足了子设备数据是不确定的要求。具体如下图所示:4 @+ e' J" k3 I


7 M- R0 a0 Q( s0 A                               
登录/注册后可看大图

6 i$ J, o; I% x) o, [3 |" X: h$ Y不论是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|小黑屋|易陆发现技术论坛 点击这里给我发消息

GMT+8, 2026-4-8 12:08 , Processed in 0.102929 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

© 2012-2025 Discuz! Team.

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