如何在 Istio 中支持 Dubbo、Thrift、Redis 以及任何七层协议? (2)

然而在 Istio 中,对于除了 HTTP 和 gRPC 之外的协议,我们只能在 OSI 三到六层对这些协议进行处理。这意味着我们只能基于三层的 IP 地址,四层的 TCP 端口或者六层的 SNI(Server Name Indication)对这些协议进行路由。只能收集到 TCP 层面的指标,例如 TCP 收发包数量或者打开/关闭的 TCP 链接数量。只能采用 mTLS 进行链路层面的认证和权限控制。换而言之,对于这些协议,我们依然需要在应用代码中处理流量控制、可观测性、安全认证这些本应该由 Service Mesh 基础设施来统一处理的共性问题。这违背了我们将微服务迁移到 Service Mesh 的初衷:将微服务通信和治理的共性问题从应用代码下沉到 Service Mesh 基础设施层。

如何在 Istio 中支持 Dubbo、Thrift、Redis 以及任何七层协议?

如何扩展 Istio 的协议管理能力?

如果我们希望能够在 Istio 中管理这些七层协议,我们应该如何实现呢?假设我们有一个 BookInfo 微服务,但该微服务采用了一种称为 AwesomeRPC 的协议而不是 HTTP 来实现服务间的远程调用。

如何在 Istio 中支持 Dubbo、Thrift、Redis 以及任何七层协议?

我们来看一下如何才能够在 Istio 中实现 AwesomeRPC 协议的流量管理,例如根据请求 header 中的 user name 字段将来自 ProductPage 的请求路由到不同版本的 Reviews 中,以实现一个灰度发布的场景。

我们想到的最显而易见的方式就是直接修改 Istio 代码。首先我们需要在 Istio 的 VirtualService CRD 中支持 AwesomeRPC 协议。增强后的 VirtualService CRD 如下图中最左的规则配置所示。 AwesomeRPC 和 HTTP 路由的语义类似,都是根据 Header 中某些属性的值进行路由。因此我们只需要将 HTTP 协议类型改为 AwesomeRPC,可以直接采用 VirtualService 中的 HTTPRoute 结构来表示 AwesomeRPC 的路由规则。然后我们需要在 Pilot 代码中根据 AwesomeRPC 的服务定义和 VirtualService 定义的路由规则生成 Envoy 所需的真实配置,并通过 xDS 下发给数据面的 Envoy。当然,以上的前提是我们已经通过 Envoy 的 Filter 扩展机制编写了 AwesomeRPC 的 Filter 插件,实现 AwesomeRPC 的编解码,Header 解析,动态路由等数据面所需的功能。

如何在 Istio 中支持 Dubbo、Thrift、Redis 以及任何七层协议?

采用这种方式,在 Envoy Filter 已经实现了的情况下,在控制面增加一个新的七层协议的过程是相对比较简单的。但是由于我们修改了 Istio 的源码,因此需要自己维护一个 Istio 的私有分支,这导致了额外的维护代价,并且很难跟上 Istio 快速的迭代步伐。

如果不希望维护自己的 Istio 代码分支,一种可行的替代方式是采用 Istio EnvoyFilter CRD:EnvoyFilter 是 Istio 提供的一种灵活强大的配置机制。我们可以使用 EnvoyFilter为 Pilot 生成的缺省 Envoy 配置打一个补丁,添加、修改或者删除缺省 Envoy 配置中的部分内容,以按我们的要求修改 Envoy 在 Istio Service Mesh 中的缺省行为。

如下图所示,由于 Pilot 并不理解 AwesomeRPC 协议,对于 Pilot 来说, AwesomeRPC 服务只是一个 TCP 服务。在 Pilot 生成的缺省配置中,AwesomeRPC 服务对应的 Outbound Listener 的 FilterChain 中采用了一个 TCP Proxy 来处理其流量。我们在 EnvoyFilter 的 Match 部分中选中该 TCP Proxy,并在 Operation 部分将其替换为一个配置了 Traffic Splitting 规则的 AwesomeRPC Filter。Pilot 会根据 EnvoyFilter 修改其生成的缺省 Envoy 配置,然后下发到数据面的 Envoy 上。这样我们就通过 EnvoyFilter 在 Istio 中实现了对 AwesomeRPC 协议的支持。

如何在 Istio 中支持 Dubbo、Thrift、Redis 以及任何七层协议?

下面我们来看一个采用 Thrift 协议的真实案例。Thrift 是 Apache 基金会下一个轻量级、支持多语言的开源 RPC 框架。Envoy 中已经支持 Thrift,但 Istio 中只对 Thrift 提供了有限的支持,并不能实现 Traffic Splitting 等高级流量管理功能。如果我们希望在 Istio 中提供下图中右下角所示 Thrif 服务的 Traffic Splitting 流量控制,我们可以通过 EnvoyFilter 来实现。

(本示例相关源码可以从 https://github.com/aeraki-framework/thrift-envoyfilter-example 下载)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyzgwd.html