openstack neutron网络插件学习(三)【Open vSwitch实现】
3.1 Open vSwitch配置相对linux-bridge,首先需要安装openstack-neutron-openvswitch。然后对应将ML2 的配置文件 /etc/neutron/plugins/ml2/ml2_conf.ini中的mechanism driver设置为openvswitch。组网方式其实与linux-bridge相差无几,可以通过 neutron agent-lis
目录
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 隧道的数据。)
- 从 port 1(patch-int)进来的包,扔给 table 2 处理:actions=resubmit(,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 的含义为:
- br-int 发过来数据如果是单播包,扔给 table 20 处理:resubmit(,20)
- 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 的含义为:
- 第一条规则就是 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) 发出。
- 对于没学习到规则的数据包,则扔给 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网络类似,不再讲解。
更多推荐
所有评论(0)