openstack 分布式路由器dvr


DVR(Distributed Virtual Route)分布式虚拟路由

用户可能会发现,所有网络服务都在网络节点上进行,这意味着大量的流量和处理,给网络节点带来了很大的压力。

这些处理的核心是路由器服务。那么如果计算节点上自己就能实现路由器服务的话,无疑是更为合理的。这个思路是正确的,但具体实施起来有诸多的考量和细节问题。

为了降低网络节点的负载,同时提高可扩展性,OpenStack 自 Juno 版本开始正式引入了分布式路由(Distributed Virtual Router,DVR)服务,来让计算节点自己来处理原先的大量的东西向流量和 DNAT 流量(有 floating IP 的 vm 跟外面的通信)。

这样网络节点只需要处理占到一部分的 SNAT (无 floating IP 的 vm 跟外面的通信)流量,大大降低了负载和整个系统对网络节点的依赖。

DHCP 服务和 VPN 服务仍然需要集中在网络节点上进行。

优势:

(1)东西向流量吞吐量增加。

(2)高东西流量下VM平均带宽增加。

(3)南北向流量和东西向流量不再互相干扰。

(4)当东西向流量在同一个Hypervisor上,就不会走过不必要的路径。


型场景

从网络的访问看,涉及到路由服务的至少是需要跨子网的访问,又包括是否是同一机器、是否是涉及到外网(东西向 vs 南北向)。

考虑下面几个典型的场景。

1.东西向

(1)同一机器

路由器直接在 br-int 上转发,不经过外部网桥。

(2)不同机器

 openstack 分布式路由器dvr_第1张图片

如图所示,租户 T1 的两个不同子网的 vmVM1 和 VM4 在不同机器上,VM1 要访问 VM4,请求过程是计算节点 上的 IR1 起到路由器功能。返程的网包,则在计算节点 上的路由器 IR2 起作用。

两个路由器的 id、内部接口、功能等其实都是一样的。即同一个路由器,但是实际上在多个计算节点上存在。

但是同样的路由器,如果都暴露在外部网络上,会出现冲突。例如当请求包离开计算节点 时,带的源应该是目标子网网关的 mac,但这个 mac 在计算节点 上同样存在。

因此,在 br-int 上进行拦截,修改其源 mac 为 tunnel 端口的 mac。同样的,计算节点 在 br-int 上拦截源mac 为这个 tunnel 端口的 mac,替换为正常的子网网关的 mac,直接扔给目标虚拟机。

2.南北向

(1)无 floating IP

这种情况(即 SNAT)下,跟传统模式很类似。

 openstack 分布式路由器dvr_第2张图片

租户 T2 在外部,通过默认的 SNAT 网关访问内部子网的 vm VM1。此时,网络节点上的 T2-SNAT 起到路由器的作用

 openstack 分布式路由器dvr_第3张图片

反过来,租户 T2 内部子网的 vm VM1 试图访问外部网络,则仍然经过网络节点上的 T2-SNAT 路由器。

为何这种情况下必须从网络节点走?这是因为对于外部网络来说,看到的都是外部接口的地址,这个地址只有一个。

当然,如果以后每个计算节点上都可以带有这样一个 SNAT 默认外部地址的话,这种情况下的流量也是可以直接从计算节点出去的。

(2)有 floating IP

 openstack 分布式路由器dvr_第4张图片

这种情况下,计算节点上的专门负责的外部路由器将负责进行转发,即计算节点 上的 IR2 和计算节点 2上的 IR1

网络节点

服务基本没变动,除了 L3 服务需要配置为 dvr_snat 模式。

命名空间上会多一个专门的 snat-xxx 命名空间,处理来自计算节点的无 floating IP 的南北向流量。

计算节点

需要额外启用 l3_agentdvr 模式),以及 metadata agent

其实,跟传统情况下的网络节点十分类似。每个路由器有自己的命名空间,进行跨子网的转发。

 openstack 分布式路由器dvr_第5张图片

所不同的是,单独有一个 qfloat-XXX 路由器(也在一个独立命名空间中)来负责处理带有 floating IP 的南北向流量。

 openstack 分布式路由器dvr_第6张图片

这里面比较重要的地方,是可能有多个同样的网关存在于多个计算节点上,因为同一个子网的虚机是可能存在在多个计算节点的。

要解决这个问题,也不难,合理处理好本地的 ARP 请求,让本地对网关的请求拦截发给本地的路由器即可。


你可能感兴趣的:(openstack)