赵化冰,腾讯云高级工程师,Istio Member,ServiceMesher管理委员,Istio 项目贡献者, Aerika 项目创建者 ,热衷于开源、网络和云计算。目前主要从事服务网格的开源和研发工作。
唐阳,知乎基础架构工程师。Istio 项目贡献者,Argo 项目贡献者,专注于开源,云原生与微服务。目前负责知乎服务网格的研发工作。
备注:本文根据腾讯云赵化冰和知乎唐阳在 IstioCon 2021 中的演讲 “How to Manage Any Layer-7 Traffic in an Istio Service Mesh?” 整理而成。
大家好,今天我们想和大家分享的主题是如何扩展 Istio 以支持任何七层协议?作为云原生领域中一个人气非常高的开源项目, Istio 目前已经基本成为了 Service Mesh 的事实标准。腾讯云上也提供了基于 Istio 进行增强,和 Istio API 完全兼容的 Service Mesh 管理服务 TCM(Tencent Cloud Mesh),以帮助我们的用户以较小的迁移成本和维护代价快速利用到 Service Mesh 提供的流量管理和服务治理能力。今天非常高兴能够有这个机会来和大家一起分享一下我们在此过程中的一些经验。
Service Mesh 提供了一个对应用透明的基础设施层,可以解决我们在分布式应用/微服务中遇到的常见挑战,例如:如何找到服务提供者?如何保证服务之间的通信安全?如何得知服务之间的调用关系?如何进行流量管理如灰度发布?等等。Service Mesh 的实现方式是伴随应用部署一个 Sidecar Proxy,该 Sidecar Proxy 会拦截应用的出向和入向流量, 对这些流量进行分析和处理,以达到在不修改应用代码的情况下对服务进行流量管理、安全加密,遥测数据收集的目的。为了实现这些服务治理能力,Sidecar Proxy 不只需要在 OSI 网络模型的三、四层上对流量进行处理,更重要的是需要在七层上进行处理。在七层上,Istio 缺省只支持了 HTTP 和 gPRC 两种协议。但我们在微服务中经常还会使用到的其他七层协议,当将这些微服务应用迁移到 Service Mesh 时,我们希望使用一致的方式对所有的这些七层协议进行统一管理,以充分利用 Service Mesh 基础设施提供的云原生能力。
在今天的分享中,我将会介绍几种将 Istio 流量管理能力扩展到其他七层协议的方法,并对比分析这几种方法各自的优缺点。我会介绍如何利用 Aeraki 开源项目来在 Istio 中管理任何七层协议,包括 Dubbo、Thrift、Redis 等。为了让大家了解 Aeraki 是如何工作的,会展示一个采用 Aeraki 实现 Thrift 服务 Traffic Splitting 的例子。来自知乎的唐阳还会为我们展示如何使用 Aeraki 的一些有趣的真实案例。
Service Mesh 中常见的七层协议如下图所示,一个典型的微服务应用中通常会使用到这些七层协议:
同步调用:不同服务之间会采用 RPC (远程方法调用)进行相互调用。常见的 RPC 调用协议包括 gRPC,Thrift,Dubbo,HTTP 也可以看做一种 RPC (只支持 GET/SET/POST 这几种标准方法) 。一些大的公司为了满足自己特定业务场景的需求,往往还会采用一些私用的 RPC 协议。
异步消息:除了 RPC 之外,异步消息也是微服务通信的一种常见模式,包括 Kafka,RabbitMQ,ActiveMQ 等。
各种数据库和缓存系统:例如 Redis, MySQL,MongoDB 等等。
那么当将这样一个微服务应用加入到 Service Mesh 以后,我们希望能够通过 Service Mesh 得到哪些管理能力呢?
理想情况下,我们希望 Service Mesh 能够管理微服务中用到的所有七层协议的流量,包括 RPC、Messaging、Cache、DB等。例如:
基于请求的负载均衡:可以将来自同一个 TCP 链接的多个独立的请求分发到不同的后端服务器,以实现更智能,更合理的负载均衡。
基于七层 Header 的流量路由:根据七层 Header 中的属性进行路由,例如根据 Dubbo 请求中的服务名或者 Redis 请求的 Key 进行路由。
对客户端的请求响应注入延迟或者错误,以测试应微服务用的弹性。
提供应用级安全,例如基于 HTTP Header 中的 JWT Token 进行认证,或者对 Redis 服务器进行认证。
请求层面的遥测数据,包括请求成功率、请求耗时、调用跟踪等等。
要实现以上这些流量管理和服务治理能力,Service Mesh 需要分析和处理 TCP 数据包中的七层协议的 Header。即 Service Mesh 必须具有七层协议的管理能力,而不只是在 TCP 层面上进行处理。