为了提高neutron网络服务的鲁棒性与性能,OpenStack从J版开始正式加入的DVR(Distributed Virtual Router)服务,它将原本集中在网络节点的部分服务分散到了计算节点上。
在该模式下,同租户的跨网段路由在计算节点之间直接完成,无需网络节点的参与。SNAT服务仍有网络节点集中化的处理。Floating服务则可以选择在计算节点分布式地处理,也可以选择在网络节点中心化的处理。
DVR在带来网络服务鲁棒性与性能提升的同时,也带来了一些缺陷。东西向的FWAAS服务变得无法实现,具体参考“链接”。简单来说就是FWAAS功能依赖于在同命名空间的vrouter下看到双向(有状态)的进出两条流。现在部署DVR功能后的东西向通信,打破了这条规则。下面将对OpenStack Queens版本的 DVR部署进行阐述分析。
部署
准备
已经部署好的基于租户网络是vxlan的OpenStack环境
控制节点配置
文件:neutron.conf
router_distributed = true
重启服务
systemctl restart neutron-server.service
网络节点配置
文件:openvswitch_agent.ini
l2_population=true
enable_distributed_routing = true
文件:l3_agent.ini
agent_mode =dvr_snat
external_network_bridge 留空
重启服务
systemctl restart openvswitch.service
systemctl restart neutron-openvswitch-agent.service
systemctl restart neutron-l3-agent.service
systemctl restart neutron-dhcp-agent.service
systemctl restart neutron-metadata-agent.service
计算节点配置
安装neutron相关服务
yum install openstack-neutron
修改内核配置
echo '
net.ipv4.conf.all.rp_filter=0
net.ipv4.conf.default.rp_filter=0
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
'>>/etc/sysctl.conf
sysctl -p
修改配置dhcp_agent.ini,l3_agent.ini,metadata_agent.ini这3个文件。
文件:openvswitch_agent.ini
l2_population=true
enable_distributed_routing = true
文件:l3_agent.ini
agent_mode =dvr
external_network_bridge 留空
添加对外网桥,eth_TBD,IP_TBD要根据实际环境而定
echo '#
ovs-vsctl add-br br-ex
ovs-vsctl add-port br-ex eth_TBD
ovs-vsctl show
ifconfig eth_TBD 0.0.0.0
ifconfig br-ex IP_TBD/24
#'>>/etc/rc.local
chmod +x /etc/rc.d/rc.local ; tail -n 8 /etc/rc.local |bash
重启服务
systemctl restart openvswitch.service
systemctl restart neutron-openvswitch-agent.service
systemctl restart neutron-l3-agent.service
systemctl restart neutron-dhcp-agent.service
systemctl restart neutron-metadata-agent.service
验证操作
在控制节点上查看network agent。
实验分析
部署虚机与网络
总览
本着“无图无真相””一图胜千言”的原则,在接下来的分析中争取多放图,少废话。
在部署好DVR,虚机,网络后,整个系统的网络组成及各节点上的功能分布如下图所示。
同节点东西向
跨节点东西向
从上表中我们可以直观的看到跨节点的路由通信过程。原理与传统路由功能基本一致。唯一的区别在进入VXLAN隧道前把原本网关MAC替换成DVR_HOST_MAC,在出VXLAN隧道后又把DVR_HOST_MAC换回网关MAC。具体原理我们将在“如何解决各节点上DVR的冲突”这一小节给出解释。
进入qrouter这个命名空间就使用linux的高级路由功能来完成路由过程。(引用《深入理解openstack neutron》中一句话:“Linux创建router并没有像创建虚机bridge那样,有一个直接的命令brctl,而且它间接命令也没有,不能创建虚拟路由器……因为它就是路由器(router)”)。在compute-1计算节点上我们可以观察到如下图所示信息。不同网段该从哪个qr口出去,不同neighbor的IP,MAC的对应关系都是有neutron事先设置好的。
NAT
这里遇到了和上一小节同样的问题。具体原理我们将在“如何解决各节点上DVR的冲突”这一小节给出解释。
FloatingIP
如何解决各节点上DVR的冲突
在各节点上的vrouter其qr口的IP,MAC都是图中各network:router_interface_distributed Port的IP,MAC.在这种情况下,各节点中的VM是如何正确的找到同宿主机下正确的vrouter及正确的网关的呢?
让我们看一下br-tun上的部分流表
从图中可知,br-int中进入br-tun中的所有流量都会经过table 1的筛选过滤。注意流表项5、6、7、8的匹配项。这4条流表把所有查询网关MAC的ARP广播报文丢弃,把所有目的MAC是网关MAC的未知单播报文都丢弃。这里就确保了一个宿主机内的VM只能感知到本宿主机内的vrouter,或者认为一些数据包是同宿主机内的vrouter给其转送数据包。
但是经过上面描述的处理后,那么三层转发报文又如何能到达其他节点呢?这里我们看一段社区给出的说明。
在初始化期间,OVS agent需要知道其持有的唯一的DVR MAC地址,以此在br-tun,br-int中输入正确的流表项。出于这个目的,L2 agent通过RPC的方式调用ML2 plugin中的get_dvr_mac_address(host_id)函数。
让我们去控制节点看看这个dvr_mac_address又是什么。在Tables_in_neutron中找到一张名为dvr_host_macs的表,查询其中的内容我们是不是又发现了熟悉的MAC。这些都是neutron分配的,全局唯一的,与各节点一一对应的MAC地址。如果有心的话在配置控制节点的neutron.conf文件时,可以看到有个名为”dvr_base_mac”配置项,该项可以自定义DVR MAC的前缀高位。
所有跨界点的三层通信,在出节点前都会把源MAC是网关MAC的报文,把源MAC都替换成各节点都唯一的DVR host MAC。这里也就解释了上面跨节点东西向和NAT中遗留的问题了。
总结
从实质上讲,neutron的DVR模式并没有使用任何颠覆性的技术手段。可以说也就是把原有的VRouter给Distribute了。至于生产环境中是否需要采用DVR功能,可能这也是网络性能,鲁棒性与网络可维护性,是否需要东西向FWAAS之间的博弈。