Aeraki — 在 Istio 服务网格中管理任何 7 层协议

Aeraki 提供了一个框架,允许 Istio 支持除 HTTP 之外的更多 7 层协议。

2021 年 9 月 28 日 | 作者:腾讯赵华冰

Aeraki [Air-rah-ki] 是希腊语中“微风”的意思。Istio 在服务网格中连接微服务,而 Aeraki 提供了一个框架,允许 Istio 支持除 HTTP 和 gRPC 之外的更多 7 层协议。我们希望这阵微风能帮助 Istio 航行得更远。

服务网格中缺少协议支持

我们现在在服务网格方面面临一些挑战

这些障碍使得用户很难(如果不是不可能的话)在微服务中管理其他广泛使用的 7 层协议的流量。例如,在一个微服务应用程序中,我们可能拥有以下协议

Common Layer-7 Protocols Used in Microservices
微服务中常用的 7 层协议

如果您已经投入大量精力迁移到服务网格,当然,您希望充分利用它——管理微服务中所有协议的流量。

Aeraki 的方法

为了解决这些问题,我们创建了一个开源项目,Aeraki Mesh,以提供一种非侵入性、可扩展的方式来管理 Istio 服务网格中的任何 7 层流量。

Aeraki Architecture
Aeraki 架构

如图所示,Aeraki 框架由以下组件组成

DubboThrift 已经基于 MetaProtocol 实现。更多协议正在开发中。如果您使用的是闭源的专有协议,您也可以通过为其编写 MetaProtocol 编解码器来在您的服务网格中管理它。

大多数请求/响应样式的无状态协议可以构建在 MetaProtocol 代理之上。但是,某些协议的路由策略过于“特殊”,无法在 MetaProtocol 中标准化。例如,Redis 代理使用槽位号将客户端查询映射到特定的 Redis 服务器节点,并且槽位号由请求中的键计算得出。只要 Envoy 代理端有可用的 Envoy 过滤器,Aeraki 仍然可以管理这些协议。目前,对于此类协议,Redis 和 Kafka 在 Aeraki 中受支持。

深入 MetaProtocol

让我们看看 MetaProtocol 如何工作。在引入 MetaProtocol 之前,如果我们想代理特定协议的流量,我们需要编写一个理解该协议的 Envoy 过滤器,并添加代码来操作流量,包括路由、标头修改、故障注入、流量镜像等。

对于大多数请求/响应样式的协议,流量操作的代码非常相似。因此,为了避免在不同的 Envoy 过滤器中重复这些功能,Aeraki 框架在一个地方实现了 7 层协议代理的大多数常用功能——MetaProtocol 代理过滤器。

MetaProtocol Proxy
MetaProtocol 代理

这种方法大大降低了编写新 Envoy 过滤器的门槛:现在您只需要实现编解码器接口,而不是编写一个功能齐全的过滤器。除此之外,控制平面已经就绪——Aeraki 在控制平面上工作,为所有构建在 MetaProtocol 之上的协议提供 MetaProtocol 配置和动态路由。

Writing an Envoy Filter Before and After MetProtocol
在 MetProtocol 之前和之后编写 Envoy 过滤器

MetaProtocol 代理中有两个重要的数据结构:元数据和变异。元数据用于路由,变异用于标头操作。

在请求路径上,解码器(编解码器实现的解码方法)使用从请求中解析的键值对填充元数据数据结构,然后元数据将传递给 MetaProtocol 路由器。路由器在匹配从 Aeraki 通过 RDS 收到的路由配置和元数据后,选择合适的上游集群。

如果需要修改请求,自定义过滤器可以填充变异数据结构,其中包含任意键值对:添加标头或更改标头的值。然后,变异数据结构将传递给编码器(编解码器实现的编码方法)。编码器负责将键值对写入线协议。

The Request Path
请求路径

响应路径与请求路径类似,只是方向相反。

The Response Path
响应路径

一个例子

如果您需要基于 MetaProtocol 实现应用程序协议,您可以按照以下步骤操作(以 Thrift 为例)

数据平面

apiVersion: metaprotocol.aeraki.io/v1alpha1
kind: ApplicationProtocol
metadata:
  name: thrift
  namespace: istio-system
spec:
  protocol: thrift
  codec: aeraki.meta_protocol.codec.thrift

控制平面

您不需要实现控制平面。Aeraki 监视服务和流量规则,生成 sidecar 代理的配置,并通过 EnvoyFilter 和 MetaProtocol RDS 将配置发送到数据平面。

协议选择

与 Istio 类似,协议通过服务端口前缀标识。请使用此模式命名服务端口:tcp-metaprotocol-{application protocol}-xxx。例如,Thrift 服务端口应命名为 tcp-metaprotocol-thrift。

流量管理

您可以通过 MetaRouter CRD 更改路由。例如:将 20% 的请求发送到 v1,80% 发送到 v2

apiVersion: metaprotocol.aeraki.io/v1alpha1
kind: MetaRouter
metadata:
  name: test-metaprotocol-route
spec:
  hosts:
    - thrift-sample-server.thrift.svc.cluster.local
  routes:
    - name: traffic-spilt
      route:
        - destination:
            host: thrift-sample-server.thrift.svc.cluster.local
            subset: v1
          weight: 20
        - destination:
            host: thrift-sample-server.thrift.svc.cluster.local
            subset: v2
          weight: 80

如果您需要在服务网格中管理除 HTTP 之外的协议,希望这可以帮到您。如有任何疑问,请联系zhaohuabing

参考

分享此文章