当前位置: 首页 > article >正文

分布式 L2 网关下的 OVS 未知单播泛洪

大家读完觉得有意义和帮助记得关注和点赞!!!

目录

1 问题描述

2 基础设施和环境信息

3 故障排除

3.1 确认:单播泛洪

3.2 确认:所有泛洪流量都以 L2 GW 为目标

3.3 验证:容器 ARP 处于活动状态时,OVS fdb 条目过时

3.4 分布式 L2 GW 行为:取决于供应商

有关物理交换机 ARP 老化的更多信息

3.5 修复

4 总结

引用


在分布式 L2 网关环境(例如 Spine-Leaf)中,ARP 老化时间配置错误可能会导致 OVS 单播泛洪。而且,的行为 分布式 L2 网关产品因供应商而异。

1 问题描述

一位内部用户报告说,他们注意到了一些实例 (docker containers)定期获得相对较大的怀疑入口流量 - 甚至 如果他们的实例没有提供服务,如下所示:

图 1.1 对实例的周期性入口流量持怀疑态度

2 基础设施和环境信息

本节提供了一些基本的基础设施信息,以帮助理解 问题。更多详细信息,请参考我之前的文章 携程 云计算时代的网络架构演进。

数据中心网络采用 Spine-Leaf 架构,具有 Leaf 节点 用作分布式 L2 和 L3 网关。

图 2.1 数据中心网络拓扑

在每个计算主机内部,所有连接到 OVS 网桥的实例以及 容器内的默认路由指向其自己的(分布式)网关。

图 2.2 主机内部的虚拟网络拓扑

别人:

  • OVS 版本: ,2.3.12.5.6
  • Linux 内核:4.14

3 故障排除

3.1 确认:单播泛洪

调用,并且不费吹灰之力,我们确认了这些流量 不是容器的目标,即这些定期数据包的 和 都不是实例的 IP/MAC。所以我们得到了第一个结论:OVS 正在进行单播泛洪 [1]。tcpdumpdst_ipdst_mac

单播泛洪意味着 OVS 不知道数据包的位置,因此 它复制了此数据包,并将此数据包的副本发送到所有接口 具有相同的 VLAN 标记。例如,在图 2.2 中,的出口流量将 复制到 ,但不是 和 。dst_macinst1inst2inst3inst4

3.2 确认:所有泛洪流量都以 L2 GW 为目标

接下来的问题是,为什么 OVS 不知道 .dst_mac

这些泛洪数据包的日志各不相同,它们来自不同的 IP 地址,并且 也选择了不同的 IP 地址。

但进一步研究捕获的数据包,我们发现所有这些数据包都泛滥了 共享同一dst_mac的数据包,假设 .我们花了 过了一会儿,才弄清楚这是我们的 Spine-Leaf 网络(此 MAC 是手动编码的,由另一个团队负责, 这就是为什么我们一开始没有确定它)。00:11:22:33:44:55

3.3 验证:容器 ARP 处于活动状态时,OVS fdb 条目过时

OVS fdb 是什么样子的:

<span style="color:#333333"><span style="background-color:#f8f8f8"><span style="background-color:#f6f8fa"><code><span style="color:#008080">$ </span>ovs-appctl fdb/show br-int
 port  VLAN  MAC                Age
    1     0  c2:dd:d2:40:7c:15    1
    2     0  04:40:a9:db:6f:df    1
    2     4  00:11:22:33:44:55    16
    2     9  00:11:22:33:44:55    6
</code></span></span></span>

接下来,我们想验证我们的假设:L2 GW 在 OVS fdb 中的条目将是 此问题发生时已过时。

幸运的是,问题每 20 分钟发生一次(结果发现有一些 产生流量的周期性作业),因此我们很容易捕获 我们想要的任何东西。我们使用以下命令来检查该条目是否存在。在 在本例中,实例具有 VLAN 标记 ,因此我们 grep pattern 。4" 4 00:11:22:33:44:55"

<span style="color:#333333"><span style="background-color:#f8f8f8"><span style="background-color:#f6f8fa"><code><span style="color:#000000"><strong>for </strong></span>i <span style="color:#000000"><strong>in</strong></span> <span style="color:#000000"><strong>{</strong></span>1..1800<span style="color:#000000"><strong>}</strong></span>; <span style="color:#000000"><strong>do
    </strong></span><span style="color:#0086b3">echo</span> <span style="color:#dd1144">$(</span><span style="color:#0086b3">date</span><span style="color:#dd1144">)</span> <span style="color:#dd1144">" "</span> <span style="color:#dd1144">$(</span>ovs-appctl fdb/show br-int | <span style="color:#0086b3">grep</span> <span style="color:#dd1144">" 4 00:11:22:33:44:55"</span><span style="color:#dd1144">)</span> <span style="color:#000000"><strong>>></strong></span> fdb.txt;
    <span style="color:#0086b3">sleep </span>1;
<span style="color:#000000"><strong>done</strong></span>
</code></span></span></span>

通常,打印是这样的:

<span style="color:#333333"><span style="background-color:#f8f8f8"><span style="background-color:#f6f8fa"><code>2     4  00:11:22:33:44:55    16
2     4  00:11:22:33:44:55    17
2     4  00:11:22:33:44:55    18
2     4  00:11:22:33:44:55    19
2     4  00:11:22:33:44:55    0
...
</code></span></span></span>

在测试过程中,我们发现打印消失了几分钟,并且这个 period 与有问题的 period 完全匹配。所以第二个结论: fdb 条目确实在容器内的 ARP 条目之前失效(因为 容器使用此 ARP 条目传输这些数据包)。

但仍然存在一个问题:容器的流量不是 在泛洪期间中断,这意味着从网关到 Container 已经成功地被 Container 接收,所以从 Container 的角度来看, 它不受此泛洪行为的影响(但如果泛洪流量 非常大,容器可能会受到影响,因为 这个案例)。

简而言之:gateway 已经回复了它从容器收到的每一个请求,为什么 OVS 没有刷新网关的 fdb 条目?理论上,OVS 会这样做,因为 回复是源自 Gateway 的单播数据包。我们错过了什么吗?

3.4 分布式 L2 GW 行为:取决于供应商

云中,来自网关的单播回复可能是 与在容器中看到的不同?src_macGW_MAC

为了验证,我调用了一个非常简单的流量,从容器 ping GW,打印每个数据包的 和 MAC 地址:srcdst

<span style="color:#333333"><span style="background-color:#f8f8f8"><span style="background-color:#f6f8fa"><code><span style="color:#008080">$ </span>tcpdump <span style="color:#000080">-n</span> <span style="color:#000080">-e</span> <span style="color:#000080">-i</span> eth1 host 10.60.6.1 and icmp
fa:16:3e:96:5e:3e <span style="color:#000000"><strong>></strong></span> 00:11:22:33:44:55, 10.6.6.9 <span style="color:#000000"><strong>></strong></span> 10.60.6.1: ICMP <span style="color:#0086b3">echo </span>request, <span style="color:#0086b3">id </span>7123, <span style="color:#0086b3">seq </span>1, length 64
70:ea:1a:aa:bb:cc <span style="color:#000000"><strong>></strong></span> fa:16:3e:96:5e:3e, 10.6.6.1 <span style="color:#000000"><strong>></strong></span> 10.60.6.9: ICMP <span style="color:#0086b3">echo </span>reply, <span style="color:#0086b3">id </span>7123, <span style="color:#0086b3">seq </span>1, length 64
fa:16:3e:96:5e:3e <span style="color:#000000"><strong>></strong></span> 00:11:22:33:44:55, 10.6.6.9 <span style="color:#000000"><strong>></strong></span> 10.60.6.1: ICMP <span style="color:#0086b3">echo </span>request, <span style="color:#0086b3">id </span>7123, <span style="color:#0086b3">seq </span>2, length 64
70:ea:1a:aa:bb:cc <span style="color:#000000"><strong>></strong></span> fa:16:3e:96:5e:3e, 10.6.6.1 <span style="color:#000000"><strong>></strong></span> 10.60.6.9: ICMP <span style="color:#0086b3">echo </span>reply, <span style="color:#0086b3">id </span>7123, <span style="color:#0086b3">seq </span>2, length 64
</code></span></span></span>

就是这样!为什么应答数据包具有 MAC 地址而不是 ?谁是 ?我们收到通知 这是分布式 L2 GW 的真实 MAC 之一,而后者 是虚拟 MAC。这就是问题所在!GW 使用与 00:11:22:33:44:55 不同的 MAC 进行回复,因此 OVS fdb 永远不会刷新此条目,因此 洪水仍在继续70:ea:1a:aa:bb:cc00:11:22:33:44:5570:ea:1a:aa:bb:cc

这是 Cisco 设备的行为,我们进一步检查了我们的 H3C 设备, 令人惊讶的是,在相同条件下,H3C 的回复是一致的: 它始终用于发送和接收。 到目前为止,我还没有关于什么是分布式 L2(和 L3)的明确答案 应该表现得好。00:11:22:33:44:55

有关物理交换机 ARP 老化的更多信息

Cisco 交换机为每个 IP 维护一个 ARP 计时器,默认为 ( 分钟) [4]。1500s25

<span style="color:#333333"><span style="background-color:#f8f8f8"><span style="background-color:#f6f8fa"><code>LEAF <span style="color:#999988"><em># show ip arp vrf test | in 2001</em></span>
10.6.2.227 00:01:12 fa16.xxxx.97c7 Vlan2001
10.6.2.228 00:01:15 fa16.xxxx.97c8 Vlan2001
10.6.2.229 00:01:33 fa16.xxxx.97c9 Vlan2001
</code></span></span></span>

如果几分钟内没有来自此 ARP 的帧,它将向此 IP(主机)发送免费 ARP。19

<span style="color:#333333"><span style="background-color:#f8f8f8"><span style="background-color:#f6f8fa"><code>Host <span style="color:#008080">$ </span>tcpdump <span style="color:#000080">-en</span> <span style="color:#000080">-i</span> eth0 ether src 00:11:22:33:44:55
15:26:31.650401 00:11:22:33:44:55 <span style="color:#000000"><strong>></strong></span> fa:16:xx:67, vlan 2001, ARP, Request who-has 10.6.2.241 <span style="color:#000000"><strong>(</strong></span>fa:16:xx:67<span style="color:#000000"><strong>)</strong></span> tell 10.6.2.1
15:27:06.023959 00:11:22:33:44:55 <span style="color:#000000"><strong>></strong></span> fa:16:xx:c5, vlan 2001, ARP, Request who-has 10.6.2.73  <span style="color:#000000"><strong>(</strong></span>fa:16:xx:c5<span style="color:#000000"><strong>)</strong></span> tell 10.6.2.1
15:27:07.594005 00:11:22:33:44:55 <span style="color:#000000"><strong>></strong></span> fa:16:xx:aa, vlan 2001, ARP, Request who-has 10.6.2.7   <span style="color:#000000"><strong>(</strong></span>fa:16:xx:aa<span style="color:#000000"><strong>)</strong></span> tell 10.6.2.1
</code></span></span></span>

3.5 修复

这个问题是由分布式 L2 GW 行为引发的,但实际上它是一个 host 内部的配置错误:我们应该始终确保 intermediate 转发设备(在本例中为 OVS 网桥)的老化时间比 实例本身和物理交换机 ARP 老化时间

Linux 内核的 ARP 老化机制真的很复杂,而不是一个或 多个参数,它由参数和状态的组合控制 机器,请参考这篇文章 [3] 如果你是 感兴趣。将 OVS fdb aging 设置为 对我们来说足够安全:1800s

<span style="color:#333333"><span style="background-color:#f8f8f8"><span style="background-color:#f6f8fa"><code><span style="color:#008080">$ </span>ovs-vsctl <span style="color:#0086b3">set </span>bridge br-int  other_config:mac-aging-time<span style="color:#000000"><strong>=</strong></span>1800
<span style="color:#008080">$ </span>ovs-vsctl <span style="color:#0086b3">set </span>bridge br-bond other_config:mac-aging-time<span style="color:#000000"><strong>=</strong></span>1800
</code></span></span></span>

(上述配置在 OVS 和系统重启后仍然存在。

配置完成后,问题消失了:

图 3.1 问题消失

4 总结

内核通常有一个 ARP 老化时间比 OVS fdb 长(默认为 300 秒),因此在某些情况下,当 网关的 MAC 条目在 ARP 表中仍然有效,它在 OVS fdb 中已过时。 因此,网关的下一个出口数据包 (with ) 将触发 OVS 单播泛洪。dst_mac=GW_MAC

当从网关收到正确响应的数据包时,OVS fdb 将刷新 网关的 MAC 条目,则后续的单播泛洪将停止(转换为 正常的 L2 转发,因为 OVS 知道 其中 is)。GW_MAC

确切地说,真正的灾难是 gateway 响应错误:

  1. 网关是一个分布式 L2 网关,具有一个虚拟 MAC 和许多实例 MAC(与负载均衡器中的 VIP 和实例 IP 的概念相同)
  2. 从容器到网关的出口流量使用网关的虚拟 MAC
  3. 从网关到容器的响应流量使用其真实 MAC 之一 (实例 MAC)

在这种情况下,OVS fdb 不会被刷新,因此 OVS 将每 egress 数据包,直到 网关主动将其虚拟 MAC 通告给容器或容器 向网关发起主动 ARP 请求 - 此泛洪期可能会持续 几分钟,并且同一 VLAN 中的所有流量(如果 VLAN 未使用)将累积/复制到连接到 OVS 的每个实例。

如果您将 QoS 设置为 容器正在使用的 OVS 接口。

引用

  1. Cisco Doc:单播泛洪
  2. 云计算时代的携程网络架构演进
  3. Linux 实现的 ARP 老化时间原理分析
  4. Cisco Doc:ip arp 超时设置

http://www.kler.cn/a/464072.html

相关文章:

  • AWS 申请证书、配置load balancer、配置域名
  • 开发培训-慧集通(iPaaS)集成平台脚本开发Groovy基础培训视频
  • Python爬虫 - 豆瓣图书数据爬取、处理与存储
  • 解决uniapp H5页面限制输入框只能输数字问题
  • 安卓11 SysteUI添加按钮以及下拉状态栏的色温调节按钮
  • MySQL 05 章——排序与分页
  • 【设计模式】 基本原则、设计模式分类
  • 【安卓开发】【Android Studio】项目构建失败提示【Could not read metadata.bin】解决方法
  • 2025年,测试技能支棱起来。
  • 每天40分玩转Django:Django安全专题
  • 【GIT(命令)基础操作笔记--关于本地仓库】
  • Kafka系列教程 - Kafka 消费者 -3
  • 数据挖掘——朴素贝叶斯分类
  • 滑动窗口——将x减到0的最小的操作数
  • 长时间序列预测算法---Informer
  • Cocos游戏中集成RichTap高品质振动
  • SpringCloud微服务架构
  • selenium 确保页面完全加载
  • react 优化方案
  • vue设计与实现-权衡的艺术
  • 打造三甲医院人工智能矩阵新引擎(一):文本大模型篇--基于GPT-4o的探索
  • SpringBoot开发——常用的几种参数传递和参数接收方式
  • js 中的递归应用+异步递归
  • Ungoogled Chromium127编译指南 Linux篇 - 拉取仓库(七)
  • IP-Guard对SolidWorks PDM 加密授权说明
  • Linux 系统中 .d 目录有什么用?