立即注册 登录
About云-梭伦科技 返回首页

mituan2008的个人空间 https://aboutyun.com/?1420 [收藏] [复制] [分享] [RSS]

日志

Neutron DVR实现multi-host特性打通东西南北流量提前看(by quqi99)

已有 1894 次阅读2015-6-27 10:53



          注意,这块的代码目前都还没有,只是提前进行一下理论分析。

         先温习下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

1, subnet_instance_binding(subnet_id, hostname, port_id, mac_address, ip_versio, ip_address, ip_version)
2, vlan_agent_binding(network_id, hostname, vlan_id)
3, dvr(hostname, dvr_mac_address)
这个表的数据如何插入,当然可以通过openstack框架自身的数据库,但那样在涉及nova的表,所以直接查该agent上的hypervisor或者ovs的数据库是个更好的方法。从这个角度讲,不用表存储这些数据,直接利用l3-agent原有的代码稍微改一下(在同步router时从数据库获取所有ports的地方改成只获取和本机虚拟机的tap的mac地址相关联的port即可)。不过全局有一个这样各机器上subnet和host映射的汇总的表的话,就可以很容易实现类似TRILL(http://blog.csdn.net/quqi99/article/details/11778413)的技术来实现使用switch id + mac来同时转发的模式(好处在于不同switch上的vm可以具有相同的ip)。


CLI:
更新CLI:
1, router-create, 应能列出router对象新增的distribute属性
原有CLI:
1, router-list-on-l3-agent
2, router-port-list
3, router-show
新增CLI:
1, l3-agent-list-hosting-snat
2, l3-agent-snat-add

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



附录一, 一种使用linux bridge时针对网络上出现多个相当IP的网关的ebtables隔离设想(文中已经描述了使用ovs隔离的流规则),注意:未测试

ebtables无法做到同时结合二层和三层的条件(三层的ip-dst和二层的arp-ip-dst)为网关IP返回不同的mac地址(arpreply-mac), 我们可以换一种思路, 令这些同ip的网关的mac地址也相同, 然后这些网关再自己决定它们该接收何冲流量,
FORWARD -m physdev --physdev-in <ex_gw> -d 10.0.0.0/8 -j DROP
FORWARD -m physdev --physdev-in qr-FFF -d ! 10.0.0.0/8 -j DROP
因为内部网关和外部网关的IP相同, 也应该隔离内部网关和外部网关上的ARP流量:
ebtables -t broute -A BROUTING -p arp -i gw --arp-ip-dst 10.0.0.0/8 -j DROP
ebtables -t broute -A BROUTING -p arp -i gw --arp-ip-src 10.0.0.0/8 -j DROP
ebtables -t filter -A FORWARD -p arp --arp-ip-dst 10.10.10.96/27 -j ACCEPT
ebtables -t nat -A POSTROUTING -p arp -o gw --arp-ip-src 10.10.10.100 -j ACCEPT
由于令内部网关与外部网关的IP相同,使用etables统一应答它们的MAC地址:
ebtables -t nat -A PREROUTING -i tapPORT_ID -p arp --arp-opcode Request --arp-ip-dst REMOTE_VM_IP -j arpreply --arpreply-mac REMOTE_VM_MAC --arpreply-target ACCEPT

也需要隔离内部网关上的DHCP广播:
FORWARD -m physdev --physdev-in qr-FFF -d 255.255.255.255 -p udp --dport 67 -j DROP

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 )


路过

雷人

握手

鲜花

鸡蛋

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 立即注册

关闭

推荐上一条 /2 下一条