在微服务架构中,应用程序将调用栈(call stack)的硬性(rigidity)和稳定性(stability)换成了网络的灵活性(flexibility)和混乱(chaos)。与调用栈无关的诸如延迟、中断重试、安全性和可追溯性已成为服务调用的关注点。服务网格帮助开发人员从这些问题中脱身,从而专注于开发业务解决方案。
API 网关和服务网格之间有很多重叠。本文探讨了服务网格的概念、优点、与 API 网关的不同,并为服务网格的使用提供了建议。
建议摘要
对于在容器上运行的大型组件化分布式应用程序,应用程序团队均应使用服务网格来管理、保护和监控其服务。 这些应用程序内,服务之间的流量是最适合服务网格的。API 网关则是用来管理业务与合作伙伴之间或两个内部业务部门之间的交互。
服务网格具有多种模式,比较理想的模式是在容器中运行的 sidecar proxy。 Istio 是最常见的服务网格产品,其他还有 Consul、Linkerd,在投资服务网格之前,我们应该评估服务网格产品的前景、成熟度,以及行业内是否已经有明确的标杆产品(例如在容器领域,Kubernetes 已经是事实上的行业标准)。
尽管服务网格在很大程度上与 API 网关、安全性、弹性和监控重叠,但是最好还是将其视为云技术,因为它与容器紧密结合在一起,并且支持云原生应用程序。
什么是服务网格?
从功能调用的调用栈转移到网络会带来安全性、不稳定和调试问题。服务网格就是用来解决这些问题的一套架构模式和支持工具。例如,功能调用可以知道被调用的功能始终可用,但网络调用不行。服务网格会通过对客户端应用程序以透明(transparent)方式的重试来帮助客户端端点处理这种网络不稳定性。另外,它还会将请求路由到最佳配置策略的 服务器节点。
服务网格通常由两层实现:数据平面(data plane)和控制平面(control plane)。 数据平面充当连接客户端和服务器端点的代理,执行从控制平面接收的策略,并且是将运行时指标反馈回控制平面的监控工具。控制平面则是管理 service policy 和数据平面的编排。
最受欢迎的数据平面是 Envoy,这是一种由 Lyft 创建的开源代理,可作为本地云应用程序(包括本地私有云)的 sidecar 运行。最受欢迎的控制平面是 Istio,这是由 Lyft、Google 和 IBM 联合创建的一个开源服务网格,能将 Envoy 实例作为容器 sidecar 注入并管理云原生应用程序。
以下是一些典型的服务网格功能,但不是所有服务网格都有这些功能。
流量路由(Traffic Routing)
服务网格可以基于策略或配置将请求路由到 service 实例。 它还能对来自客户端应用程序的流量进行优先级排序,选择性地将流量路由到不同版本的 service,以支持:
- 金丝雀部署。
- AB Test。
- 服务版本控制、向后兼容。
可观察性
proxy 日志调用替代开发人员登录到每个客户端和服务器。通过这些日志,下游监控工具可以分析并回报性能和可用性,提供基本的跨调用链跟踪。通过额外的编程,开发人员可以增强调用链分析,包括业务交易跟踪。
一些典型的可观察性功能如下:
- 服务图和仪表板显示服务如何相互连接(无需更改代码)。
- 发出信号和警报,以显示延迟、吞吐量和错误率(无需更改代码)。
- 跟踪请求或业务交易是如何通过网格的(只需在代码标头中更改传递交易 ID)。
弹性
Proxy-enforced 重试策略使开发人员解决了服务调用短暂无法使用的情况。代理可以尝试使用该服务的备用路径或故障转移到备份服务。例如,如果 Netflix 的个性化推荐服务处于脱机状态,那就会退回到未个性化的默认推荐服务。在尝试所有努力后,它才会返回错误。开发人员认为,如果服务的调用失败,那么代理要尽最大努力处理通信错误。
我们可以配置和实施的弹性模式示例:
- 重试策略。
- 断路器模式。
- 速率限制、节流。
安全策略
将单体应用拆分为许多独立的服务会大大增加其攻击面。 每个服务都是需要保护的入口。使用服务网格,客户端和服务器端点上的代理都可以应用策略来保护两者之间的通信。服务网格不需要开发人员手动将安全性编程到每个服务中。代理负责身份验证、授权和加密,这就是服务网格内的零信任安全性。
身份识别
服务网格可以管理和维护哪些身份能访问哪些服务,并维护访客访问服务的日志。 身份可以通过 JWT 进行验证,从而允许基于终端用户以及服务调用进行授权。
加密
如上所述,服务之间的通信是加密的。控制平面提供证书管理功能,例如证书生成和证书轮换,它会将这些证书和相关的配置数据推送到数据平面。
相互 TLS 身份验证的支持非常强大。相互 TLS 是指两个端点把证书加入连接的另一端点白名单,它能提供身份验证和加密。
一些组织更倾向于 OAuth 而非相互 TLS 身份验证作为其 API 网关的身份验证协议。这是因为使用相互 TLS 需要手动维护证书。如果手动维护未正确完成,这可能会导致维护失败和生产中断。相比之下,服务网格可以在没有人工操作的情况下即时颁发新证书。这是因为网格管理着客户端和服务器端点,并且可以控制它们使用和预期使用的证书。
服务网格与API 网关
尽管服务网格和 API 网关乍一看很相似,但是深入研究微服务和 API serve 的不同需求时,它们会有很大不同。
微服务和 API 服务不同的需求
微服务和 API 服务解决了两个不同的问题,前者是技术性问题,后者是业务问题。
- 微服务应在有界上下文(bounded context)中进行通信。它们的设计是由连接组成有界上下文的组件需求所驱动的,就像远程过程调用(RPC)一样。
- API(通常是 REST,但也包括事件流和其他协议,例如 SOAP、gRPC 和 GraphQL)应提供接口,将有界上下文暴露给外界。理想情况下,它们的接口设计是由业务价值驱动的,而不仅仅是 RPC。
换句话说,API 是在外部将一个有界上下文的业务暴露给另一个有界上下文,而微服务是构成有界上下文内部的几个组件。在传统体系结构中,这些组件可能是通过进程调用栈进行通信的类或 DLL。在微服务架构中,它们可能是跨网络通信的独立服务。
服务网格和 API 网关满足不同需求
要了解服务网格和 API 网关之间的区别,首先我们要定义“定向流量”(directional traffic)。东西流量通常是指数据中心内的数据,而南北方向是指进出数据中心的流量。
在本文中,从有界上下文的角度来看:停留在有界上下文内的流量是东西流量,而越过有界上下文的流量是南北流量。
服务网格旨在管理东西流量。 虽然 API 网关也可以管理东西流量,但服务网格更适合。这是因为服务网格在连接的两端都有代理。东西方都可以进行这种配置,因为这两个端点都由同一应用开发组织控制。
服务网格同样可以管理南北流量,但 API 网关更适合,因为它连接的一部分不在服务网格的控制范围之内。
此外,南北流量通常涉及业务合作伙伴,并且需要管理终端用户的体验。API 网关更专注于管理终端用户体验。 它们通常是较大的 API 管理解决方案一部分,具有集成的 API 目录和开发人员门户,能将内部开发人员和外部业务合作伙伴加入其中。
相反,服务网格并不专注于管理服务客户端终端用户体验。由于服务网格旨在管理组成应用程序、有界上下文的服务,因此其所有的客户端通常由拥有服务的同一 IT 部门构建,团队可以轻松更改微服务的界面。
总而言之,API 网关和服务网格两者是相辅相成的:API 网关处理外部流量和服务网格处理内部流量,其拓扑结构如下图所示:
何时使用服务网格
如果我们拥有具有动态、需要频繁更改的服务和大量东西流量的分布式组件化体系结构(即微服务或微型服务体系结构),就需要服务网格。以下是一些有助于做出决定的注意事项。如果有一个问题的回答为“是”,那就要考虑服务网格了。
- 环境。 网络拓扑是否会随着多个服务的伸缩而频繁更改?
- 代码更改。 代码是每周更改一次还是更频繁地更改?
- 服务数量。 有十个或更多的微服务吗?是否有大量的东西网络流量?是否每个点都可以扩展到五个或更多实例?
- 安全。 是否需要相互 TLS 来保护服务,但又无法手动维护这么多服务证书?请注意,自动相互 TLS 是采用服务网格的首要原因。
- 可观察性。 是否需要观察服务之间的交互并通过系统跟踪业务交易?
何时不使用服务网格
在以下情况下,服务网格可能不会带来任何其他好处:
- 很少的服务。 只有很少的服务(少于 10 个是标准),或者服务无法扩展到许多实例(少于 5 个是标准)。
- 可观察性。 不需要服务之间的细粒度跟踪,或可以通过诸如 AppDynamics 之类的简单工具轻松解决。
- 没有东西流量。 应用程序中的所有通信都保持在一个边界内,没有或几乎没有内部网络通信。
- 固定的网络拓扑。 应用程序的网络拓扑是固定的,并且变化非常有限。
- 很少更改代码。 当企业仅需要很少地更改应用程序时,微服务和服务网格所提供的敏捷性就不适用。
服务网格评估
几乎所有服务网格都在使用 Envoy sidecar 作为数据平面。他们最明显的区别是在控制平面上。尽管大多数控制平面都使用 Istio,但与 Istio的竞争仍然很多。对不同服务网格的评估应侧重于控制平面的功能,以及哪个控制平面满足我们的需求。这里有一些注意事项:
- 控制平面是否在 Cl/CD pipeline 中提供了最大的价值?
- 控制平面是声明性的吗?
- 是否允许自助服务(self-service)?
总结
服务网格采用了许多专门用于管理组成分布式组件化应用程序的微服务或微服务的方式打包它们。它们与 API 网关有很多重叠,但主要关注点不同。服务网格管理组成应用程序或有界上下文服务的东西流量。API 网关管理公共接口的南北流量,重点是管理用户与 API 的关系。服务网格管理连接的两个端点,并且仅限于容器化的应用程序。API 网关管理连接的服务器端点,可以对任何 API 进行管理。