注意,这块的代码目前都还没有,只是提前进行一下理论分析。
先温习下l3-agent原理:l3-agent节点为所有subnet创建内部网关,外部网关,路由等。l3-agent定期同步router时会为将和该router相关联的subnet调度到相应的l3-agent节点上创建网关(根据port的device_owner属性找到对应的port, port里有subnet)。neutron支持在多个节点上启动多个l3-agent, l3-agent的调度是针对router为单位的, 试想, 如果我们创建众多的router, 每一个subnet都关联到一个router的话, 那么也意味着每一个subnet的网关都可被调度到不同的l3-agent上, 从而将不同的subnet的流量分流到不同的l3-agent节点.
但是上述方案不具有HA特性, 所以出现一个VRRP HA的Blueprint继续使用VRRP+Keepalived+Conntrackd技术解决单点l3-agent的HA问题, VRRP使用广播进行心跳检查, backup节点收不到master节点定期发出的心跳广播时便认为master死掉从而接管master的工作(删除掉原master节点上的网关的IP, 在新master节点上重设网关). 可参见我的另一博文:http://blog.csdn.net/quqi99/article/details/18799877
但是, 上述两种方案均无法解决相同子网的东西向流量不绕道l3-agent的状况, 所以又出现了一个名DVR的Blueprint, 如下图:
tenant之间通过namespace隔离, tenenat下可以有多个router, 每个router具有自己的namespace, 一个subnet只能添加到一个router上 (实际上, 如果为这个subnet再生成一个port, 也是可以将这个port加入到另一个router上的, 这点待确认).
一, 先看L2的设计
我想问题的关键是肯定会出现多个计算节点上存在同一子网的网关,所以应该各计算节点上相同子网的所有网关使用相同的IP与MAC地址,或者也可以为每个计算节点生成唯一的DVR MAC地址。然后应该让这些IP局部ARP隔离使之成为真正的内部路由(附录一只是一种我想到的方法),下面看看ovs中的实现(参考:https://wiki.openstack.org/wiki/Neutron/DVR_L2_Agent)
ovs agent原来的ovs流表见如下图(来自:https://wiki.openstack.org/wiki/Ovs-flow-logic, ), patch_int, gre_port, vxlan_port分别是br-tun上的三个port.
进出计算节点的流量都应该替换到DVR MAC地址,流表要在上图的基础上增加,见:https://wiki.openstack.org/wiki/Neutron/DVR_L2_Agent
对于出口流量,
table=1, priority=4, dl_vlan=vlan1, dl_type=arp, ar_tpa=gw1 actions:drop #一计算节点所有子网到其他计算节点其网关的arp流量
table=1, priority=4, dl_vlan=vlan1, dl_dst=gw1-mac actions:drop #一计算节点所有子网到其他计算节点其网关的流量
table=1, priority=1, dl_vlan=vlan1, dl_src=gw1-mac, actions:mod dl_src=dvr-cn1-mac,resubmit(,2) #所有出计算节点的流量使用DVR MAC
对于入口流量,还得增加一个table 9, 插在table 2&3 (改先跳到table 9) 与table 10之间:
table=9, priority=1, dl_src=dvc-cn1-mac actions=output-> patch-int
table=9, priority=0, action=-resubmit(,10)
二、再看L3 (IR) 的设计
肯定要增加一种port类型network:router_interface_distributed,
三、DNAT的设计
对于南北向的流量,如果有floating ip,流量就直接走计算节点。如果没有floating ip,则会走网络节点。
四、SNAT的设计
根据agent_mode的下列三种模式决定SNAT iptables规则是否设置在计算节点上( iptables_manager.ipv4['nat'].add_rule('snat', '-j $float-snat') )
1, legacy, 原来的全局使用一个l3-agent
2, dvr, 用计算节点上的IR来实现SNAT
3, dvr_snat, 使用了DVR特性,但是SNAT走中心化结点
当在DVR模式时,SNAT走中心化网络节点的话,不又会出现网络节点与计算节点同网关的问题吗?可以将网关的IP设置成不一样就可以了啊。这点类似于quantum时期nova中的multi-host特性,每个计算节点都有路由,但网关的IP是不一样的。
再说一下VPN, VPN肯定是需要SNAT走中心化的节点的, 在legency时使用的是qr名空间,但在dvr_snat使用的是snat_名空间,要想使用vpn应该使用snat名空间,见patch: https://review.openstack.org/#/c/143203/
数据结构:
如上所述,因为dvr-agent处理的不是所有subnet的网关,只是和该agent相关联的subnet的网关。所以肯定需要一个数据表记录subnet和agent之间的映射关系,可参考:https://docs.google.com/document/d/1kMUO1-y4yATQNBlAkdjDu7OwFYt5cfzIzb5NKQjhb08/edit?pli=1#heading=h.ttq3kyub25tn
3, l3-agent-snat-remove
Devstack:
http://blog.csdn.net/quqi99/article/details/25923921
neutron.conf
router_distributed = True
l3-agent.ini
agent_mode = dvr_snat
ml2_conf.ini
ml2 section
append ",l2population" to mechanism_drivers
agent section
l2_population = True
tunnel_types = vxlan
enable_distributed_routing = True
FORWARD -m physdev --physdev-out qr-FFF -d 255.255.255.255 -p udp --dport 67 -j DROP
作者:张华 发表于:2014-03-07
版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明(http://blog.csdn.net/quqi99 )