Neutron/DVR L2 Agent
目录
作者
Vivekanandan Narasimhan 惠普公司
Swaminathan Vasudevan 惠普公司
目的
注意:此蓝图是分布式虚拟路由器的组成部分。可以通过以下链接访问 DVR 的父蓝图。
本文档描述了为在 L2 层启用分布式虚拟路由器功能,OpenStack Neutron 中 L2 插件和 L2 Agent 中提出的更改。
DVR 中 L2 的设计目标
在 OVS 中设计一组规则以在 L2 层启用分布式虚拟路由功能时,有了一系列目标。
1. 这些规则应允许在不同网络上的租户 VM 之间进行通信,通过托管在计算节点中的分布式路由器。
2. 任何给定的分布式路由器实例可能驻留在所有计算节点上,并负责路由由在同一节点上共同驻留的 VM 生成的数据包。
3. 给定的分布式路由器实例要么托管在计算节点中作为 DVR(或)作为网络节点上的正常路由器,但绝不会同时在两个节点中。
4. 这些规则应是这样,以便可以使用 OpenStack Neutron 中现有的 OpenVswitch 基础设施来实现分布式路由。
5. 应使用更少的 MAC 地址每个计算节点,并继续保持路由数据包的 L2 隔离。
6. 应确保启用南北路由,这表示 VM 可以直接访问外部网络。
7. 应拥抱 FWaaS 服务,即使在 DVR 接口上启用了分布式路由,也能保持运行。
8. 云中任何元素(桥接)的 MAC 超时和 ARP 超时,不应影响 DVR 的运行。
9. 这些规则必须确保即使在云中启用重叠 IP 地址时,多租户隔离仍然存在。
10. 这些规则必须确保即使在云中启用重叠 MAC 地址时,多租户隔离仍然存在(通过重叠 MAC 地址,这里的意思是不同网络上的 MAC 地址可能相同)。
分布式路由的工作原理
为了实现分布式路由,L3 和 L2 Agent 的工作都需要在计算节点内协同工作。 今天,L3 Agent 在网络节点中运行,但有了这个 DVR 提案,L3 Agent 也将在计算节点中运行。 计算节点上的 L2 Agent 将继续像今天一样运行,但将以一种称为“DVR 模式”的增强模式工作,在这种模式下,L2 Agent 将额外负责管理(添加/删除)OVS 规则,以实现分布式路由。
以下是用于说明如何实现分布式路由的示例拓扑。
图示数据包内容的术语
red1-L-vlan 表示计算节点 CN1 上红色网络的本地 VLAN。
grn1-L-vlan 表示计算节点 CN1 上绿色网络的本地 VLAN。
red2-L-vlan 表示计算节点 CN2 上红色网络的本地 VLAN。
grn2-L-vlan 表示计算节点 CN2 上绿色网络的本地 VLAN。
red-vni 表示用于隧道帧的 VXLAN ID,用于由 red-L-vlan 本地 VLAN 表示的租户网络。
grn-vni 表示用于隧道帧的 VXLAN ID,用于由 grn-L-vlan 本地 VLAN 表示的租户网络。
r1-red-ip 表示 DVR 路由器 (r1) 的红色子网接口的 IP 地址。DVR 路由器 (r1) 在 CN1 和 CN2 中实例化的红色子网接口的 IP 地址将保持相同。
r1-grn-ip 表示 DVR 路由器 (r1) 的绿色子网接口的 IP 地址。DVR 路由器 (r1) 在 CN1 和 CN2 中实例化的绿色子网接口的 IP 地址将保持相同。
r1-red-mac 表示 DVR 路由器 (r1) 的红色子网接口的 MAC 地址。DVR 路由器 (r1) 在 CN1 和 CN2 中实例化的红色子网接口的 MAC 地址将保持相同。
r1-grn-mac 表示 DVR 路由器 (r1) 的绿色子网接口的 MAC 地址。DVR 路由器 (r1) 在 CN1 和 CN2 中实例化的绿色子网接口的 MAC 地址将保持相同。
dvr-cn1-mac 表示由控制器分配给计算节点 CN1 的 DVR 基 MAC 池中的 MAC 地址。此 mac 地址将作为由 CN1 中存在的 DVR 子网接口生成的所有帧的源 mac 地址。
dvr-cn2-mac 表示由控制器分配给计算节点 CN2 的 DVR 基 MAC 池中的 MAC 地址。此 mac 地址将作为由 CN2 中存在的 DVR 子网接口生成的所有帧的源 mac 地址。
在上面的图中,从红色网络上的 vm1 发起对连接到标识为 r1 的 DVR 路由器的绿色网络上的 vm2 的 PING ECHO 请求。 DVR 路由器 r1 在 CN1 和 CN2 上的两个节点上将具有相同的 IP 地址和 MAC 地址。 如我们所见,DVR 路由器 r1 有两个接口:一个接口是红色网络中的子网,另一个接口是绿色网络中的子网。
从 vm1 到 vm2 的 PING ECHO 请求的数据包流在上面的图中以编号为“1”到“6”的数据包所示。
1 vm1 发送的目标 ip 为“vm2 ip”的帧到红色网络的默认网关 mac,即 r1-red-mac。 集成桥接将此帧转发到 DVR 路由器 r1。
2 DVR 路由器 r1 的红色子网接口拾取此帧,然后路由帧中的 IP 数据包。
3 路由后,DVR 路由器 r1 将路由的帧从其绿色子网接口发出。 此帧由集成桥接切换到隧道桥接,并使用绿色网络的本地 VLAN 标签标记该帧。
4 CN1 上的隧道桥接,将帧的源 mac 地址替换为其节点(每个计算节点由控制器分配一个唯一的 DVR mac 地址)的唯一 DVR MAC 地址。 通过此隧道桥接将结果帧转发到 CN2。 在转发之前,它还会剥离本地绿色 VLAN 标签并使用绿色-vni VXLAN ID 隧道化该帧。
5 CN2 上的隧道桥接,拾取隧道帧,对其进行解隧道化并剥离绿色-vni 标签。 然后,它将本地绿色网络 VLAN 标签添加到该帧并将其转发到集成桥接。
6 CN2 上的集成桥接,识别传入帧的源 mac 地址是云中的所有 l2-agent 都知道的唯一 DVR MAC 地址。 然后,它将唯一 DVR MAC 地址替换为本地 dvr 实例子网接口 mac 地址,然后将帧转发到本地目标 VM。
从 vm2 到 vm1 的 PING 响应,上述序列以相反的顺序发生。
如您所注意,帧由帧源节点中的 DVR 路由器路由,然后它们只是发送到正确的目的地。 对于所有路由的帧,帧源节点的唯一 DVR MAC 地址在底层用作帧的源 MAC 地址(即,在内部帧中)。
CN1 上 DVR 路由器 r1 的 vm2 的 ARP 条目将由运行在 CN1 上的 L3-Agent(通过 L3 插件提供的信息)预填充。 同样,DVR 路由器 r1 在 CN2 上实例化的 vm1 的 ARP 条目将由运行在 CN2 上的 L3-Agent(通过 L3 插件提供的信息)预填充。
在计算节点 CN1 上
集成桥接规则
隧道桥接规则
在计算节点 CN2 上
集成桥接规则
隧道桥接规则
所有以棕色显示的表和规则都是 L2 Agent 在 DVR 模式下运行时将额外管理的规则。
对规则的简要描述如下
a. 由租户 VM 生成的 ARP 广播请求广播到云中的每个其他 CN。 但是,如果 ARP 请求帧的目标是默认网关 IP(路由器子网 ip),则此类帧将由本地隧道桥接丢弃,以防止转发到云中。 因为,此类 ARP 需要并且将仅由本地可用的 DVR 实例提供服务。
隧道桥接
DVR PROCESS 表 1(DVR 的新表):table=1, priority=4, dl_vlan= red1-L-vlan, dl_type=arp, ar_tpa= r1-red-ip actions: drop table=1, priority=4, dl_vlan= grn1-L-vlan, dl_type=arp, ar_tpa= r1-grn-ip actions: drop
b. 由分布式路由器接口端口生成的所有请求,无论是 ARP 请求、其他广播(或)单播数据包,都将发送到云中。 但是,所有此类帧都被视为“dvr 路由帧”,因此,在原始节点上转发到云之前,此类帧将在帧的源 mac 中携带“本地唯一 dvr macaddress”。
通过 DVR PROCESS 表中的以下规则进行本地路由器接口 mac 地址到“本地唯一 dvr macaddress”的转换。
隧道桥接
DVR PROCESS 表 1(DVR 的新表):table=1, priority=1, dl_vlan=red2_L_vlan, dl_src=r1-red-mac, actions: mod_dl_src=dvr-cn1-mac, resubmit(,2) table=1, priority=1, dl_vlan=grn2_L_vlan, dl_src=r1-grn-mac, actions: mod_dl_src=dvr-cn1-mac, resubmit (,2)
c. 补充上述 b 点,在接收到的计算节点上的集成桥接将从帧的源 MAC 字段中剥离唯一的 DVR MAC 地址。 在相同的位置,集成桥接将在转发到本地目标 VM 之前替换为本地 dvr 实例子网接口 mac 地址。 这是通过集成桥接上的新表 1 完成的。 例如在 CN2 上
集成桥接规则
表 0:(本地交换表)table=0, priority=2, in_port=patch-tun, dl_src=dvr-cn1-mac actions: goto table 1 table=0, priority=1, actions: output->NORMAL 表 1:(DVR_TO_LOCALMAC 表)
table=1, priority=2, dl_vlan=grn2-L-vlan, nw_dst=grn-subnet actions: strip_vlan, mod_dl_src=r1-grn-MAC,output->port-vm2 table=1, priority=1 actions: drop
d. 为了防止将目的地为本地 dvr 子网接口 mac 地址的数据包转发到云中,这将导致其他计算节点在解码数据包时产生 mac 歧义,因此通过以下规则丢弃隧道桥接中的数据包
隧道桥接
DVR PROCESS 表 1(DVR 的新表):table=1, priority=2, dl_vlan=red2_L_vlan, dl_dst=r1-red-mac, actions: drop table=1, priority=2 , dl_vlan=grn2_L_vlan, dl_dst=r1-grn-mac, actions: drop
e. 为了防止将路由到远程 VM 的所有单播数据包发送到云中的所有计算节点,使用了 l2 预填充技术来预填充计算节点中的 FDB 表,以便仅将帧输出到正确的单个目标计算节点。
f. 对于集成桥接中的这些规则,其中“output port”操作中可能会出现很长的端口列表,本文档建议使用 OpenVswitch (OVS) 版本 2.1 中提供的“Group Tables”功能。
集成桥接
表 1:(DVR_TO_LOCALMAC 表)table=1, priority=2, dl_vlan=grn2-L-vlan, nw_dst=grn-subnet actions: strip_vlan, mod_dl_src=r1-grn-MAC,output->port-vm2
DVR 中 L2 的数据模型扩展
DistributedVirtualRouterMacAddress 表保存在控制器中,该表用于存储/检索分配给由“host”标识的主机上运行的 L2 Agent 的唯一 DVR MAC 地址。
L2 Agent 特定的配置
enable_distributed_routing
OVS L2 Agent 使用的 ovs_neutron_plugin.ini 文件将具有一个额外的配置标志
enable_distributed_routing=False
为了在 DVR 模式下运行 OVS L2 Agent,必须将上述标志设置为 True 并重新启动 OVS L2 Agent。此标志的默认值为 False。例如,在网络节点上,L2 Agent 将不会在 DVR 模式下运行。也就是说,在 NN 上,云管理员需要保持此标志不变。
L2 Agent 将像今天一样正常运行。但是,当 L2 Agent 在其 init() 中读取 enable_distributed_routing=True 时,它将额外以 DVR 模式运行。什么是 DVR 模式?DVR 模式只是指 L2 Agent 的增强行为,它将智能地处理在集成桥上检测到的分布式路由器接口端口。作为处理分布式路由器接口端口(存在/不存在)的一部分,它将使用本文档中记录的 OVS 规则。
dvr_base_mac
需要在 neutron.conf 中提供另一个标志,该标志代表 ML2 插件用于 DVR 唯一 MAC 分配的基础 MAC 地址。配置如下所示:
- DVR 基础 MAC 地址。前 3 个字节将保持不变。如果
- 第 4 个字节不是 00,它也将被使用。其余字节将随机生成。
- 3 字节
- dvr_base_mac = fa:16:3f:00:00:00
- 4 字节
- dvr_base_mac = fa:16:3f:4f:00:00
上述 dvr_base_mac 必须与用于虚拟端口分配的基础 MAC 地址不同。这是为了确保虚拟端口 MAC 地址与 DVR 唯一 MAC 地址隔离。
RPC 变更
本节描述了将在 OpenStack 的 L2 区域引入的新 RPC 调用,以启用 DVR 功能。
将引入以下新的 RPC:
get_dvr_mac_address_by_host (hostname)
get_dvr_mac_address()
dvr_mac_address_update()
get_compute_ports_on_host_by_subnet()
get_compute_ports_by_subnet()
get_device_details (device, agent_id)
L2 与插件和 L3 Agent 的交互
L2 OVS Agent 初始化
在初始化期间,L2 OVS Agent 需要知道其托管的唯一 dvr mac 地址,以便将适当的 OVS 规则键入隧道和集成桥。为此,L2 agent 调用由 ML2 插件提供的 RPC get_dvr_mac_address(host_id)。
分布式路由器创建
可以显式创建一个分布式路由器。通常,由于路由器创建(无论是分布式模式还是其他模式),代理不需要采取任何操作。只有在向路由器添加接口时,L2 和 L3 代理才会采取行动。在插件侧,如常,创建的路由器信息存储在 DB 中,如图所示。
向分布式路由器添加接口
在分布式路由器上执行 router-interface-add 命令会导致 routers_updated() RPC 被调用到 CN 上的 L3-Agent-on-CN。作为服务此请求的一部分,L3-Agent-on-CN 首先验证受影响的路由器是否为分布式路由器。如果是,它会获取与新添加的接口对应的接口端口,并将该端口附加到集成桥上。此操作与 L3 Agent 类似,不同之处在于 L3-Agent-on-CN 在计算节点上运行,仅在这些端口面向分布式路由器时才添加路由器端口。
分布式路由器的接口端口将具有一个特殊的 device_owner 字段值,即 network:router_interface_distributed。
在 br-int 上添加路由器接口端口后,L3-Agent-on-CN 请求有关云上在此子网接口上可用端口的信息。为此,它调用 get_compute_ports_by_subnet (subnet_id) 到 L3 插件。然后,L3 插件联系 ML2 插件以获取输入子网上所有可用的端口,并将端口列表返回给 L3-Agent-on-CN。L3-Agent-on-CN 缓存这些端口,然后使用端口信息在 DVR 路由器命名空间中创建静态 ARP 条目。这完成了路由器接口的 DVR 端处理。
L3-Agent-on-CN 添加的路由器接口端口被 L2 Agent 检测到。L2 Agent 识别此端口是否为分布式路由器接口。如果不是,则执行正常处理。如果是,则执行特殊处理,其中调用 get_compute_ports_on_host_by_subnet(subnet_id) 以获取此路由器接口上可用的本地 VM 列表。然后,它使用此端口列表和路由器接口端口信息在隧道和集成桥中创建 OVS 规则。
从分布式路由器中删除接口
在分布式路由器上执行 router-interface-delete 命令会导致 routers_updated() RPC 被调用到 CN 上的 L3-Agent-on-CN。作为服务此请求的一部分,L3-Agent-on-CN 首先验证受影响的路由器是否为分布式路由器。如果是,它会获取与正在删除的接口对应的接口端口。它从集成桥上删除该路由器接口端口。此操作与 L3 Agent 类似,不同之处在于 L3-Agent-on-CN 在计算节点上运行,仅在这些端口属于分布式路由器时才删除路由器端口。在 br-int 上删除路由器接口端口后,L3-Agent-on-CN 访问端口缓存以确定已删除路由器接口上可用的端口列表。然后,它从路由器命名空间中删除所有这些端口的静态 ARP 条目。这完成了路由器接口删除的 DVR 端处理。
L3-Agent-on-CN 删除的路由器接口端口被 L2 Agent 检测到。L2 Agent 识别此端口是否为分布式路由器接口。如果不是,则执行正常处理。如果是,则执行特殊处理,其中从集成和隧道桥中删除所有与删除的路由器接口端口匹配的 OVS 规则。
将新的 VM 添加到分布式路由器的子网接口
当新的租户 VM 添加到由分布式路由器管理的子网接口时,Nova 会执行 CreatePort API 调用以托管新的租户 VM。作为 ML2 插件通过 createPort 服务的一部分,ML2 插件将通知 L3 插件有关可用新端口的信息。L3 插件将检查此新端口是否位于 DVR 托管的子网中。如果不是,它将不执行任何处理。如果是,L3 插件将启动 RPC 调用 port_add() 到 L3-Agent-on-CN。L3-Agent-on-CN 将服务此 RPC,其中它将获取此端口信息并在相应的路由器命名空间中添加该端口的静态 ARP 条目。这完成了新的租户 VM 端口添加的 DVR 端处理。
L2 Agent 检测到新的租户 VM 端口。L2 Agent 识别此端口是否为已是分布式路由器接口的子网的成员。如果不是,则执行正常处理。如果是,则执行特殊处理,其中将此端口(OFPORT)添加到 br-int 和 br-tun 中与匹配子网网关的现有 OVS 规则中。
从分布式路由器的子网接口删除现有的 VM
当租户 VM 从由分布式路由器管理的子网接口中删除时,Nova 会为删除的租户 VM 执行 DeletePort API 调用。作为 ML2 插件通过 deletePort 服务的一部分,ML2 插件将通知 L3 插件有关正在删除的端口的信息。L3 插件将检查此删除的端口是否位于 DVR 托管的子网中。如果不是,它将不执行任何处理。如果是,L3 插件将启动 RPC 调用 port_delete() 到 L3-Agent-on-CN。L3-Agent-on-CN 将服务此 RPC,其中它将获取此端口信息并在相应的路由器命名空间中删除该端口的匹配静态 ARP 条目。这完成了租户 VM 端口删除的 DVR 端处理。
L2 Agent 检测到删除的端口。L2 Agent 识别此端口是否为已是分布式路由器接口的子网的成员。如果不是,则执行正常处理。如果是,则执行特殊处理,其中修改 br-int 和 br-tun 中的现有 OVS 规则,以便该规则不包含正在删除的端口(OFPORT)。
















