微服务架构下服务网格的出现带来了什么?

更新时间 2022-11-25

服务网格介绍

服务网格是一种技术架构,它用于管理微服务系统中各个服务之间的通信,旨在处理微服务间的流量(也称为东西向流量)。

在云原生应用中,一个应用的背后可能存在着成百上千个服务,各个服务可能又有着若干个实例,各个实例的状态也一直在变化。在如此复杂的服务运行环境中,如何保障用户的可靠访问以及维持业务的平稳运行成为一个很大的挑战,服务网格的治理方案便应运而生。

服务网格就像是微服务间的 TCP/IP,负责服务间的网络调用、限流限速、监控等。服务网格目前主要应用在 Kubernetes 平台上,其最经典的一种实现模式是 Sidecar 模式:将一些通用功能抽象到 Sidecar 容器中,并将 Sidecar 容器与服务容器挂载在同一个 Pod 里。由于 Sidecar 容器与服务容器并行,且各个 Sidecar 间相互通讯,共同构成了网格形式的网络,因此称之为服务网格。如下图所示:

Service Mesh architecture

Sidecar 并非唯一的一种服务网格实现模式,除此之外还有 DaemonSet 模式及 Ambient mesh模式:

  • DaemonSet 模式与 Sidecar 的不同在于它仅在 Kubernetes 集群的每个节点上运行一个,这个 Pod 承担了类似 Sidecar 代理的工作。相比于 Sidecar 模式,DaemonSet 模式占用的机器资源会更少,当然它也会有其他的缺点,例如隔离性差,资源调度难预测等,更多差异点可以参考这篇文章:Sidecars and DaemonSets: Battle of containerization patterns

  • Ambient mesh 模式是 Istio 于 2022 年 9 月 7 日宣布的一种全新的数据面模式,它将数据面的代理从应用 pod 中剥离出来独立部署,以解决 mesh 基础设施和应用部署耦合的问题。Ambient mesh 将数据面分为安全覆盖层和七层处理层:安全覆盖层负责 TCP 路由、监控指标、访问日志、mTLS 隧道等功能;七层处理层则除了安全覆盖层的功能外,提供 HTTP 协议的流量管控,可观测性等功能,并且可以实现丰富的七层授权策略。另外 Ambient mesh 还使用了一个共享代理 ztunnel(零信任隧道),它运行在 Kubernetes 集群的每个节点上,负责安全地连接与认证 mesh 内的工作负载。关于 Ambient mesh 模式更多细节可以看参考这个文档:Introducing Ambient Mesh

为什么我们需要服务网格

在服务网格流行之前,很多微服务架构的服务治理都是通过微服务框架配合控制平台实现的,这种方式存在以下几个问题:

  1. 框架与业务耦合,整体复杂度与运维难度很高,且开发者需要对公共库有一定的了解,没法只专注于业务实现。
  2. 需要维护多种语言版本的框架,增加了维护的成本。
  3. 微服务框架本身的升级成本比较高,在升级时往往需要进行业务重启等操作。
  4. 线上存在很多版本的框架,会导致复杂的兼容性考虑。

面对以上的这几个问题,原 Twitter 工程师威廉 · 摩根 (Willian Morgan),Linkerd 的创建者之一, 提出了 “Service Mesh” 的概念,即服务网格。服务网格通过 Sidecar 模式实现在不侵入业务服务的情况下将基础设施与业务逻辑解耦,实现跨语言统一更新发布及运维。

Microservices Framework to Service Mesh

服务网格将流量管理,可观测性,安全通讯等功能下沉到基础组件,因此开发者无需关心通信层和服务治理的具体实现,与通信相关的一切工作直接交给服务网格,让开发者能够更关注于业务的开发。基于服务网格的这些特点,前面提到的几个问题都能够得到有效解决。

服务网格是如何工作的

服务网格不会为应用的运行时环境加入新功能,任何架构中的应用还是需要相应的规则来指定请求如何从 A 点到达 B 点。但服务网格的不同之处在于,它从各个服务中提取逻辑管理的服务间通信,并将其抽象为一个基础架构层。

目前服务网格大多数采用是数据面 + 控制面的架构模式,如下图所示:

Data plane & Control plane

控制面

控制面用于管理和配置数据面以及在运行时执行策略。单个网格中控制平面的所有实例共享相同的配置资源。

控制面聚焦于安全、可观测性、流量管控等策略的处理和下发,同时还能够收集和集中数据平面的遥测数据,供运维人员使用。

数据面

数据面通常以代理的形式实现,是由一个个的网络代理 Sidecar 组成,Sidecar 与业务应用实例并行,通过拦截业务数据流以管控业务应用的流量。

在前面的介绍中有提到服务网格是将 Sidecar 设计模式在 Kubernetes 进行实现,通过容器化的方式实现了封装,Sidecar 主张以额外的容器来扩展或增强主容器,这个额外的容器被称为 Sidecar 容器,它与业务容器在同一个 Pod 中。而服务网格即是一个个 Sidecar 代理所构成的网格式网络。

服务网格的实际应用

在微服务架构中,工程师往往会为对外暴露的服务采取加密或访问限制的措施以保障服务的安全,但却忽视了集群内部的流量通信安全,所以至今仍有很多微服务应用没有采取服务间通信的加密措施,集群内部的流量以明文的形式进行传输,非常容易导致内部流量遭到数据窃听或是中间人攻击。

而为了防止集群内部流量遭到攻击,通常会使用 mTLS 将通讯数据进行加密。mTLS 可以用于确保服务网格中微服务之间的通信安全。它使用加密安全技术相互认证各个微服务并加密它们之间的流量。

mTLS Comparison

虽然可以直接在微服务中定义通信安全策略并执行身份验证和加密,但在每一个微服务中去单独实现相同的功能效率是很低的。而且增加功能还需要改动业务代码,侵入业务逻辑。且即便完成了功能,后期的升级迭代与测试都需要开发者投入额外精力去维护,无法专注于业务功能的开发。

而使用服务网格,我们就可以在不影响原本业务的情况下零感知的为服务提供 mTLS 通信。因为在服务网格中,服务通信相关的功能都被转移至 Sidecar 代理中实现。

当两个微服务需要通信时,将由 Sidecar 建立 mTLS 连接,加密的流量将通过该 mTLS 连接流动。Sidecar 之间会交换证书并通过证书颁发机构相互认证。在发起连接前, Sidecar 会检查控制面推送的配置中的授权策略,以判断是否允许微服务进行通信。如果允许则 Sidecar 会使用生成的会话密钥建立安全链接,加密微服务间的通信数据。在整个实现过程中,业务应用都不会受到影响,降低开发者心智负担。

mTLS

通过这个场景,相信大家就能理解服务网格是如何做到在不影响业务的情况下拓展当前应用的功能的。当然,服务网格除了可以实现类似 mTLS 这类的内部流量安全配置功能,通过调整控制面的配置还能快速的拓展包括流量管控,可观测性,协议编解码等更多功能。

总结

这篇文章为大家介绍了服务网格基础概念、工作原理以及服务网格可以为我们带来的价值。服务网格为微服务架构带来了很大的变革,让开发者从复杂的微服务环境中抽身,专注于业务功能的开发。

虽然服务网格解决了很多微服务架构中的痛点,但它也同时有自己的局限性,在软件开发中复杂度是不灭的,只是在不同的部分之间做转移。我们将服务治理抽离为单独的一层就要面对流量链路的增长以及运维难度的提升,且服务网格需要在云原生的环境中使用,这对于运维的专业能力及工程实践经验有了更高的要求。所以说技术只是用于解决问题的工具,服务网格能带来的价值还是得从应用的从实际情况出发。

随着云原生的爆炸式发展及服务网格的不断优化,未来的服务网格可能会完全取代传统微服务架构,成为各个企业微服务及云原生改造的首选架构。