L3/BGP - 使 BGP 扬声器对基础设施中断具有弹性

https://bugs.launchpad.net/neutron/+bug/2006145

本 RFE 旨在为 BGP 扬声器建立的 BGP 对等会话实现弹性支持。目前,Neutron 动态路由服务架构依赖于 DRAgent 服务和 Neutron 服务器之间进行某种类型的消息传递。然而,这些通信严重依赖于消息传递服务的可用性(例如 RabbitMQ),OpenStack 基础设施节点中的任何瞬态/永久性故障都可能影响通过 BGP 的前缀通告。

问题描述

当我们在使用动态路由和 BGP 来通告云基础设施中的网络地址前缀时,所有网络流量都依赖于 BGP 对等元素的正确运行。DRAgent 在这种情况下起着至关重要的作用,因为该服务负责在南北通信中通告所有 L3 前缀,是云操作的单一漏洞点。

当前的 DRAgent 参考设计 [1] 使用如下所述的两个独立的周期性任务

状态报告周期性任务 (DrAgentWithStateReport 类)

+------------------------------------------------+
|DrAgentWithStateReport class                    |
|                                                |
|     +------------------------------------+     |
|     |heartbeat = _report_state           |     |
|     |interval=CONF.AGENT.report_interval |     |
|     |  call _report_state                |     |
|     +------------------+-----------------+     |
|                        |                       |
|     +------------------+-----------------+     |
|     |_report_state polling task          |     |
|     |                                    |     |
|     | RPC processing                     |     |
|     |   if agent_status == revived       |     |
|     |     call schedule_full_resync      |     |
|     +------------------+-----------------+     |
|                        |                       |
|     +------------------+-----------------+     |
|     |schedule_full_resync                |     |
|     +------------------------------------+     |
|                                                |
+------------------------------------------------+

BGP DRAgent 周期性任务 (BgpDrAgent 类)

+---------------------------------------+
|BgpDrAgent class                       |
|                                       |
|   +-------------------------------+   |
|   |periodic_resync polling task   |   |
|   |interval=CONF.periodic_interval|   |
|   |  call _periodic_resync_helper |   |
|   +---------------+---------------+   |
|                   |                   |
|   +---------------+---------------+   |
|   |_periodic_resync_helper        |   |
|   | if full_sync or resync/reason |   |
|   |   call sync_state             |   |
|   +---------------+---------------+   |
|                   |                   |
|   +---------------+---------------+   |
|   |sync_state                     |   |
|   |                               |   |
|   | if bgp_speaker_id == None     |   |
|   |   remove speaker from DRAgent |   |
|   |                               |   |
|   | Exception (MessagingTimeout)  |   |
|   |   call schedule_full_resync   |   |
|   +--------------+----------------+   |
|                  |                    |
|   +--------------+----------------+   |
|   |schedule_full_resync           |   |
|   +-------------------------------+   |
|                                       |
+---------------------------------------+

这两个周期性任务具有独立配置的 interval 范围,BGP DRAgent 任务的 periodic_interval,以及心跳报告状态的 AGENT.report_interval。然而,来自这两个周期性任务都可以发起完全同步请求,并且将处理 sync_state 方法。RPC 心跳响应中的 agent_status revived 会激活上述整个流程,直到扬声器从 DRAgent 中移除。对于 sync_state 方法中发生 exception 的情况,将安排一次完全同步(根据上述描述的流程),直到扬声器从 DRAgent 中移除。

无论完全同步请求的来源如何,缓存机制显然不起作用,因为代理之前已经配置好,但在通过 RPC 接收到 revived 状态后,它只是从 DRAgent 中移除扬声器,并重新安排未来的同步,以便稍后重新包含(具体取决于配置的周期性间隔)。当扬声器从 DRAgent 中移除时,BGP 对等会话将被关闭,只有在扬声器重新添加后才会重新建立。

这个问题可以以两种不同的方式表现出来

  • 当消息传递服务/RabbitMQ 离线并且在很长的时间间隔内没有响应 AMQP 服务器不可达(请注意 Neutron agent_down 配置的超时时间);然后 RMQ/RPC 再次变为活动状态。

  • 当消息传递服务/RabbitMQ 队列承受很大的压力和/或遇到 exception 超时,例如:等待回复超时;然后 RMQ/RPC 再次变为活动状态。

提议的变更

为了解决上述问题,建议为 DRAgent 引入新的扬声器缓存逻辑,以便在 RPC 异常和/或通过 RPC 重新建立通信的情况下保留扬声器设置和 BGP 对等会话。此外,为了避免由于 RPC 通信中的瞬态故障而从 DRAgent 中移除 BGP 扬声器配置,需要更改 get_bgp_speakers 空返回处理逻辑,首先安排一次完全同步,然后在下一次周期性同步中允许移除 BGP 扬声器。

为了启用新的 DRAgent 扬声器缓存机制,应通过 bgp_dragent.ini 文件中的 [BGP] 部分启用一个新的配置选项。

* ``speaker_cache_timeout = 300``

此配置选项使 DRAgent 能够在配置的超时时间(以秒为单位)内保留扬声器设置和相关的 BGP 对等会话。此超时缓存的目的是防止 resync 检查逻辑中的错误,从而在满足超时条件之前不会移除任何扬声器。

speaker_cache_timeout 的默认值必须为零,从而保持当前的 DRAgent 行为。任何非零值都应影响 DRAgent 行为,如下所述

  • 状态报告周期性任务:使用 revived RPC 状态,DRAgent 必须启动缓存超时计时器,并将 cache_out_of_sync 标志设置为 True。如果 DRAgent 在 cache_out_of_sync 变为 False 之前执行 sync_state 方法,则必须忽略完全同步过程,并等待下一次周期性检查。

  • DRAgent 周期性任务:如果 sync_state 方法在操作期间抛出任何 exception,DRAgent 必须启动缓存超时计时器,并将 cache_out_of_sync 标志设置为 True。与上述情况类似,如果 DRAgent 在 cache_out_of_sync 变为 False 之前执行 sync_state 方法,则必须忽略完全同步过程,并等待下一次周期性检查。

  • 缓存超时任务:如果在计时器计数期间发生另一个 revivedException 事件,缓存任务必须重置超时间隔计数并重新开始。否则,缓存任务必须在配置的超时到期时终止,并将 cache_out_of_sync 标志设置为 False。

  • 默认工作流程:如果 speaker_cache_timeout 为空或设置为零;或者如果配置的缓存超时计时器已到期 - cache_out_of_sync 标志为 False;任何周期性任务都应运行完全同步。

数据库影响

Rest API 变更

实现

负责人

工作项

  • 在 DRAgent 扬声器同步中实现新的缓存逻辑。

  • 使用 Neutron 动态路由中现有的设施实现相关的单元和功能测试。

  • 编写文档。

文档影响

用户文档

  • 有关 DRAgent 扬声器缓存支持的信息。

测试

  • 单元/功能测试。

参考资料