Qrator过滤网络配置管理系统

Qrator过滤网络配置管理系统

TL博士:我们内部网络配置管理系统 QControl 的客户端-服务器架构的描述。 它基于两层传输协议,可处理 gzip 打包的消息,无需在端点之间解压缩。 分布式路由器和端点接收配置更新,并且协议本身允许安装本地化中间中继。 该系统的构建原理 差异备份 (“最近稳定”,如下所述)并使用 JMESpath 查询语言和 Jinja 模板引擎来呈现配置文件。

Qrator Labs 运营着一个全球分布式攻击缓解网络。 我们的网络按照选播原则运行,子网通过 BGP 进行通告。 作为物理上位于地球多个区域的 BGP 选播网络,我们可以处理和过滤更靠近互联网核心(一级运营商)的非法流量。

另一方面,成为一个地理上分散的网络并不容易。 网络存在点之间的通信对于安全服务提供商拥有所有网络节点的一致配置并及时更新它们至关重要。 因此,为了向消费者提供尽可能高水平的核心服务,我们需要找到一种跨大陆可靠地同步配置数据的方法。

太初有道。 它很快成为需要更新的通信协议。


QControl 存在的基石,同时也是花费大量时间和资源来构建此类协议的主要原因,是需要获得单一权威配置源并最终同步我们的存在点用它。 存储本身只是 QControl 开发过程中的几个要求之一。 此外,我们还需要与存在点 (POP) 上的现有和计划服务、数据验证的智能(且可定制)方法以及访问控制进行集成。 除此之外,我们还希望使用命令来控制这样的系统,而不是修改文件。 在 QControl 出现之前,数据几乎是手动发送到存在点的。 如果其中一个存在点不可用并且我们稍后忘记更新它,则配置最终会不同步,我们将不得不浪费时间将其恢复并运行。

于是,我们提出了如下方案:
Qrator过滤网络配置管理系统
配置服务器负责数据验证和存储;路由器有多个端点,用于接收配置更新并将其从客户端和支持团队广播到服务器,以及从服务器广播到存在点。

世界各地的互联网连接质量仍然存在很大差异 - 为了说明这一点,让我们看一下从捷克共和国布拉格到新加坡和香港的简单地铁。

Qrator过滤网络配置管理系统
从布拉格到新加坡的地铁

Qrator过滤网络配置管理系统
香港也一样

高延迟意味着较低的速度。 另外,还有丢包的情况。 通道宽度并不能弥补这个问题,在构建去中心化系统时必须始终考虑到这一点。

存在点的完整配置包含大量数据,必须通过不可靠的连接发送给许多收件人。 幸运的是,虽然配置不断变化,但变化的增量很小。

最近稳定的设计

可以说,基于增量更新原理构建分布式网络是一个相当明显的解决方案。 但差异存在很多问题。 我们需要保存参考点之间的所有差异,并且还能够重新发送它们,以防有人丢失部分数据。 每个目的地必须按照严格指定的顺序应用它们。 通常,在多个目的地的情况下,这样的操作可能需要很长时间。 接收器还必须能够请求丢失的部分,当然,中央部分必须正确响应此类请求,仅发送丢失的数据。

结果,我们得出了一个相当有趣的解决方案 - 我们只有一个参考层,固定的,我们称其为稳定的,并且只有一个差异 - 最近的。 每个最近的数据都基于最后生成的稳定数据,足以重建配置数据。 一旦新的最近的到达目的地,旧的就不再需要了。

剩下的就是不时发送新的稳定配置,例如因为最近的配置变得太大。 这里同样重要的是,我们以广播/多播模式发送所有这些更新,而不用担心单个接收者及其拼凑数据片段的能力。 一旦我们确定每个人都有正确的马厩,我们只会发送最近的新马厩。 是否值得澄清这是否有效? 作品。 稳定版本缓存在配置服务器和收件人上,最新版本根据需要创建。

二级传输架构

为什么我们要在两个层面上建设我们的交通? 答案非常简单 - 我们希望将路由与高级逻辑分离,从 OSI 模型及其传输层和应用程序层中汲取灵感。 我们使用 Thrift 来充当传输协议的角色,并使用 msgpack 序列化格式来充当控制消息的高级格式。 这就是为什么路由器(执行多播/广播/中继)不会查看 msgpack 内部,不会解包或打包内容,而仅转发数据。

Thrift(来自英语 - “thrift”,发音为 [θrift])是一种接口描述语言,用于为不同的编程语言定义和创建服务。 它是远程过程调用(RPC)的框架。 将软件管道与代码生成引擎相结合,以开发在语言之间或多或少高效且轻松地工作的服务。

我们选择Thrift框架是因为RPC并且支持多种语言。 和往常一样,简单的部分是客户端和服务器。 然而,路由器却是一个棘手的难题,部分原因是我们在开发过程中缺乏现成的解决方案。

Qrator过滤网络配置管理系统还有其他选择,例如 protobuf / gRPC,但是,当我们开始项目时,gRPC 还很新,我们不敢接受。

当然,我们可以(事实上应该)建造我们自己的自行车。 根据我们的需要创建一个协议会更容易,因为与在 Thrift 上构建路由器相比,客户端-服务器架构的实现相对简单。 无论如何,人们对自行编写的协议和流行库的实现存在一种传统的偏见(有充分的理由);此外,在讨论过程中总是会出现这样的问题:“我们如何将其移植到其他语言?” 于是我们立刻就扔掉了自行车的想法。

Msgpack 与 JSON 类似,但更快、更小。 它是一种二进制数据序列化格式,允许在多种语言之间交换数据。

在第一级,我们使用 Thrift 提供路由器转发消息所需的最少信息。 第二层是打包的 msgpack 结构。

我们选择 msgpack 是因为它比 JSON 更快、更紧凑。 但更重要的是,它支持自定义数据类型,使我们能够使用很酷的功能,例如传递原始二进制文件或指示缺少数据的特殊对象,这对于我们的“最近稳定”方案很重要。

JMES路径
JMESPath 是一种 JSON 查询语言。
这正是我们从 JMESPath 官方文档中得到的描述,但事实上,它的作用远不止于此。 JMESPath 允许您搜索和过滤任意树结构中的子树,并动态应用对数据的更改。 它还允许您添加特殊的过滤器和数据转换程序。 当然,尽管它需要大脑的努力才能理解。

神社
对于某些消费者,我们需要将配置转换为文件 - 因此我们使用模板引擎,而 Jinja 是显而易见的选择。 在它的帮助下,我们根据模板和在目的地接收的数据生成配置文件。

要生成配置文件,我们需要一个 JMESPath 请求、FS 中文件位置的模板以及配置本身的模板。 在这个阶段澄清文件权限也是一个好主意。 所有这些都成功地合并在一个文件中 - 在配置模板开始之前,我们放置了一个 YAML 格式的标头来描述其余部分。

例如:

---
selector: "[@][[email protected]._meta.version == `42`] | items([0].fft_config || `{}`)"
destination_filename: "fft/{{ match[0] }}.json"
file_mode: 0644
reload_daemons: [fft] ...
{{ dict(match[1]) | json(indent=2, sort_keys=True) }}

为了为新服务制作配置文件,我们只需添加新的模板文件。 无需更改存在点上的源代码或软件。

自 QControl 上线以来发生了哪些变化? 第一件也是最重要的事情是将配置更新一致且可靠地传送到网络中的所有节点。 第二个是获得一个强大的工具,用于由我们的支持团队以及服务的消费者检查配置并对其进行更改。

我们能够使用最近稳定的更新方案来完成所有这一切,以简化配置服务器和配置接收者之间的通信。 使用两层协议支持内容无关的数据路由方式。 成功地将基于 Jinja 的配置生成引擎集成到分布式过滤网络中。 该系统支持我们的分布式和异构外设的多种配置方法。

感谢您在撰写材料时提供的帮助。 沃兰·丹罗德, 宁静, .

英文版 帖子。

来源: habr.com

添加评论