01
背景
随着云计算与网络技术的不断发展,公司内越来越多的业务有着上云的需求。我们底层虚拟化团队基于社区openstack版本提供云服务,借助社区的力量能够快速实现一套满足基本功能的云平台。但原生neutron(openstack网络组件)在公司内场景下使用时网络方面会暴露出一些缺陷:比如计算节点规模达到数百上千台时,控制层面性能会比较差;比如DVR模式下使用浮动ip,每台计算节点会额外占用一个浮动ip资源;比如南北向流量高可用性也做的不好,网络节点的宕机可能会引发全网snat、port forwarding流量的断流,虽然可以部署多台网络节点+VRRP的方式实现高可用,但不能实现流量的快速切换,且会加重网络节点的负担;比如公司的IDC物理网络结构是三层网络(可以理解成网关都在接入交换机上,网络的广播域被终结在接入交换机,这种做法可以避免IDC内大面积的广播风暴出现),但neutron的external网络是二层网络,这样就不能实现虚拟机跨交换机迁移,限制了集群规模;比如服务器与交换机紧耦合,一方出故障就可能会造成集群大面积断网,也增加了运维难度等等。
我们为了解决这些问题,提供一个稳定高效的可商用云网络服务,需要在原生neutron的基础上重新设计云平台架构,最终我们采用虚拟化网络+云网关的形式来设计我们的组网架构,下面我们具体看一下。
02
架构介绍
上图所示就是我们的云网络架构图,云网关根据功能可以分为snat网关、fip网关、负载均衡网关、云联网网关、防火墙网关等,不同的网关实现的功能不一样,但与底层neutron的适配没有本质上的差异,由于这篇文章重点讲述底层虚拟化网络与云网关的适配,就以fip网关为例进行介绍。
这里我们将用户流量分为东西向流量和南北向流量两种。
(1)东西向流量采用DVR模式,保持原始neutron架构不变,这里只使用了openstack中最核心的二三层网络和安全组功能,这部分功能是比较稳定的。
(2)南北向流量采用与云网关对接的方式,每台计算节点与云网关建立vxlan隧道,将用户的南北向流量发给网关,由网关来处理转发。云网关其实不是一个单点,而是多台服务器组成的一个集群,它南向通告vip给计算节点,该vip用于与计算节点建立vxlan隧道,即vip就是云网关的vtep ip,这就实现了三层网络,不依赖中间的交换机或者路由器。云网关北向通告fip,用于外网访问fip的引流。
那么我们怎么将用户的南北向流量,引到云网关呢?下面我们具体看一下。
03
引流方案
东西向流量采用DVR模式保持原生neutron架构不变,南北向流量分为虚拟机主动访问外部网络的流量和外部网络主动访问虚拟机的流量这两种情况。
针对虚拟机主动发起的流量,云网关南向对内网交换机通告vip(即云网关集群的vtep ip),计算节点根据该vip建立vxlan隧道,通过vxlan引流到云网关,由网关做nat转换后发往外网;
针对外部网络主动访问虚拟机的流量,云网关向上对外网交换机通告fip,流量到网关后根据neutron侧提供的虚机信息将报文nat转换后通过vxlan引流到计算节点;
04
具体实现
1.计算节点与云网关vxlan隧道怎么建立?
计算节点增加配置项,记录云网关的vtep ip,配置项格式如下:
cfg.StrOpt('fip_gw_vxlan_remote_ip', default='')
拿到vtep ip后,在下发流表时,创建tunnel口(如已创建则pass),发包走vxlan封装。
2.计算节点的南北向流量如何引流到云网关?
(1)虚拟机主动访问外部网络的流量
针对这种流量,原生neutron的逻辑是流量从虚机发出后到该计算节点的qrouter namespace中,然后匹配策略路由下一跳到fip namespace的fpr口,然后从fg口封装vlan出去。我们要想把流量引到云网关,需要在qrouternamespace修改策略路由下一跳到一个特殊的port,我们暂且把这种port称为sgr port,该port与sg port类似存在于snatnamespace中,这样流量会引到br-tun上走vxlan隧道,所以我们只需要针对这种流量设置output口将原先的去往snat网络节点的流量改为去往云网关节点即可。下面我们看下具体规则的下发:
(注意:网络节点和计算节点不能混部,否则流量不会引到br-tun上。)
策略路由的下发:
之前虚机绑定公网ip后,出外网时流经qrouter时,匹配策略路由引到fip namespace,示例如下:
现在将策略路由修改,将默认路由的下一条跳到我们特殊的port,由于该port在网络节点,流量必然引到br-tun上,修改后的策略路由如下:
流量通过策略路由引到br-tun后,我们只需要在br-tun上通过流表导流到云网关即可,流表格式如下:
table=20, priority=2,dl_vlan=29,dl_dst=<sgrport mac> actions=strip_vlan,load:0x19->NXM_NX_TUN_ID[],output:<云网关的隧道口>
(2)外部网络主动访问虚拟机的流量
针对绑定了fip的南北向流量,外网主动访问fip,流量到云网关后,会根据neutron提供的虚机信息将报文nat转换后通过vxlan引流到计算节点;
计算节点收到报文后解vxlan封装,目的mac是dvr host mac,流量会发往qr口,然后匹配流表转给虚机,这块符合原生逻辑不需要适配修改。
3.怎么创建这种特殊的port?
主要分两步:
(1)控制层面记录信息
neutron server创建port,占用一个ip地址,device owner值为network:router_centralized_fip,具体可参考sg port的创建
(2)数据层面创建网卡
ovs agent创建这种router_centralized_fip类型网卡,即下图中sgr开头的虚拟网卡,具体可参考sg口的创建
4.neutron需要通知云网关虚机的什么信息?
neutron需要通知云网关如下信息:
字段 | 说明 |
vm ip | 虚拟机内网ip |
dvr host mac | 虚拟机所在计算节点的dvr host mac |
vni | 虚拟机所在network的vni |
vtep ip | 计算节点的vtep ip |
floating ip address | 虚拟机绑定的浮动ip |
floating ip id | 浮动ip的id |
openstack id | openstack集群id,因为多个openstack集群可能共用一套云网关 |
当上述信息发送变化时,neutron需要通知云网关信息的变化,比如虚拟机的迁移或下线、浮动ip解绑或绑定等操作都要引发neutron重新通知变更信息。
05
新方案的优势
我们先来回顾下文章开头说的那几个问题,看看在新架构下是如何解决的。
1.控制层面性能差的解决方案
这块我们可以从不同角度去优化该问题,比如可以去掉非必要的功能模块,如fwaas、vpnaas、lbaas等;比如可以优化rabbitmq和数据库模块;比如控制节点/网络节点和计算节点分开部署,不混用,保障控制节点的稳定性等。
2.浪费浮动ip资源问题
由于新方案中流量不需要fip namespace,自然也就不需要fg口。我们可以使用subnet的service type属性,分配假公网ip即可,不需要修改代码。
3.南北向流量高可用性和性能问题
云网关集群使用vip与计算节点建立vxlan通道,云网关之间是主主关系,一台或几台宕机不影响整网流量。
云网关是基于dpvs实现的,并且可以根据业务流量动态扩缩容,因此性能可以保障。
4.虚拟机跨交换机迁移问题
由于计算节点与云网关通过vxlan实现三层组网,因此不受物理位置的限制。
5.服务器与交换机紧耦合问题
交换机上不需要配置任何用户网络相关的信息,因此不存在紧耦合。交换机上只负责通过bgp通告浮动ip网段即可。
新架构采用虚拟化网络+云网关的方式,让我们解决了openstack网络原生的一些问题,这使得我们的云平台在稳定性和性能方面都不错,我们也在线上一些主力机房稳定运行了一段时间,后续我们会在此架构的基础上不断优化和创新。