openstack neutron网络插件学习(三)【Open vSwitch实现】

目录

3.1 Open vSwitch

3.1.1 Open vSwitch配置

3.1.2 OVS中的网络设备类型

3.1.3 Local Network

3.1.4 Flat Network

3.1.5 Vlan Network

3.1.5 Routing

3.1.6 Vxlan


3.1 Open vSwitch

3.1.1 Open vSwitch配置

      相对linux-bridge,首先需要安装openstack-neutron-openvswitch。然后对应将ML2 的配置文件 /etc/neutron/plugins/ml2/ml2_conf.ini中的mechanism driver设置为openvswitch。组网方式其实与linux-bridge相差无几,可以通过 neutron agent-list 命令查看到 neutron-openvswitch-agent在节点上的运行情况。

3.1.2 OVS中的网络设备类型

Neutron默认在网络节点(此处网络节点与控制节点合一)上创建三个网桥:br-ex,br-int 和 br-tun。计算节点上也有 br-int 和 br-tun(没有br-ex网桥)。

  • br-ex:连接外部(external)网络的网桥。
  • br-int:集成(integration)网桥,所有 instance 的虚拟网卡和其他虚拟网络设备都将连接到该网桥。
  • br-tun:隧道(tunnel)网桥,基于隧道技术的 VxLAN 和 GRE 网络将使用该网桥进行通信。

这些网桥需要用 Open vSwitch 的命令 ovs-vsctl show进行查看,如下所示:

在 Open vSwitch 环境中,一个数据包从 instance 发送到物理网卡大致会经过下面几个类型的设备:

1、tap interface:命名为 tapXXXX;2、linux bridge:命名为qbrXXXX;3、veth pair:命名为 qvbXXXX, qvoXXXX;4、OVS integration bridge:命名为 br-int;5、OVS patch ports:命名为 int-br-ethX 和 phy-br-ethX(X 为 interface 的序号);6、OVS provider bridge:命名为 br-ethX(X 为 interface 的序号);7、物理 interface:命名为 ethX(X 为 interface 的序号);8、OVS tunnel bridge:命名为 br-tun。

其中,OVS provider bridge 会在 flat 和 vlan 网络中使用;OVS tunnel bridge 则会在 vxlan 和 gre 网络中使用;

3.1.3 Local Network

      对于一个local类型的网络,其DHCP的TAP设备是直接关联到br-int网桥的,通过veth连接到dhcp的namesapce,在namespace里查看网卡名称也是tapXX的描述。这点在linux-bridge既有相同之处,也有不同之处,两者的实现方式还是不同的。区别在于,对于linux-bridge实现方式,一端连接的tap设备,另一端是连接的对应namespace的ns设备。

       值得注意的是,brctl show主要是对于linux-bridge环境下查看网桥的配置信息,对于Open vSwitch则是用ovs-vsctl show 查看 bridge 的配置。当新建一个VM实例时,通过ovs-vsctl show查看网桥下br-int下增加一个qvoxxx类型的设备,而通过brctl show查看会发现新建了一个qbrxx网桥,关联tapxx设备与qvb设备。其中qvb设备与qvo设备之间组成了一对veth pair(可以通过ethtool -S查看设备veth pair的对应索引关系statistics),相当于实例VM首先与新建的qbrxx网桥上的tapxx设备互联,qbrxx再通过veth pair与br-int网桥互联,总体结构如下图。从而,VM实例的tapxx设备(虚拟网卡)则间接连接到了br-int网桥。这点相对之前linux-bridge实现方式----直接通过tap设备与新建的网桥关联,结构上要相对复杂。

       增加qbrxx这个网桥的原因主要是: Open vSwitch 目前还不支持将 iptables 规则放在与它直接相连的 tap 设备上。如果做不到这一点,就无法实现 Security Group 功能。对于不同的local network网络,所有的VM实例间接都连接到同一个br-int网桥,Open vSwitch是怎么进行不同local网络的隔离呢?-----答案就是:通过vlan进行隔离。先看下面一张图:

        其中qvo设备可以看成不同实例VM连接网桥br-int的接口,tap设备为不同local 网络的dhcp设备,tag其实就是vlan tag(与物理交换机上的vlan无关,虚拟交换机的vlan区分),不同local网络的VM之间的隔离就是靠tag进行区分和隔离。结构如下:

3.1.4 Flat Network

       由Open vSwitch实现的Flat网络与linux-bridge的实现方式很类似,都是每个flat网络都会占用一块物理网卡,linux-bridge中直接是通过flat物理标签与宿主机物理网卡一一对应,而Open vSwitch中则是通过网络标签与创建的网桥进行对应,网桥与宿主机的物理网卡进行一一对应。基本配置与linux-bridge类似,如下:

修改租户网络类型:

设置网络标签:

设置ovs mapping中标签与网桥对应关系,注意此处对应的网桥是后续需要创建的

       网桥创建命令:ovs-ovctl,ovs-ovctl add-br [网桥名称] 表示创建网桥,ovs-ovctl add-port [网桥名称] [网卡]。当创建多个标签时,之间用逗号隔开,同时在映射关系上也对应多个网桥,每个网桥对应不同网卡。ovs-vsctl show可以看到:

      对于 ovs bridge “br-eth1” 和其上桥接的 port “eth1” 我们应该不会感到意外,这是前面配置的结果。然而除此之外,br-int 和 br-eth1 分别多了一个 port “int-br-eth1” 和 “phy-br-eth1”,而且这两个 port 都是 “patch” 类型,同时通过 “peer” 指向对方。这表明:br-int 与 br-eth1 这两个网桥通过 int-br-eth1 和 phy-br-eth1 连接在一起了。其网络结构如下图所示:

       这里可以看到网桥br-int 与 br-eth1之间是通过patch port 连接在一起,而不是veth pair。总的看来,patch port 是 ovs bridge 自己特有的 port 类型,只能在 ovs 中使用。如果是连接两个 ovs bridge,优先使用 patch port,因为性能更好。对于ovs网桥之间可以使用patch port,性能更好,除外其他情况一般只能使用veth pair进行网桥连接。

       通过对比flat网络类型与local网络类型可以发现,flat网络类型相对而言只是多了一个自己创建的网桥(对应某块物理网卡),DHCP的TAP设备都是挂在br-int这个默认集成网桥上,OVS网桥通过patch port与br-int网桥进行连接,br-int网桥再通过veth pair与关联实例tap设备的qbr网桥连接。从而完成了VM实例间接连接到了br-xxx网桥(创建的对应物理网卡的网桥)。其网络结构图如下所示:

3.1.5 Vlan Network

       在 Open vSwitch 实现方式下,不同 vlan instance 的虚拟网卡都接到 br-int (集成网桥)上。这一点与 linux bridge 非常不同,linux bridge 是不同 vlan (类似网卡子接口如eth1.100等)接到不同的网桥上。配置方式上,Open vSwitch方式是对应网桥(如下),而linux-bridge是对应物理网卡,另外OVS还需要通过ovs-ovctl创建网桥,并在网桥关联相应网卡。其他配置基本都一样,就不再展开说了。

      通过创建网络、实例VM,通过ovs-ovctl查看可以发现这种网络其实和local网络也比较类似,创建的DHCP的TAP设备与VM的port都带有tag,每创建一个VM都会对应创建一个linux-bridge网桥,VM通过网桥间的veth-pair间接连接到br-int。这点很相似。

网络结构如下:

针对不同的vlan网络,vlan网络之间是怎么进行隔离的呢?其实实现原理主要是通过Open vSwitch的flow rule(流规则)进行控制。不同vlan网络的网络架构如下图所示:

        相对于Linux Bridge driver用eth1.xx的vlan接口实现vlan网络隔离。open vswitch则是用flow rule来对进出br-int的集成网桥、br-ethxx网桥等进行流量控制,可以对相应进出端口的流量进行加vlan标签、修改vlan标签、剥vlan标签,从而完成vlan网络的隔离。查看 flow rule 的命令是 ovs-ofctl dump-flow <bridge>,首先查看计算节点 br-eth1 的 flow rule:

可以看到,每条 rule 有不少属性,其中比较重要的属性有:

  • priority:rule 的优先级,值越大优先级越高。Open vSwitch 会按照优先级从高到低应用规则;
  • in_port:inbound 端口编号,每个 port 在 Open vSwitch 中会有一个内部的编号。可以通过命令 ovs-ofctl show <bridge> 查看 port 编号。比如 br-eth1:

  • dl_vlan:数据包原始的 VLAN ID;
  • actions:对数据包进行的操作;

首先分析一下br-eth1的flow rule的关键信息,ovs-ofctl show br-eth1查看:

priority=4,in_port=2,dl_vlan=1 actions=mod_vlan_vid:100,NORMAL
priority=4,in_port=2,dl_vlan=5 actions=mod_vlan_vid:101,NORMAL

第一条的含义是:从 br-eth1 的端口 phy-br-eth1(in_port=2)接收进来的包(其实就是VM的数量包由br-int的int-br-eth1端口发送给的phy-br-eth1端口的包),如果 VLAN ID 是 1(dl_vlan=1),那么需要将 VLAN ID 改为 100(actions=mod_vlan_vid:100)

怎么理解将 VLAN ID 1 改为 VLAN ID 100 呢?

通过ovs-vsctl show命令查看节点的open vswitch网桥配置:

        可以看到,br-int网桥下不同的port的带有不同的tag标签,这个tag可以看作是节点内部的vlan标签,通过这种内部的vlan标签来隔离port,内部的vlan tag对应不同的vlan网络,该对应关系由neutron进行维护,并将转换规则配置在 flow rule 中。该内部vlan tag只在br-int有效,与外部网络的vlan无关,不同于物理网络的vlan。总的来看,进入br-ethxx网桥phy-br-ethxx端口的报文,flow rule是将原来的内部vlan转换成对应配置的vlan tag;而进入br-int网桥的int-br-ethxx则是将物理vlan替换回int-br的内部vlan。从而完成了vlan网络的隔离。

3.1.5 Routing

       Routing主要是由L3 agent提供服务,L3 agent需要正确配置才能工作,配置文件为 /etc/neutron/l3_agent.ini。大部分情况下默认配置已经帮我们配置好了,不需要再单独配置。需要注意:

如果 mechanism driver 是 open vswitch,则:

interface_driver = neutron.agent.linux.interface.OVSInterfaceDriver

。。。。。

如果选用 linux bridge,则: 

interface_driver = neutron.agent.linux.interface.BridgeInterfaceDriver

L3 agent运行在网络节点或者控制节点(如果网络节点与控制节点合一)

        对于routing的底层实现,可以进一步分析来看。创建两个vlan网络vlan 100、vlan 101。底层上在br-int对应增加了两个port(分别对应两个vlan)。与 linux bridge 实现方式一样, router_100_101 运行在自己的 namespace 中。与linux-bridge不同的地方在于,router的qrxx端口在ovs中是直接作为br-int网桥上的Port存在的,没有linux-bridge的veth pair线路将qrxxx设备与网桥上的tap设备互联。此外,可以看到br-int网桥上的router的port也是带tag的,对应vlan在br-int网桥上的内部vlan。

整体的网络结构参加下图:

        以上讲解了neutron网络内跨vlan网络的互访情况,那么对于外部外部网络的访问,是如何实现呢?首先 需要设置外部网络的标签,例如标签label命名为 “external”,网桥为 br-ex。

如果类型为 flat,控制节点 /etc/neutron/plugins/ml2/ml2_conf.ini 配置如下:

如果类型为 vlan,配置如下:

       此外,我们还需要在节点上通过ovs-vsctl add-br br-ex命令创建网桥,然后由ovs-vsctl add-port br-ex xxx命令将xxx网卡关联到br-ex网桥。总的来说,当外部网络为flat网络时,每个flat网络对应一块物理网卡,如果有多个外部网络则需要多块物理网卡与之对应;当外部网络为vlan网络时,多个不同vlan的flat网络可以对应一块网卡。创建完成外部网络,可以查看到底层网桥上br-int与br-ex之间通过int-br-ex与phy-br-ex的patch port连接起来。

     创建完成外部网络的子网后,neutron会自动在br-ex网桥上分配一个port(qgxxx)。router interface 的命名规则如下: 1. 如果 interface 用于连接租户网络,命名格式为 qr-xxx(关联br-int网桥);2. 如果 interface 用于连接外部网络,命名格式为 qg-xxx(关联br-ex网桥)。br-int与br-ex之间也是由一对patch port连接起来,主要用来承载VM进出外部网络的流量。网络架构整体描述如下:

       通过图上可以看出,一台VM想要访问外部网络,经过的路径为:qvbxxx(接口,存在vm自身tap设备关联的网桥上qbrxxx)→qvoxxx(接口,br-int网桥上)→qrxx接口(router接口)→int-br-ex(br-int网桥上)→phy-br-ex(br-ex网桥上)→qgxxx(br-ex网桥)→外部网络。qrxx与qgxx接口之间并不是直接通过router过来的,而是需要通过int-br-ex与phy-br-ex这对patch port间通过。其出网过程中,与linux-bridge实现方式一样,会进行SNAT转换,入网则用float ip模式进行DNAT转换。

3.1.6 Vxlan Network

配置准备:在/etc/neutron/plugins/ml2/ml2_conf.ini配置文件中使能vxlan、l2population,指定租户vxlan网络的配置范围。

设置租户创建网络类型为vxlan:

设置vxlan的范围:

设置agent的类型为vxlan。使能l2_population(目的是减少vxlan内隧道里的arp泛洪报文)

ovs中配置local_ip地址和对应网桥,没有指定网卡对应关系,通过对应的ip查找路由选择对应从哪块网卡出去(这点与linux-bridge的方法比较类似):

其网络架构的网桥桥接模式与vlan网络比较类似,br-int网桥与br-tun网桥之间通过patch port互联(patch-tun~patch int)(如下):

通过比较其底层的网络结构,与vlan网络大部分都比较类似,相对而言vxlan网络在br-tun网桥下会多创建一个port vxlanxxx(上面记录了本端与对端的VTEP IP),用来在控制节点与计算节点之间建立vxlan隧道。控制节点上:

计算节点上:

其网络结构如下所示:

      隧道建立起来了,VM之间的数据流量在整个过程是怎么转发呢?------这主要是依靠flow rule来指导进行转发,该部分也是很复杂的一部分内容,按照之前的例子分别查看br-int、br-tun的流表。

br-int的flow rule:

br-int 的 rule 看上去虽然多,其实逻辑很简单,br-int 被当作一个二层交换机,其重要的 rule 是下面这条:

cookie=0xaaa0e760a7848ec3, duration=52798.625s, table=0, n_packets=143, n_bytes=14594, idle_age=9415, priority=0 actions=NORMAL

此规则的含义是:根据 vlan 和 mac 进行转发。

br-tun 的 flow rule:(主要)

这些才是真正处理 VXLAN 数据包的 rule,其流程如下:

上图各方块中的数字对应 rule 中 table 的序号,下面分析各个table的功能与作用。

table 0:

cookie=0xaaa0e760a7848ec3, duration=76707.867s, table=0, n_packets=70, n_bytes=6600, idle_age=33324, hard_age=65534, priority=1,in_port=1 actions=resubmit(,2)

cookie=0xaaa0e760a7848ec3, duration=76543.287s, table=0, n_packets=56, n_bytes=4948, idle_age=33324, hard_age=65534, priority=1,in_port=2 actions=resubmit(,4)

cookie=0xaaa0e760a7848ec3, duration=76707.867s, table=0, n_packets=0, n_bytes=0, idle_age=65534, hard_age=65534, priority=0 actions=drop

结合如下port编号:

     table 0 flow rule 的含义为:(即第一条 rule 处理来自内部 br-int(这上面挂载着所有的网络服务,包括路由、DHCP 等)的数据;第二条 rule 处理来自外部 VXLAN 隧道的数据。)

  1. 从 port 1(patch-int)进来的包,扔给 table 2 处理:actions=resubmit(,2)
  2. 从 port 2(vxlan-a642100b)进来的包,扔给 table 4 处理:actions=resubmit(,4)

table 4:

cookie=0xaaa0e760a7848ec3, duration=76647.039s, table=4, n_packets=56, n_bytes=4948, idle_age=33324, hard_age=65534, priority=1,tun_id=0x64 actions=mod_vlan_vid:1,resubmit(,10)

table 4 flow rule 的含义为: 如果数据包的 VXLAN tunnel ID 为 100(tun_id=0x64),action 是添加内部 VLAN ID 1(tag=1),然后扔给 table 10 去学习。

table 10:

cookie=0xaaa0e760a7848ec3, duration=76707.865s, table=10, n_packets=56, n_bytes=4948, idle_age=33324, hard_age=65534, priority=1 actions=learn(table=20,hard_timeout=300,priority=1,cookie=0xaaa0e760a7848ec3,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:0->NXM_OF_VLAN_TCI[],load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[],output:NXM_OF_IN_PORT[]),output:1

table 10 flow rule 的含义为: 学习外部(从 tunnel)进来的包,往 table 20 中添加对返程包的正常转发规则,然后从 port 1(patch-int)扔给 br-int。

rule 中下面的内容为学习规则,这里就不详细讨论了。

NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:0->NXM_OF_VLAN_TCI[],load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[],output:NXM_OF_IN_PORT[]

table 2:

cookie=0xaaa0e760a7848ec3, duration=76707.866s, table=2, n_packets=28, n_bytes=3180, idle_age=33324, hard_age=65534, priority=0,dl_dst=00:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,20)
cookie=0xaaa0e760a7848ec3, duration=76707.866s, table=2, n_packets=42, n_bytes=3420, idle_age=33379, hard_age=65534, priority=0,dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,22)

table 2 flow rule 的含义为:

  1. br-int 发过来数据如果是单播包,扔给 table 20 处理:resubmit(,20)
  2. br-int 发过来数据如果是多播或广播包,扔 table 22 处理:resubmit(,22)

table 20:

cookie=0xaaa0e760a7848ec3, duration=76543.287s, table=20, n_packets=28, n_bytes=3180, idle_age=33324, hard_age=65534, priority=2,dl_vlan=1,dl_dst=fa:16:3e:fd:8a:ed actions=strip_vlan,set_tunnel:0x64,output:2

cookie=0xaaa0e760a7848ec3, duration=76707.865s, table=20, n_packets=0, n_bytes=0, idle_age=65534, hard_age=65534, priority=0 actions=resubmit(,22)

table 20 flow rule 的含义为:

  1. 第一条规则就是 table 10 学习来的结果。内部 VLAN 号为 1(tag=1),目标 MAC 是 fa:16:3e:fd:8a:ed(virros-vm2)的数据包,即发送给 virros-vm2 的包,action 是去掉 VLAN 号,添加 VXLAN tunnel ID 100(十六进制 0x64),并从 port 2 (tunnel 端口 vxlan-a642100b) 发出。
  2. 对于没学习到规则的数据包,则扔给 table 22 处理。

table 22:

cookie=0xaaa0e760a7848ec3, duration=76543.282s, table=22, n_packets=2, n_bytes=84, idle_age=33379, hard_age=65534, dl_vlan=1 actions=strip_vlan,set_tunnel:0x64,output:2

cookie=0xaaa0e760a7848ec3, duration=76707.82s, table=22, n_packets=40, n_bytes=3336, idle_age=65534, hard_age=65534, priority=0 actions=drop

      table 22 flow rule 的含义为: 如果数据包的内部 VLAN 号为 1(tag=1),action 是去掉 VLAN 号,添加 VXLAN tunnel ID 100(十六进制 0x64),并从 port 2 (tunnel 端口 vxlan-a642100b) 发出。匹配不上就丢弃。

      以上简单对流表进行了分析,可以看出是很复杂的,也是neutron学习过程中很烧脑的部分。此外,vxlan的float ip和routing和vlan网络类似,不再讲解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值