neutron-高可用(1)--DVR

环境 fuel8.0

介绍

DVR简称分布式路由,M版前的neutron网络结构。

无论是南北流量中的1:N还是1:1还是东西流量也好都经过网络节点,这就带来一个问题了,网络节点负载很大,往往成为整个架构的性能短板,同时还很容易出现单点故障。
在Juno版本后可以配置DVR模式,每个compute节点上都配置了一个L3 agent,集群内的流量(东西流量)这里有个前提条件,同网段内主机在不同compute节点,在同一个compute节点就直接通过本机就能直接转发了。直接就通过tunnel到达另外一个compute节点,不在需要通过网络节点去做转发了,而配置了floatting ip的主机,直接通过本compute节点的L3 agent 通过br-ex连接外网。


进行深入前的一些基本概念的讲解:
路由策略
引用百科里的一句话
路由策略是一种基于目标网络进行路由更加灵活的数据包路由转发机制。应用了路由策略,路由器将通过路由图决定如何对需要路由的数据包进行处理,路由图决定了一个数据包的下一跳转发路由器。 路由策略的种类 大体上分为两种:一种是根据路由的目的地址来进行的策略称为:目的地址路由; 另一种是根据路由源地址来进行策略实施的称为:源地址路由! 随着路由策略的发展现在有了第三种路由方式:智能均衡的策略方式!

使用 ip rule 操作策略路由

基于策略的路由比传统路由在功能上更强大,使用更灵活,它使网络管理员不仅能够根据目的地址而且能够根据报文大小、应用或IP源地址等属性来选择转发路径。
ip rule 查看策略路由表

数字越小,优先级越高

规则0,它是优先级别最高的规则,规则规定,所有的包,都必须首先使用local表(254)进行路由。本规则不能被更改和删除。

规则32766,规定所有的包,使用表main进行路由。本规则可以被更改和删除。

规则32767,规定所有的包,使用表default进行路由。本规则可以被更改和删除。

在默认情况下进行路由时,首先会根据规则0在本地路由表里寻找路由,如果目的地址是本网络,或是广播地址的话,在这里就可以找到合适的路由;如果路由失败,就会匹配下一个不空的规则,在这里只有32766规则,在这里将会在主路由表里寻找路由;如果失败,就会匹配32767规则,即寻找默认路由表。如果失败,路由将失败。重这里可以看出,策略性路由是往前兼容的。

3232243201: from 192.168.30.1/24 lookup 3232243201 #这条规则的含义是规则3232243201 源ip为192.168.30.1/24的包,使用local表3232243201 进行路由

linux二层网络中一些基本名词

TAP设备:如kvm创建虚拟机后,宿主机上的vnet0、vnet1等,是操作系统内核中的虚拟网络设备。
veth配对设备(veth pair)或ovs配对设备,它其实是一对网卡把一块叫veth,另外一块叫peer,当一个数据真被发送到其中一端中,veth的另外一端也会收到此帧。在虚拟化中常用veth pair来连接两个bridge,比如qbr网桥跟br-int网桥上的qvb-xxx和qvo-xxx就是一对veth pair。

启用DVR

以下配置的前提是开启了l2_population
l2population原理介绍如下
http://blog.csdn.net/cloudman6/article/details/53167522

1,安装

compute节点

(1)安装l3-agent
(2)修改的内核参数

1
2
3
4
5
6
vi /etc/sysctl.conf
net.ipv4.ip_forward = 1
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0

sysctl -p

(3)增加一块能上外网的网卡,并创建个br-ex网桥把这块网卡桥接到br-ex上

1
2
ovs-vsctl add-br br-ex
ovs-vsctl add-port br-ex ethx

(4)配置l3agent.ini

1
2
3
4
5
6
7
vim /etc/neutron/l3_agent.ini

interface_driver =neutron.agent.linux.interface.OVSInterfaceDriver
use_namespaces = True
agent_mode = dvr
````
vim /etc/neutron/plugins/ml2/ml2_conf.ini

[agent]
enable_distributed_routing=True

1
2
3
4
5

重新启动 neutron-openvswitch-agent, netron-l3-agent ,openvswitch-switch 服务。


#### 网络节点

vim /etc/neutron/l3_agent.ini
agent_mode = dvr_snat

1
2
3
4
```
vim /etc/neutron/plugins/ml2/ml2_conf.ini
[agent]
enable_distributed_routing=True
1
重启neutron-server、netron-l3-agent ,openvswitch-switch 服务。

配置成功后可以neutron agent-list 看见compute的l3-agent。

原理解释

1台control节点(server-4),2台compute(server-5、server-6)、外网为192.168.122.0/24
在control节点上在控制台创建个网络,创建个路由器,设置网关,在路由器上将网络端口添加进去。在基于此网络创建个主机。
可以发现在control节点上创建路由器时,会同时在namespace里面创建qroute-xxx和snat-xxx两个命名空间,snat-xxx命名空间会根据创建的子网来添加接口,qg-xxx和sg-xxx,其中qg-xxx上面配置了外网ip,sg-xxx配置的是本子网可用的第一个ip(前两个为网关和dhcp)

当该网络内其他主机需要上外网时,源ip会已postrouting形式,snat成路由器的网关,这步操作会在snat-xx命名空间内做


在传统网络架构下,snat操作本来是应该在qroute下进行,而在DVR模式下qroute-xxx完全是连接内网的网关。

当创建一个实例时,会自动在实例所在的compute节点创建一个qroute-xxx 此qrouter-xxx的ip和mac都与control节点的一样。

当给实例分配一个floating_ip时,在自动在实例所在的计算节点namespace里面生成fip-xxx命名空间

需要注意的是fip-xxx这个id是与你的public网络id是一致

也就是说一个public网络对应一个fip-xxx namespace,在下面会解释为什么这样做
节点fg-xxx对应的是外网接口,fpr接口与qrouter接口一对veth pair

DVR模式下流量的走向

南北流量(1:N)

所谓南北流量(1:N)实际上就是指SNAT就是子网内的主机通过路由器的floatingIP去上外网
1,首先需要确认router已经发到compute节点,我这router叫test2
可以看见已经在server-6上有了

我在vm(192.168.50.4)上面ping百度

因为是跨网段的,所以发送给默认路由,就是网关。
在网关上路由策略可以看见发现,发给默认路由192.168.50.1的数据,最终会发给192.168.50.3

那192.168.50.3在哪呢,通过前面分析,我们知道,192.168.50.3在control节点snat-xx命名空间里面

然后在iptables里面做一次snat

就出外网了,因为我这是KVM虚拟机里面所以还要nat一层。

ping public网络 192.168.122.1 然后抓包分析

所以SNAT流程

1
2
3
                    (compute节点)         vxlan    (network节点)
vm--->qr-xxx--->br-int---->br-tun---> br-tun----->br-int----->snat-xxx----br-ex

南北流量(1:1)

给主机192.168.50.4绑定一个floating_ip


观察control节点和compute节点的namespace发现
control节点
没有发生变化,而vm所在的compute的节点的namespace发现多了一个
fip命名空间

注意看这个fip的ip是我们创建的外网网络id,这个在上面已经说过了。
查看一个这个fip-xxx的内容

vm绑定floating_ip后如何跟外网进行通信

1,vm ping外网,首先数据包丢给默认路由,qroute,
2,查找路由表

命中table 16

走rfp端口

3,然后进行snat


4,然后发送给fip-xxx命名空间

因为已经进行snat了地址变成外网的,所以这里都default route 直接给外网网关,完成

如下图
来源http://www.cnblogs.com/sammyliu/p/4713562.html


vm绑定vip后外网DNAT进入内网主机
1,arp-proxy
外网ip要ping通内网,首先需要知道内网ip的mac,fip,并没有直接绑定在一个特定的端口是怎么知道mac的呢

进行路由追踪发现

arping发现mac地址为 尾数为C7:C3的

那这个mac地址为谁的

竟然是fip-xxx的fg端口

原来是fip-xxx在fg这个端口上做了arp-proxy,这样,fg既可以响应发给它自己的arp请求,也可以响应发给经过它路由的端的arp请求


可以看见内核参数里面已经开启了

2,将包丢给路由器


我们从fip-xxx ip route 可以看见包被丢给169.254.93.254这个接口了,这个接口是qroute-xxx的一个接口

3,qroute–xxx做DNAT

1
2
3
4
5
流程如下

arp欺骗 通过fpr DNAT
extra----->fip--xxx---->qroute-----> VM

为什么要独立出一个snat namespace来做SNAT,而不继续之前的qrouter多SNAT方案?

因为 当创建子网的第一台主机时,会同时在compute节点上也创建个qrouter-xxx的namespace,但computer节点上的qrouter并不做snat功能,只做当有绑定float_ip时 连接FIPnamespace中转,所以需要将SNAT功能独立出来,于是就有了SNATnamespace当然这个也只会在网络节点的namespace里面创建。

当虚拟机绑定fip时,为什么compute要多出一个fip namespace,不直接在qrouter上的qg直接连接br-ex?
是为了减少暴露在外部网络上的mac和ip地址,所以才需要有fip的出现。由于传统router只在网络节点上,数量很少,直接在传统router的qg上配floating ip和用其mac地址应答arp请求,所以没这个问题。但是dvr router由于分布到大量的compute node(每个私有网络都可能有一个router),如果再这么做,会导致有大量router的qg接口暴露在外部网络上,因此分离出fip,而fip是按照(compute node,external network)分配的,数量少很多。一个external_network就一个另外fip也可以做集中的arp proxy,不需要把floating ip真正绑到fip的接口上。同时也可以减少交换机MAC地址表的占用,减轻交换机的负担。