第 2 章 OpenStack与网络

第 2 章 OpenStack与网络

在OpenStack的各类技术群中,我经常碰到一个现象,那就是搞OpenStack的人通常更熟悉软件,而在网络方面相对陌生一些。这也是让很多人头痛的地方,正是因为对网络知识了解不足,很多初学者在部署OpenStack时知其然而不知其所以然,即使出现问题也难以解决。

网络不仅对于初期部署OpenStack很重要,而且对整个线上运行的云系统更重要。如果网络规划不合理而使流量分布不合理,就会在云系统中形成很多瓶颈,云系统的性能就会受到很大的影响。特别是在很多初学者还不具备完全灵活应用OpenStack各个组件的情况下,如果沿用官方文档的部署方案设计线上系统,那么网络的情况会变得更为重要。

针对这种情况,我认为需要专门一章汇集一下与OpenStack相关的网络背景知识,使初学者不必多方查找,节省一些时间,这些内容有以下几个方面。

  • 网桥:用于OpenStack FlatDHCP部署模式。

  • VLAN:用于OpenStack VLAN部署模式。

  • GRE:用于OpenStack multi namespace部署模式。

  • VXLAN:用于OpenStack multi namespace部署及多数据中心迁移模式。

  • Namespace:用于理解OpenStack Neutron网络模式。

当然,由于篇幅限制,这里也只能讲一些核心的网络知识。若要深入理解其中的某些细节,建议读者再多看一些资料。

2.1 网卡管理工具ethtool

我们很多时候对网卡的配置都是直接写网卡配置文件或是使用ifconfig之类的命令,而实际上如果对网卡进行更多细微的调整,则需要使用ethtool网卡管理工具,比如设置网卡速率或者全双工等工作模式时。

2.1.1 安装与使用ethtool

在Ubuntu系统下安装ethtool非常简单:

root@GCM1:~# apt-get install ethtool

在CentOS系统下安装也很简单:

[root@localhost ~]# yum install ethtool

ethtool可用于一些特殊的网卡处理要求,如设置eth0网卡处于1000MB、全双工状态:

ethtool -s eth0 autoneg off speed 1000 duplex full

使用ethtool工具查看网卡的基础信息:

root@GCM1:~# ethtool eth0
Settings for eth0:
     Supported ports: [ TP ]
     Supported link modes:   10baseT/Half 10baseT/Full
                             100baseT/Half 100baseT/Full
                             1000baseT/Full
     Supported pause frame use: No
     Supports auto-negotiation: Yes
     Advertised link modes:  10baseT/Half 10baseT/Full
                             100baseT/Half 100baseT/Full
                             1000baseT/Full
     Advertised pause frame use: No
     Advertised auto-negotiation: Yes
     Speed: 1000Mb/s
     Duplex: Full
     Port: Twisted Pair
     PHYAD: 1
     Transceiver: internal
     Auto-negotiation: on
     MDI-X: Unknown
     Supports Wake-on: g
     Wake-on: d
     Link detected: yes

在上述信息中,我们可以看到网卡工作在全双工1000Mb/s速率,且物理连接正常。

在CentOS下使用ethtool工具查看网卡信息:

[root@localhost ~]# ethtool em1
Settings for em1:
     Supported ports: [ TP ]
     Supported link modes:   10baseT/Half 10baseT/Full
                             100baseT/Half 100baseT/Full
                             1000baseT/Full
     Supported pause frame use: No
     Supports auto-negotiation: Yes
     Advertised link modes:  10baseT/Half 10baseT/Full
                             100baseT/Half 100baseT/Full
                             1000baseT/Full
     Advertised pause frame use: No
     Advertised auto-negotiation: Yes
     Speed: 1000Mb/s
     Duplex: Full
     Port: Twisted Pair
     PHYAD: 1
     Transceiver: internal
     Auto-negotiation: on
     MDI-X: Unknown
     Supports Wake-on: g
     Wake-on: d
     Link detected: yes

注意 在DELL R710服务器下安装CentOS 6.2时,网卡名被标记为em1、em2、em3、em4等。

使用ethtool工具配置网卡的参数最终需要以文件的形式保存下来,这个文件在不同操作系统下保存的位置不同,具体如下所示。

  • Ubuntu下:/etc/network/interfaces。

  • CentOS下:/etc/sysconfig/network-scripts/ifcfg-eth0。

在Ubuntu下重启网卡配置时命令如下:

root@GCM1:/etc/network# /etc/init.d/networking restart

在CentOS下重启网络服务的命令如下:

service network restart

2.1.2 网卡子接口

有时OpenStack实验环境中的机器只有一个网卡,但我们希望在网卡连接的同一个物理网络中,网卡能同时具有多个IP地址,此时需要创建一个或多个子接口,以让本机能够接入多个IP网段之中。

在Ubuntu下配置子接口时命令如下:

auto eth2
iface eth2 inet static
address 12.7.2.2
netmask 255.0.0.0

auto eth2:0
iface eth2:0 inet static
address 12.7.2.21
netmask 255.0.0.0

在上述配置中,我们增加了eth2:0子接口。重启网络服务后,可以看到系统增加了eth2:0网卡:

root@GCM1:/etc/network# ifconfig
eth2      Link encap:Ethernet  HWaddr 78:2b:cb:43:5d:cc
          inet addr:12.7.2.2  Bcast:12.255.255.255  Mask:255.0.0.0
          inet6 addr: fe80::7a2b:cbff:fe43:5dcc/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:10 errors:0 dropped:21514 overruns:0 frame:0
          TX packets:12 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:1251 (1.2 KB)  TX bytes:1705 (1.7 KB)
          Interrupt:32 Memory:da000000-da012800

eth2:0    Link encap:Ethernet  HWaddr 78:2b:cb:43:5d:cc
          inet addr:12.7.2.21  Bcast:12.255.255.255  Mask:255.0.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          Interrupt:32 Memory:da000000-da012800

在CentOS下,子接口需要另建一个网卡配置文件。如在em2网卡上创建一个子接口,其配置文件/etc/sysconfig/network-scripts/ifcfg-em2:0的内容是:

DEVICE=em2
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.1.100
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
ONPARENT=yes

由于子接口本身是一个物理网卡,所以可以单独配置IP地址。同样,如果用于实验的机器只有一个物理网卡,我们可以创建多个子接口来模拟多个网段的情况。

2.1.3 网卡信息文件

在OpenStack系统的搭建过程中,有时为了简化操作,我们直接以某个虚拟机为基础,用cp命令等复制出来其他虚拟机,但此时会发现一个奇怪的现象,那就是虚拟机启动后,虽然IP地址等都不与其他虚拟机冲突,但就是无法ping通其他节点。

这个问题的原因与虚拟机中的/etc/udev/rules.d/70-persistent-net.rules有关,此文件记录了虚拟机在第一次创建时系统得到的网卡信息及MAC地址。通过复制产生的虚拟机,如果不删除这个文件,那么就算在虚拟机的XML描述文件中更改了MAC地址,而由于虚拟机启动后内核仍从此文件读取网卡与MAC信息,因此外部更新后的网卡地址等信息内核还是无法获得。所以,如果新创建的虚拟机是从其他虚拟机复制过来的话,那么需要将虚拟机中的70-persistent-net.rules文件删除,这样虚拟机启动后,就可以学习到新的网卡配置信息了。下面是这个文件的信息,供读者了解:

# This file was automatically generated by the /lib/udev/write_net_rules
# program, run by the persistent-net-generator.rules rules file.
#
# You can modify it, as long as you keep each rule on a single
# line, and change only the value of the NAME= key.

# PCI device 0x14e4:/sys/devices/pci0000:00/0000:00:03.0/0000:02:00.1 (bnx2)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="78:2b:cb:43:5d:ce", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth3"

# PCI device 0x14e4:/sys/devices/pci0000:00/0000:00:03.0/0000:02:00.0 (bnx2)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="78:2b:cb:43:5d:cc", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth2"

# PCI device 0x14e4:/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.1 (bnx2)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="78:2b:cb:43:5d:ca", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"

# PCI device 0x14e4:/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0 (bnx2)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="78:2b:cb:43:5d:c8", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"

2.1.4 OpenStack:运用网卡子接口模拟多网卡

由于一个网卡可以创建多个子接口,而每个子接口又可以加入不同的网桥,这样如果我们在安装OpenStack时只有一张网卡,但实际上可以模拟一个多网卡、多网桥的网络环境,在配置FlatDHCP安装模式时很有用。

2.2 网桥及网桥管理工具bridge-utils

很多人刚开始很难理解网桥的概念。不同于物理机,虚拟机没有硬件设备,若我们在虚拟机中配置了网卡,那这些网卡连接到哪里了呢?

配置网桥就是解决虚拟机的网卡连接问题的。创建网桥后,就像网络交换机具有物理网络接口一样,我们就可以进一步在网桥上创建多个虚拟的物理接口,而每个接口再与虚拟机的网卡连接。在Linux操作系统的KVM虚拟环境内,为挂载虚拟机,网桥接口的标识通常会是vnet0、vnet1等符号。

图2-1展示了虚拟机、网桥、物理机网卡以及外部交换机间的关系。在本书的实验环境中,我们使用DELL服务器,物理机网卡标识以em开头,比如em1和em2。

{%}

图 2-1 虚拟机、网桥、物理机网卡以及外部交换机间的关系

图2-1共有3个网桥,其中br1与br2桥分别与宿主机的em1与em2物理端口连接,且宿主机的em1再连接到互联网上。br800上虽然连接有一个虚拟机D,但此桥却不与任何宿主机的物理端口连接,因此与br800连接的虚拟机是无法访问外网的。

vnet0通过uml-utilities工具生成的虚拟机物理接口,最终被加入到网桥上,从而完成虚拟机与网桥的连接。而bridge-utils工具则用于在操作系统中创建网桥。在KVM虚拟化环境中,创建虚拟执时vnet0等端口会自动创建,并不需要人工干预,因此这里不需要进一步讲解uml-utilities工具的使用方法,而是将重点集中于如何使用bridge-utils工具在系统中创建网桥。

2.2.1 安装与使用bridge-utils

CentOS下的网桥管理工具是bridge-utils包。安装该包后,可以使用brctl命令来创建、查看与管理网桥:

[root@localhost network-scripts]# yum install bridge-utils
[root@localhost network-scripts]# brctl
Usage: brctl [commands]
commands:
    addbr    <bridge>            add bridge
    delbr    <bridge>            delete bridge
    addif    <bridge><device>    add interface to bridge
    delif    <bridge><device>    delete interface from bridge
......

例如,下面使用brctl命令创建网桥br1,并将em1端口加入此网桥:

[root@localhost network-scripts]# brctl addbr br1
[root@localhost network-scripts]# brctl addif em1
[root@localhost network-scripts]# ifconfig em1 0.0.0.0
[root@localhost network-scripts]#ifconfig br1172.21.1.3 netmask 255.255.0.0

在上述配置中,同时将em1的IP地址去除,并创建了网桥的IP地址。

查看网桥包括的端口信息:

[root@localhost ~]# brctl show br1
bridge name     bridge id               STP enabled     interfaces
br1             8000.d4ae52640406       no              em1
                                                        vnet0
                                                        vnet12
                                                        vnet16
                                                        vnet20
                                                        vnet24
                                                        vnet28
                                                        vnet32
                                                        vnet36
                                                        vnet4
                                                        vnet40
                                                        vnet44
                                                        vnet8

上述信息表示,br1网桥上除了宿主机的物理端口em1外,还有一系列以vnetXX命名的网桥端口,每个虚拟机的网卡都连接到不同的vnet端口上。

2.2.2 理解网桥的IP地址与虚拟机的IP地址

如同交换机和平时家用的ADSL上网设备都有一个管理用的IP地址一样,配置了网桥的IP地址后,即可使用telnet或ssh通过此地址访问宿主机。如在本例中,可以使用ssh连接172.21.1.3的IP地址通过em1物理端口登录到宿主机的CentOS操作系统:

[root@localhost ~]# ifconfig
br1       Link encap:Ethernet  HWaddr D4:AE:52:64:04:06
          inet addr:172.21.1.3  Bcast:172.21.255.255  Mask:255.255.0.0
          inet6 addr: fe80::d6ae:52ff:fe64:406/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:2029839 errors:0 dropped:0 overruns:0 frame:0
          TX packets:66524 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
          RX bytes:111721520 (106.5 MiB)  TX bytes:6409933 (6.1 MiB)

与网桥连接的虚拟机IP地址,可以与网桥处于同一个IP网段,也可以处于不同的IP网段。比如,在我们的实验环境中,可以将虚拟机的IP地址段设置为192.168.1.0/24,而将外部的交换机设置为192.168.1.1的网关地址,这样虚拟机就可以通过外部交换机访问互联网,虽然此时br1桥的IP地址是172.21.1.3。

2.2.3 Ubuntu下网桥的配置文件

相对来说,Ubuntu下的配置网卡、网桥等都汇集到一个/etc/network/interfaces文件中。例如,下面我们配置了名为br0的网桥,并将eth0接口加入网桥中:

auto eth0 iface

eth0 inet manual
auto br0
iface br0 inet static
    address 192.168.3.3
    netmask 255.255.255.0
    gateway 192.168.3.1
    bridge_ports eth0

2.2.4 CentOS下网桥的配置文件

brctl命令对网桥的配置需要以文件形式保存下来,这样系统再次启动后所有配置仍能生效。br1的网桥及em1网卡的配置文件ifcfg-br1如下:

DEVICE="br1"
TYPE=Bridge
BOOTPROTO=static
IPADDR=172.21.1.3
NETMASK=255.255.0.0
NETWORK=172.21.0.0
GATEWAY=172.21.1.1
DNS1=61.139.2.69
ONBOOT="yes"

而此时em1网卡配置文件ifcfg-em1的内容是:

DEVICE="em1"
HWADDR="D4:AE:52:64:04:06"
#NM_CONTROLLED="yes"
ONBOOT="yes"
BRIDGE="br1"

2.2.5 将虚拟机与某个网桥连接

在创建虚拟机时,在CentOS下可以通过virt-manager图形化工具将虚拟机挂接到指定的网桥上,或者增加虚拟机的网卡数量,将它们分别挂到不同的网桥上。如图2-2所示,当前虚拟机(共计4块网卡)的第一个网卡与网桥br1连接。

{%}

图 2-2 虚拟机网卡与网桥的连接

2.3 虚拟局域网VLAN

虽然我们可以使用网桥连接很多虚拟机,但它的局限性也很清晰。网桥上的其他虚拟机可以收到某个虚拟机发出的二层广播包,当多个虚拟机都挂载在同一个网桥上时,每个虚拟机发出的广播包而引起的广播风暴会使得网桥的通信吞吐能力大幅度下降,从而使得虚拟机的网络性能急剧下降。因此需要某种机制,使得某个或某几个虚拟机的广播包能限制在一定的范围内,这样就不会影响其他的虚拟机。这种技术就是802.1Q机制,或者我们说的VLAN。

当多台虚拟机被划分到不同的VLAN后,同一VLAN中的机器相当于连接在一个网桥中,而不同VLAN间的通信就被隔离。在当今的很多企业内网中,在交换机上已经广泛应用了VLAN技术,以隔离不同的网络,提高安全性的同时也提升了性能。

在Linux操作系统内部的虚拟化环境中,我们通常会将网桥与VLAN对应起来,即A网桥划分到VLAN A中,B网桥划分到VLAN B中。

2.3.1 VLAN协议802.1Q

如果不过多引用理论,从便于理解的角度来看,802.1Q的作用是将每个虚拟机发出的包加一个标签,一个局域网内可以有4096个标签,每个标签可以看作一个独立的虚拟网络(Virtual LAN),每个虚拟机只能接收与自身设置相同VLAN号码的数据包,如图2-3所示。

{%}

图 2-3 虚拟机、桥与VLAN

虚拟机A与虚拟机A1虽然分处于不同的宿主机,但这两台机器每个二层数据包均有一个VLAN 1的号码标签,因此虚拟机A与A1可以互相收到对方发出的数据包,A与A1的广播包也被限定在这两台机器之间,不会扩散到其他机器上。

2.3.2 接入端口与中继端口

将数据包打上VLAN号码标记的端口,我们称为接入端口(access port),而将不处理标签,只是转发数据包的端口称为中继端口(trunk port)。图2-3中各个虚拟机在桥上的接口vnetXX等就是接入端口,而宿主机的物理网卡em1以及交换机的s1端口,则为中继端口。

2.3.3 VLAN管理工具vconfig

在Linux下,VLAN的管理工具是vconfig。结合使用bridge-utils与vconfig工具,我们可以创建网桥并将其与VLAN关联。

1. vconfig的安装

vconfig工具位于vlan包中,安装完此包后,vconfig工具也一同安装完毕。同时,我们也要手工载入8021q模块以支持后续VLAN的创建工作:

apt-get install vlan
modprobe 8021q

为了使机器下次启动时,能自动加载8021q包,我们将其加入到/etc/modules文件中:

8021q

2. 创建VLAN 接口与网关IP地址

Linux的VLAN机制是,如果物理机器只有一个网卡,那么我们可以在这个网卡上建立多个VLAN,意即多个VLAN的数据可以通过这个物理网卡对外转发。而每个VLAN以独立的接口(interface)体现,比如我们打算在eth2上创建2、3、4号VLAN,那么就是要创建eth2.2、eth2.3、eth2.4这3个不同的接口。

同时,我们也可以为每个VLAN的接口分配不同的IP地址,让这个地址成为这个VLAN内部的对外访问网关,如可以将eth2.2设置为192.168.2.1作为此VLAN内的网关地址。

下面我们在eth2上分别创建2、3、4号VLAN并赋予它们IP地址,然后将其加入到主机路由表中:

vconfig add eth2 2
vconfig add eth2 3
vconfig add eth2 4
ifconfig eth2.2 192.168.2.1 netmask 255.255.255.0 up
ifconfig eth2.3 192.168.3.1 netmask 255.255.255.0 up
ifconfig eth2.4 192.168.4.1 netmask 255.255.255.0 up
ip route add 192.168.1.0/24 dev eth2.2
ip route add 192.168.2.0/24 dev eth2.3
ip route add 192.168.3.0/24 dev eth2.4

注意,vconfig add eth2.2 的含义是在eth2端口上增加VLAN号码为2的子接口,生成的子接口名称标识为eth2.2。

如果要删除已创建的接口eth2.2,则可以使用以下语句:

vconfig rem eth2.2

这些VLAN接口的作用是,将其加入到桥中,使得某个桥与VLAN关联起来。

3. 虚拟化环境中网桥与VLAN的结合

在虚拟化环境下,我们需要将虚拟机加到不同的VLAN中。实现这个目标的方法就是将创建好的VLAN子接口加入到一个网桥中,网桥上的其他接口也就自动属于这个VLAN。

比如,我们在主机A的eth2物理接口上创建eth2.2接口,并将其加入到网桥br1中,同时将虚拟机a1和a2等接入到br1网桥中;在主机B的eth2物理接口上也创建eth2.2接口,并将其加入到br1网桥中,同时也将虚拟机b1和b2等接入到br1网桥中。

在主机A的eth2物理接口上,创建2号VLAN接口并将其加入到br1的过程如下:

vconfig add eth22
ifconfig eth2.2 up
brctl addbr br1
brctl addif br1 eth2.2

上述过程完成后,我们可理解为,凡是在br1上的其他网络端口都属于2号VLAN。br1网桥创建好后,桥下就自动有一个br1的接口,将eth2.2加进来后,这个桥就有两个接口br1与eth2.2。

如果主机A还要考虑到与不同VLAN中其他虚拟机进行通信,我们可以为2号VLAN中的虚拟机创建一个网关IP地址。我们会将br1作为VLAN2的接口并赋予其IP,相较于将eth2.2作为VLAN 2的接口的做法,这样好记一些:

ifconfig br1 192.168.2.1 netmask 255.255.255.0 up
ip route add 192.168.1.0/24 dev br1

我们可以将上述配置写入网卡配置文件/etc/network/interface中:

auto eth2
auto eth2.2
auto br1

iface eth2.2 inet static
ifconfigeth2.2 0.0.0.0 up vlan-raw-device eth2 iface br1 inet static address 192.168.2.1 netmask 255.255.255.0 bridge-ports eth2.2 bridge_stp off  bridge_fd 0

4. 交换机中的VLAN IP interface

在上述操作中,我们将VLAN2的网关192.168.2.1创建在Linux主机中,这可以满足一两台机器的简单应用,但无法满足几十台机器都通过交换机连接的需求,更好的办法是将VLAN2的网关都创建到交换机中。如图2-3所示,我们在物理机中只创建桥与VLAN,而VLAN2的网关IP则创建在交换机中,同时不同的VLAN间的互访也通过交换机中的路由表来实现。在图2-3中,不同物理机中的VLAN2若要访问VLAN3,则要通过交换机来完成。当然,有时需要限制不同VLAN间的互访,因此,还需要在交换机配置不同的访问控制列表(ACL)。

由于OpenStack系统在计算节点中自动处理VLAN,不需要人工干涉,这简化了我们的工作量。

2.4 主机多网卡静态路由配置

在实际的OpenStack安装过程中,特别是生产类系统中,为了使网络流量更加均衡,通常会使用多块网卡连接多个不同的网段,此时就需要通过建立路由表的形式来处理网络路径。

例如,服务器中有6个可用的网卡,其中eth0的IP地址是20.1.1.6,eth5的IP地址是25.1.1.6,我们的期望如下所示。

  • 上网时走eth5,eth5连接到第一台交换机,它提供的网关IP地址为25.1.1.1。

  • 访问30.1.0.0的网段时能够走eth0,eth0连接到第二台交换机,该交换机连接着30.1.0.0网段中的设备。

  • 访问80.1.0.0网段时,能够走eth5连接的第一台交换机该交换机还连接着80.1.0.0网段中的设备。

我们进行以下多路由配置以实现此目标:

route del default
route add default gw 25.1.1.1 dev eth5
route add -net 30.1.0.0 netmask 255.255.0.0 gw 20.1.1.1 dev eth0
route add -net 80.1.0.0 netmask 255.255.0.0 gw 25.1.1.1 dev eth5

简单来说,上述的指令实现了上网流量通过default gw完成,即通过eth5走出去;若要访问计算节点的30网段,则通过端口eth0到20.1.1.1的路由器转至30.1.0.0网段。

2.5 Open vSwitch简介与实验

Open vSwitch是OpenStack在操作系统中使用的虚拟交换机插件,了解它的基本操作对后期安装非常有帮助。

2.5.1 Open vSwitch简介

随着虚拟化技术的发展,用软件在宿主机内构建一台与硬件交换机具备相同特性的软件交换机这个应用需求也越来越迫切。Open vSwitch正是因这一需求而诞生的。

Open vSwitch即开放的软件虚拟交换机,能够达到产品级质量,意即可以部署在一些生产环境中使用。它的出现更多的是满足虚拟化技术的要求。因为在虚拟化环境中,主机都是创建在操作系统中,而多个主机间需要连接,除了可以使用Linux的网桥、VLAN等传统做法外,那么还可以通过虚拟交换机Open vSwitch。Open vSwitch不仅支持基本的二层交换,还支持标准的管理接口和协议(如NetFlow、sFlow、SPAN、RSPAN、CLI、LACP、802.1ag),同时也支持OpenFlow,可以很好地与SDN体系融合。

由于Open vSwitch开放且能够满足各类应用的要求,OpenStack也在F、G等版本中提供了对Open vSwitch的支持,因此了解Open vSwitch是如何运作的,对于后期的OpenStack系统安装与管理非常有帮助。本节中,我们将花更多笔墨介绍Open vSwitch的独立安装与管理。

下面是在单独一台机器上安装Open vSwitch及相关操作的实验记录,目标是方便读者理解它的各方面操作,特别是相较于Linux的相关工具而言。实验中,我们会将Open vSwitch简称为OVS。

2.5.2 安装Open vSwitch

我们准备在Ubuntu 12.04上安装Open vSwitch。在全新安装Ubuntu 12.04并完成所有更新后,按如下步骤开始实验。

1. 安装KVM包

下面的步骤完成KVM虚拟化环境准备以及确保操作系统支持802.1Q VLAN。

(1) 安装KVM等软件包:

apt-get install kvm libvirt-bin virtinst

(2) 检查系统是否支持KVM:

kvm-ok
modprobe kvm
modprobe kvm-intel

(3) 加载8021q:

apt-get install vlan
modprobe 8021q

(4) 将上述配置写入modules文件,下面是此文件的相关内容:

# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.

kvm
kvm-intel

loop
lp
rtc
8021q

2. 安装OVS对KVM的支持包及脚本

安装uml-utilities软件,用于处理虚拟机网卡:

apt-get install uml-utilities

创建下面的两个脚本文件——/etc/ovs-ifup和/etc/ovs-ifdown,它们用于启动虚拟机时创建虚拟机网卡,其中/etc/ovs-ifup的内容如下:

#!/bin/sh
switch='br0'
/sbin/ifconfig $1 0.0.0.0 up
ovs-vsctl add-port ${switch} $1

/etc/ovs-ifdown的内容如下:

#!/bin/sh
switch='br0'
/sbin/ifconfig $1 0.0.0.0 down
ovs-vsctl del-port ${switch} $1

通过下面的代码可以让这两个文件运行:

Chmod +x /etc/ovs*

3. 删除virbr0网桥及ebtables

如果存在virbr0及ebtables,则需要删除它们:

virsh net-destroy default
virsh net-autostart --disable default
apt-get purge ebtables

4. 安装OVS包及brcompat_mod

安装OVS相关的软件:

apt-get install kvm libvirt-bin openvswitch-controller openvswitch-brcompat openvswitch-switchopenvswitch-datapath-source

brcompat_mod是Open vSwitch为了兼容bridge_utils而提供的,意即当OVS运行时,仍可使用brctl等工具处理桥的相关参数。

接着设置brcompat_mod与OVS一同启动。编辑/etc/default/openvswitch-switch,并设置BRCOMPATyes

......
BRCOMPAT=yes

然后编译安装brcompat。执行以下命令加载brcompat_mod:

module-assistant auto-install openvswitch-datapath

最后检查是否加载了brcompat:

root@CM214:~# lsmod | grep brcom
brcompat       13512  0
openvswitch    84038  1 brcompat

5. 启动或关闭OVS服务

使用service openvswitch-switch start/stop方式来启动或关闭OVS:

root@CM214:/home/romi# service openvswitch-switch start
 * Inserting openvswitchmodule
 * /etc/ openvswitch/conf.db does not exist
 * Creating empty database /etc/ openvswitch/conf.db
 * Starting ovsdb-server
 * Configuring Open vswitch system IDs
 * Starting ovs-vswitchd
 * Enabling gre with iptables

2.5.3 使用ovs-vsctl管理OVS

OVS提供了几个不同的管理工具,其中最常用的是ovs-vsctl,本节就简要介绍一下如何使用它。

1. 网桥相关操作

网桥相关的操作如下,比如增加网桥、将网卡加入网桥、查看网桥等。

增加网桥:

# ovs-vsctl add-br br0

将网卡加入网桥:

# ovs-vsctl add-port br0 eth0

查看OVS中的所有网桥及端口信息:

# ovs-vsctl show
a23c503b-bfbe-4646-8738-a7f69e5d69a0
    Bridge "br0"
        Port "eth0"
           Interface "eth0"
        Port "br0"
           Interface "br0"
               type: internal
ovs_version: "1.4.0+build0"

将eth0加入到br0网桥后,eth0网卡不再需要配置IP地址,我们将其IP地址重新配置为0,具体如下所示:

root@CM214:~# ifconfig eth0 0
root@CM214:~# ifconfig
eth0      Link encap:Ethernet  HWaddr d4:ae:52:66:70:02
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1319 errors:0 dropped:45 overruns:0 frame:0
          TX packets:517 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:125684 (125.6 KB)  TX bytes:67143 (67.1 KB)
          Interrupt:36 Memory:d6000000-d6012800

如果eth0没有IP 地址,那该如何通过eth0所在的网段访问服务器呢?其做法是,给eth0归属的br0网桥配置IP地址及网关。我们将br0网桥的地址配成10.2.1.4,然后就可以通过此地址远程访问服务器了:

root@CM214:~# ifconfig br0 10.2.1.4 netmask 255.0.0.0
root@CM214:~# ifconfig
br0       Link encap:Ethernet  HWaddr d4:ae:52:66:70:02
          inet addr:10.2.1.4  Bcast:10.255.255.255  Mask:255.0.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:397 errors:0 dropped:31 overruns:0 frame:0
          TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
          RX bytes:32354 (32.3 KB)  TX bytes:174 (174.0 B)

eth0     Link encap:Ethernet  HWaddr d4:ae:52:66:70:02
         UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
         RX packets:1421 errors:0 dropped:45 overruns:0 frame:0
         TX packets:520 errors:0 dropped:0 overruns:0 carrier:0
         collisions:0 txqueuelen:1000
         RX bytes:133774 (133.7 KB)  TX bytes:67365 (67.3 KB)
         Interrupt:36 Memory:d6000000-d6012800

2. 保存OVS的配置

要保存OVS的配置,一种办法是将上述配置指令写到/etc/rc.local中:

ovs-vsctl add-br br0
ovs-vsctl add-br br3
ovs-vsctl add-port br0 eth0
ovs-vsctl add-port br3 eth3
ifconfig eth0 0 && ifconfig br010.2.1.4 netmask 255.0.0.0
ifconfig eth3 0 && ifconfig br313.2.1.4 netmask 255.0.0.0
route add default gw 13.1.1.1 br3

另一种办法是将配置直接写到/etc/network/interfaces中:

auto lo
iface lo inet loopback

auto br0
iface br0 inet static
address 10.2.1.4
netmask 255.0.0.0

auto eth0
iface eth0 inet manual
up ifconfig $IFACE 0.0.0.0 up
down ifconfig $IFACE down


auto eth1
iface eth1 inet dhcp
auto eth2
iface eth2 inet dhcp

auto br3
iface br3 inet static
address 13.2.1.4
netmask 255.0.0.0
gateway 13.1.1.1
dns-nameservers 61.139.2.69

auto eth3
iface eth3 inet manual
up ifconfig $IFACE 0.0.0.0 up
down ifconfig $IFACE down

2.5.4 OVS的数据库配置与网络配置文件的关系

OVS的配置写在一个ovsdb数据库中。ovsdb是一个非常轻量级的数据库,与其说它是一个数据库,不如说它是一个提供增、删、查、改等功能的临时配置缓存。之所以这么说,是因为ovsdb数据库根本就未使用多少数据库技术。

ovssdb数据库操作的一般格式为:

ovs-vsctl list/set/get/add/remove/clear/destroy table record column [value]

默认情况下,ovsdb中有以下数据表:bridgecontrollerinterfacemirrornetflowopen_vswitchportqosqueuesslsflow。即table可为其中的任一个,record为数据表中name字段的值,column为数据表任一个字段的字段名,value为字段值。

比如,我们可以使用ovs-vsctl list bridge命令查询ovsdb中bridge表中的桥与网卡信息:

root@CM214:~# ovs-vsctl list bridge
_uuid  : 0645823c-613c-492b-8322-527840797260
name   : "br3"
ports  : [76ca46d6-6d29-4f0c-9086-7c094856d321, 794e2a41-7692-49da-aae0-cc7eb12aa16c]

_uuid  : 23de99d6-8c02-4016-aff1-471155d469c7
name   : "br0"
ports  : [a55577e6-d173-4bbe-9957-41a6d0566b52, e5a14d8a-be98-454e-9824-631a9517dc99]

在上述信息中,可以看到网桥br3中包含了ID为76ca46d6-6d29-4f0c-9086-7c094856d321和 794e2a41-7692-49da-aae0-cc7eb12aa16c这两个端口。

更进一步地,我们可以通过ovs-vsctl list port命令查看更多端口的信息:

root@CM214:~# ovs-vsctl list port
_uuid         : 794e2a41-7692-49da-aae0-cc7eb12aa16c
interfaces    : [9b63edb8-4a5f-4c39-89ce-e24f3549a4ac]
name          : "eth3"

_uuid         : 76ca46d6-6d29-4f0c-9086-7c094856d321
interfaces    : [e97a975b-6745-4af0-8c7c-e6bc1c645cc3]
name          : "br3"

_uuid         : a55577e6-d173-4bbe-9957-41a6d0566b52
interfaces    : [b9b16633-60df-4a90-b255-649b4f58bb60]
name          : "br0"

_uuid         : e5a14d8a-be98-454e-9824-631a9517dc99
interfaces    : [1381f041-6516-46a9-974a-86774e1521bb]
name          : "eth0"

可以看到,OVS中的bridgeport表完整地记录了桥与端口的关系。同时,我们也可以看到每个桥隐含地会建立同名的端口。但是,数据库中并不记录每个桥的IP地址,即IP地址仍由/etc/network/ interface文件记录。

2.5.5 设置VLAN及VLAN接口的IP地址

以下示例OVS演示了如何设置中继端口与接入端口,以及如何创建VLAN及设置VLAN 接口的IP地址。

将eth0作为中继端口加入到br0桥中:

ovs-vsctl add-br br0
ovs-vsctl add-port br0 eth0c

接着在br0中增加vlan1与vlan2端口,且它们分别属于VLAN 1与VLAN 2:

ovs-vsctl add-port br0 vlan1 tag=1
ovs-vsctl add-port br0 vlan2 tag=2

然后设置vlan1端口的IP地址为192.168.1.1:

ovs-vsctl set Interface vlan1 type=internal
ifconfig vlan1 192.168.1.1 netmask 255.255.255.0

ovs-vsctl set Interface vlan2 type=internal
ifconfig vlan2 192.168.2.1 netmask 255.255.255.0

2.5.6 OVS支持OpenFlow的SDN模式

在SDN模式下,交换机通过OpenFlow协议与控制器(controller)连接,由控制器确定转发表后下发到交换机中,交换机根据转发表在各个端口间转发数据。

在OVS安装完成后,将会自动安装OVS的控制器。控制器工作在操作系统中的6633端口,若要将OVS与控制器连接,那么需要在OVS中创建一个网桥,此网桥包含物理网卡,并透过物理网卡与操作系统中的OVS OpenFlow 控制器连接:

ovs-vsctl add-br br0
ovs-vsctl add-port br0 eth0
Ifconfig eth0 0
Ifconfig br0 192.168.88.101 netmask 255.255.255.0

接着确保br0能与OVS控制器ping通,完成与OVS控制器的连接:

ovs-vsctl set-controller br0 tcp: 192.168.88.100:6633

执行ovs-vsctl show命令,可以看到:

Controller "tcp:192.168.88.100:6633"
ts_connected: true

2.6 构建云中的网络

在OpenStack系统中,为了隔离租户间的网络,通常会使用VLAN、VXLAN和GRE这3种方法。这3种方法各有优缺点,以下简要说明一下。

2.6.1 VLAN的优势与局限

为了建设较高安全性的OpenStack云系统,必须将其中的租户完全隔离。使用VLAN虽然能实现这个目标,但由于一个网络管理域中最大只有4096个VLAN,因此一套OpenStack系统如果按每个租户分配一个VLAN网络的模式,最大只能支持4096个租户。对企业私有云系统来说,这可能够用了,但对公共云来说,其规模明显受限。

相比标准的以太帧报文,VLAN是其中加入了Tag标签,使用不同号码标明这个报文所属于的VLAN,其报文如图2-4所示。

{%}

图 2-4 VLAN报文

下面简要说明报文中各项的含义。

  • MAC DA:目的二层地址(网卡地址)。

  • MAC SA:源二层地址(网卡地址)。

  • Tag(802.1Q):VLAN号码。

  • Type:指明后面的数据类型,常用的类型如下所示。

    • IPv4:0x0800。

    • IPv6:0x86DD。

    • IPX(Novell):0x8037。

    • ARP:0x0806。

      如果类型为0x0800,则表明数据部分为IP包。IP包的简要格式如图2-5所示。

      {%}

      图 2-5 IP包的简要格式

这里简要说明IP包中各项的含义。

  • Protocol:指明后部数据相关的四层协议类型,常用的类型有以下四种。

    • UDP:17。

    • TCP:6。

    • ICMP:1。

    • GRE:47。

  • IP SA:源IP地址。

  • IP DA:目标IP地址。

  • Payload:IP包中装载的数据内容。

2.6.2 GRE的特点

GRE(Generic Routing Encapsulation,通用路由封装)是对某些网络层协议的报文进行封装,使这些被封装的报文能够在另一网络层协议中传输,比如在OpenStack系统中使用GRE就意味着IP over IP。

GRE是一种隧道(tunnel)技术。隧道是一个虚拟的点对点的连接,可以看成仅支持点对点连接的虚拟接口,这个接口提供了一条通路,使封装的数据报能够在这个通路上传输,并在一个隧道的两端分别对数据报进行封装及解封装。

GRE的报文封装如图2-6所示。

{%}

图 2-6 GRE的报文封装

下面简要说明其中部分项的含义。

  • GRE 47:指明IP包中的数据协议为GRE。

  • GRE Header:指GRE本身的一些封包格式。

  • GRE type:指明GRE 封包内运载的数据类型,其中0x0800指明内部运载的是IPv4协议。

2.6.3 VXLAN的特点

RFC草案所描述的VXLAN标准使用一个名为VXLAN网络标识符(VNI)的24位标识符,将与应用程序关联的VLAN分组到一个片段中。每一个管理域能够定义多达1600万个VNI,而每一个VNI可能最多包含4096个VLAN。客户数据会保证分离,因为只有运行在同一个VNI的VM可以进行通信。这样同一租户的VM不仅可以跨多数据中心部署,而且也使得整个云系统能够支持的租户数量不受限,完全突破了原来VLAN的限制。

目前,一些网络厂商也纷纷推出了支持VXLAN功能的数据中心交换机,透过VXLAN的技术可以将所有的OpenStack计算节点服务器均连接到VXLAN交换机上,利用交换机强大的包处理功能与成熟的代码,可以使OpenStack系统获得更好的稳定性。

VXLAN的封包格式如图2-7所示。

{%}

图 2-7 VXLAN的封包格式

下面简要说明一下。

  • VXLAN 的数据是嵌入到UDP协议中,因此IP包的负载数据协议类型指向17。

  • VXLAN VNI可以有1600万个号码,用以区分数据属于哪一个VXLAN。

  • 后边的数据仍是一个标准的以太网帧。

2.7 Linux内核的VXLAN功能实验记录

为了让读者对VXLAN有一些基本了解,这里我们将基于Linux内核的VXLAN实验记录展示出来。Linux内核中支持VXLAN的组播功能,可以让我们将来有机会进一步与支持VXLAN间的交换机结合,设计出稳定与性能俱佳的云网络系统。

2.7.1 实验环境及目标

VXLAN内核支持至少要求3.7,因此在实验环境中,我们使用了两台Ubuntu 13.04操作系统的虚拟机,内核版本为3.8。

我们的实验环境采用两台机器,名为vxlangateway14的IP地址分别是10.7.1.14,vxlangateway15的IP地址是10.7.1.15,具体如图2-8所示。

{%}

图 2-8 Linux VXLAN功能实验

实验环境说明如下。

  • 在vxlangateway14上创建名为vxlan0、包含eth0物理接口的VXLAN接口。

  • 将vxlan0加入到内部创建的br0桥中(注意,br0本身并不包含eth0物理接口)。

  • 在br0上创建100和101这两个VLAN接口,并赋予不同接口IP地址。

  • 在vxlangateway15上也做类似的配置。

实验目标:验证VXLAN的机制能否正常工作。

如果VXLAN机制工作正确,两台机器内具有相同VLAN号码、不同IP地址的接口之间就可以互相ping通。

2.7.2 配置与测试VXLAN

安装桥与8021q模块:

apt-get install -y vlan bridge-utils
modprobe 8021q

在vxlangateway14上增加VXLAN端口、VLAN端口及IP地址:

ip link add vxlan0 mtu 1500 type vxlan id 42 group 239.1.1.1 local 10.7.1.14 dev eth0

ip link set dev vxlan0 up

brctl addbr br0
brctl addif br0 vxlan0
ifconfig br0 192.168.1.14 netmask 255.255.255.0 up

vconfig add vxlan0 100
ifconfig vxlan0.100 up
ifconfig vxlan0.100 172.16.1.14 netmask 255.255.255.0 up

vconfig add br0 101
ifconfig br0.101 192.192.1.14 netmask 255.255.255.0 up

之后通过ifconfig命令可以看到网络配置情况:

br0       Link encap:Ethernet  HWaddr ce:b5:ca:9e:39:03
          inet addr:192.168.1.14  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::ccb5:caff:fe9e:3903/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:7 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:566 (566.0 B)

br0.101   Link encap:Ethernet  HWaddr ce:b5:ca:9e:39:03
          inet addr:192.192.1.14  Bcast:192.192.1.255  Mask:255.255.255.0
          inet6 addr: fe80::ccb5:caff:fe9e:3903/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:4 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:328 (328.0 B)

eth0      Link encap:Ethernet  HWaddr 52:54:00:80:ab:90
          inet addr:10.7.1.14  Bcast:10.255.255.255  Mask:255.0.0.0
          inet6 addr: fe80::5054:ff:fe80:ab90/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:313 errors:0 dropped:14 overruns:0 frame:0
          TX packets:20 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:21091 (21.0 KB)  TX bytes:2160 (2.1 KB)

eth3      Link encap:Ethernet  HWaddr 52:54:00:83:dd:93
          inet addr:13.7.1.14  Bcast:13.255.255.255  Mask:255.0.0.0
          inet6 addr: fe80::5054:ff:fe83:dd93/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:293 errors:0 dropped:13 overruns:0 frame:0
          TX packets:196 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:22682 (22.6 KB)  TX bytes:23799 (23.7 KB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

vxlan0    Link encap:Ethernet  HWaddr ce:b5:ca:9e:39:03
          inet6 addr: fe80::ccb5:caff:fe9e:3903/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:13 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:1070 (1.0 KB)

vxlan0.100 Link encap:Ethernet  HWaddr ce:b5:ca:9e:39:03
           inet addr:172.16.1.14  Bcast:172.16.1.255  Mask:255.255.255.0
           inet6 addr: fe80::ccb5:caff:fe9e:3903/64 Scope:Link
           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
           RX packets:0 errors:0 dropped:0 overruns:0 frame:0
           TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
           RX bytes:0 (0.0 B)  TX bytes:238 (238.0 B)

同样,在机器vxlangateway15上执行如下命令:

ip link add vxlan0 mtu 1500 type vxlan id 42 group 239.1.1.1 local 10.7.1.15 dev eth0

ip link set dev vxlan0 up

brctl addbr br0
brctl addif br0 vxlan0
ifconfig br0 192.168.1.15 netmask 255.255.255.0 up

vconfig add vxlan0 100
ifconfig vxlan0.100 up
ifconfig vxlan0.100 172.16.1.15 netmask 255.255.255.0 up

vconfig add br0 101
ifconfig br0.101 192.192.1.15 netmask 255.255.255.0 up

此时就在Vxlangate way15机器上创建了与Vxlangate way 14机器上相同的网桥及VXLAN接口。

2.7.3 测试与结果

我们在vxlangateway14上ping vxlangateway15的IP地址,可以ping通,以下是相关信息:

root@vxlangateway14:/home/romi# ping 192.192.1.15
PING 192.192.1.15 (192.192.1.15) 56(84) bytes of data.
64 bytes from 192.192.1.15: icmp_req=1 ttl=64 time=1.22 ms
64 bytes from 192.192.1.15: icmp_req=2 ttl=64 time=0.493 ms
^C
--- 192.192.1.15 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.493/0.856/1.220/0.364 ms

root@vxlangateway14:/home/romi# ping 172.16.1.15
PING 172.16.1.15 (172.16.1.15) 56(84) bytes of data.
64 bytes from 172.16.1.15: icmp_req=1 ttl=64 time=0.705 ms
64 bytes from 172.16.1.15: icmp_req=2 ttl=64 time=0.251 ms
^C
--- 172.16.1.15 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.251/0.478/0.705/0.227 ms

结果表明,VXLAN机制工作正常,两台机器间VLAN的IP地址可以互相ping通。

2.8 Linux内核VXLAN与Open vSwitch的结合

如果虚拟化环境的代码可以控制,则可以先在宿主机上创建一个VXLAN接口,然后将VXLAN接口加入Open vSwitch的一个桥中,这样就能让不支持VLAN 组播功能的Open vSwitch拥有组播的能力:

ip link add vxlan0 mtu 1500 type vxlan id 42 group 239.1.1.1 local 10.7.1.15 dev eth0

ip link set dev vxlan0 up

ovs-vsctl add-br brvxlan
ovs-vsctl add-port brvxlan vxlan0

上述做法可以使OVS使用内核的VXLAN功能,并支持组播。

2.9 网络名字空间及网络虚拟设备

在Linux中,命名空间主要提供一种轻量级的资源虚拟隔离机制,比如LXC、Docker等都是基于这种机制从而实现多个进程间互不干扰。对于进程而言,一个命名空间包括5个具体的命名空间:mntutsipcpid以及net。对于OpenStack来说,我们更关注的是网络名字空间,它是Neutron网络组件运行的基础。

2.9.1 网络名字空间

引入网络名字空间以后,即使我们不采用VLAN等网络技术,也可以使同一台物理机上同时存在多个不同甚至相同的网络,相同名字空间内的网卡、网桥、路由器等设备可以互相访问,而不同名字空间内的网络设备之间互相隔离、互不影响。

创建网络名字空间较为简单,比如下面的命令可以在Ubuntu 14.04下创建两个网络名字空间:

# ip netns add netspace01
# ip netns add netspace02

当然,也可以通过ip netns list/del等命令进一步查看或删除当前已有的名字空间。

2.9.2 网络名字空间与系统空间的数据转发

如果网络名字空间内的网络设备通信仅在命名空间内部进行,那么命名空间内的网络信息如何与宿主机的系统空间进行通信呢?

名字空间与系统间的通信是通过VETH设备来实现的。VETH (Virtual ETHernet)成对出现,一个在名字空间内(如Docker、LXC),另一个在系统空间中,向其中某一个设备发送的数据将自动转发到另一个设备,从而实现系统与多个名字空间的通信。

例如,我们准备为已经创建的namespace01namespace02创建两对VETH设备:

# ip link add ns01-veth-out type veth peer name ns01-veth-in
# ip link add ns02-veth-out type veth peer name ns02-veth-in

之后,就可以通过ip addr list看到系统中已经成功创建了两对网络设备。我们进一步将ns01-veth-in赋给netspace01,将ns02-veth-in赋给netspace02名字空间:

# ip link set ns01-veth-in netns netspace01
# ip link set ns02-veth-in netns netspace02

之后,就可以通过以下命令:

# ip netns exec netspace01 ip addr list

在名字空间内部看到VETH接口了:

1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default
       link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
12: ns01-veth-in: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether fe:93:7d:ad:39:49 brd ff:ff:ff:ff:ff:ff

然后为此端口设置IP地址及默认网关地址:

# ip netns exec netspace01 ifconfig ns01-veth-in 10.7.113.194/24
# ip netns exec netspace01 route add default gw 10.7.113.2

那么,如何能够让名字空间内的虚拟网络设备的数据通过宿主机的eth0端口进行数据收发呢?

我们知道,netspace01空间内的ns01-veth-in接口的数据都将被转发到系统空间的ns01-veth-out端口,若将eth0与ns01-veth-out端口加入到系统空间中的同一个网桥后,netspace01名字空间内ns01-veth-in接口的数据就可以通过宿主机的eth0端口与外部通信了:

# brctl addbr br0
# brctl addif br0 eth0 ns01-veth-out
# brctl show

得到的结果如下:

bridge name     bridge id               STP enabled     interfaces
br0             8000.06edfa6d3d34       no              eth0
                                                        ns01-veth-out

综合使用VLAN、VXLAN和GRE等技术,可以形成更为复杂的网络机制。

2.10 小结

本章中,我们汇集并介绍了网卡、网桥、VLAN、GRE以及VXLAN等网络背景知识,并提供了Open vSwitch与VXLAN的实验记录。这些基础知识对于后期更好地理解OpenStack Neutrom网络组件的工作原理起着决定性的作用。

本章中,我们并没有介绍qemu-kvm虚拟化环境、管理工具virt-manager及virsh系列命令的用法,相关内容读者可以进一步参看其他资料。有了虚拟化与网络方面的基础知识,对于应用OpenStack会有很大帮助。

2.11 参考资源

本章的参考资源如下所示。

目录