openstack分布式路由详解

背景

在 openstack 传统的集中式路由场景下:

Openstack Neutron DVR 分布式路由-neutron 分布式路由

从图中可以明显看到东西向和南北向的流量会集中到网络节点,这会使网络节点成为瓶颈。

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

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

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

DHCP 服务和 VPN 服务仍然需要集中在网络节点上进行。这样的优势:

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

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

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

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

注意:openstack 比较新的官方安装文档把默认的网络组件 openvswitch 改为 Linux bridge 了,原因这里不做深究。有资料显示 dvr只能部署在 ovs 上,这个点需要注意一下。

流量走向

东西向

同一机器

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

不同机器

img

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

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

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

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

南北向

无 floating IP(浮动IP)

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

img

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

img

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

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

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

有 floating IP(浮动IP)

img

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

网络节点

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

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

计算节点

需要额外启用 l3_agent(dvr 模式),以及 metadata agent。

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

img

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

img

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

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

配置样例

基本部署模型由一个控制器节点,两个或多个网络节点和多个计算节点组成。

控制节点配置

1.把以下部分加入/etc/neutron/neutron.conf:

[DEFAULT]
core_plugin = ml2
service_plugins = router
allow_overlapping_ips = True
router_distributed = True
l3_ha = True
l3_ha_net_cidr = 169.254.192.0/18
max_l3_agents_per_router = 3
min_l3_agents_per_router = 2

当配置router_distributed = True标志时,所有用户创建的路由器是分布式的。 没有它,只有特权用户可以使用–distributed True创建分布式路由器。
类似地,当配置l3_ha = True标志时,所有用户创建的路由器默认为HA。
因此,在配置文件中这两个标志设置为True,所有用户创建的路由器将默认为分布式HA路由器(DVR HA)。
同样可以通过具有管理凭据的用户在neutron router-create命令中设置标志来显式实现:

$ neutron router-create name-of-router --distributed=True --ha=True1

max_l3_agents_per_router和min_l3_agents_per_router确定将被实例化的备份DVR / SNAT路由器的数量。

2.把以下部分加入/etc/neutron/plugins/ml2/ml2_conf.ini:

[ml2]
type_drivers = flat,vxlan
tenant_network_types = vxlan
mechanism_drivers = openvswitch,l2population
extension_drivers = port_security

[ml2_type_flat]
flat_networks = external

[ml2_type_vxlan]
vni_ranges = MIN_VXLAN_ID:MAX_VXLAN_ID

将MIN_VXLAN_ID和MAX_VXLAN_ID替换为适用于您的环境的VXLAN ID最小值和最大值。
当常规用户创建网络时,tenant_network_types选项中的第一个值将成为默认项目网络类型。

网络节点配置

1.配置Open vSwitch代理。 将以下内容添加到/etc/neutron/plugins/ml2/ml2_conf.ini中:

[ovs]
local_ip = TUNNEL_INTERFACE_IP_ADDRESS
bridge_mappings = external:br-ex

[agent]
enable_distributed_routing = True
tunnel_types = vxlan
l2_population = True

将TUNNEL_INTERFACE_IP_ADDRESS替换为处理VXLAN项目网络的接口的IP地址。

2.配置L3代理。 将以下内容添加到/etc/neutron/l3_agent.ini中:

[DEFAULT]
ha_vrrp_auth_password = password
interface_driver = openvswitch
external_network_bridge =
agent_mode = dvr_snat

external_network_bridge选项故意不包含值。

计算节点配置

[ovs]
local_ip = TUNNEL_INTERFACE_IP_ADDRESS
bridge_mappings = external:br-ex

[agent]
enable_distributed_routing = True
tunnel_types = vxlan
l2_population = True

[securitygroup]
firewall_driver = neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver

配置L3代理,将以下内容加入/etc/neutron/l3_agent.ini:

[DEFAULT]
interface_driver = openvswitch
external_network_bridge =
agent_mode = dvr

将TUNNEL_INTERFACE_IP_ADDRESS替换为处理VXLAN项目网络的接口的IP地址。

已知限制

目前不支持将路由器从仅分布式,仅HA或传统方式迁移到分布式HA。 路由器必须创建为分布式HA。 也不支持反向。 您不能将分布式HA路由器重新配置为仅分布式,仅HA或传统方式。
在某些情况下,l2pop和分布式HA路由器不以期望的方式交互。 这些影响HA的路由器和l2pop的情况是相同的。

理想化的流量走向

最理想的流量走向是:

  1. 网络节点提供外部流量的访问,不管vm有没有浮动IP
  2. 计算节点外部接口为了安全限制外部访问,只提供不同 vpc 之间的访问

但是好像目前 openstack 分布式路由无法做到

原文地址:https://www.cnblogs.com/leffss/p/15560072.html