写在前面的话:
最近在学习Service Mesh,也系统看了下它的原理以及演进过程,算是对Service Mesh 有了一个认识,便尝试着整理下Service Mesh一些文章,而这篇文章也是本系列的第一篇文章。
本篇文章主要的目的是想讲清楚下面几个问题:
代码语言:javascript复制问题1: Service Mesh是什么?
问题2: 为什么我们需要Service Mesh?
问题3: Service Mesh 能做什么?
问题 1: Service Mesh 是什么?
Service Mesh 是伴随微服务架构和云原生而产生的,可以说是云原生里面的网络通讯层,主要用来解决网络通讯层面的问题。
对于云原生来说,kubernetes更像是一个大型的分布式操作系统,负责调度和维护这里面的资源信息。而Service Mesh则是其中的网络通讯部分,负责云原生里面的网络通讯部分。
Service Mesh的定义如下所示:
代码语言:javascript复制A service mesh is a dedicated infrastructure layer for handling
service-to-service communication. It’s responsible for the reliable
delivery of requests through the complex topology of services that
comprise a modern, cloud native application. In practice,
the service mesh is typically implemented as an array of lightweight
network proxies that are deployed alongside application code,
without the application needing to be aware.
(翻译:Service Mesh 是一个专门处理服务通讯的基础设施层。
它的职责是在由云原生应用组成服务的复杂拓扑结构下进行可靠的请求传送。
在实践中,它是一组和应用服务部署在一起的轻量级的网络代理,
并且对应用服务透明。)
关键信息为:
本质:基础设施层。
功能:请求分发。
部署形式:网络代理。
特点:透明。
架构图如下所示:
介绍: Service Mesh一个专用的基础设施层,旨在“在微服务架构中实现可靠、快速和安全的服务间调用”。它不是一个“服务”的网格,而是一个“代理”的网格,服务可以插入这个代理,从而使网络抽象化。在典型的服务网格中,这些代理作为一个 Sidecar(边车)被注入到每个服务部署中。服务不直接通过网络调用服务,而是调用它们本地的Sidecar代理,而 Sidecar代理又代表服务管理请求,从而封装了服务间通信的复杂性。相互连接的 Sidecar 代理集实现了所谓的数据平面。
构成:主要由控制平面与数据平面共同构成。
控制平面:
代码语言:javascript复制不直接解析数据包。
与控制平面中的代理通信,下发策略和配置。
负责网络行为的可视化。
通常提供 API 或者命令行工具可用于配置版本化管理,便于持续集成和部署。
数据平面:
代码语言:javascript复制1.通常是按照无状态目标设计的,但实际上为了提高流量转发性能,
需要缓存一些数据,因此无状态也是有争议的。
2.直接处理入站和出站数据包,转发、路由、健康检查、负载均衡、认证、鉴权、产生监控数据等。
3.对应用来说透明,即可以做到无感知部署。
问题2:为什么我们需要Service Mesh?
Service Mesh 是伴随微服务产生的,随着微服务的普及,微服务相关的痛点也显露无疑,而Service Mesh就是为了解决这些痛点而被设计出来的。
个人理解:对于微服务而言,本质就是对一些耦合在一起的业务或者基础逻辑做解耦操作,尽量让一个服务支持一个或者很少量几种组合的功能,然后切分成这种很小粒度的服务,也就是微服务。 这种切割方式,势必会导致业务逻辑依赖的公共代码逻辑,需要在切分出来的几个微服务中都需要使用一套。除此之外,服务的数量也同样变得很多,是切割之前的几倍,几十倍,甚至几百倍的增长,而这种数量的变化也导致了微服务的管理和维护成本变高。
下面列出了微服务架构的一些痛点,如下所示:
1)侵入性强。
想要集成 SDK 的能力,除了需要添加相关依赖,往往还需要在业务代码中增加一部分的代码、或注解、或配置,业务代码与治理层代码界限不清晰。(备注:就算我们采用代码实现统一lib的方式,但是还是改变不了把lib库代码侵入到业务代码的事实。)
2)升级成本高。
每次升级都需要业务应用修改 SDK 版本,重新进行功能回归测试,并且对每一台机器进行部署上线,而这对于业务方来说,与业务的快速迭代开发是有冲突的,大多不愿意停下来做这些与业务目标不太相关的事情。(备注:如果部署的数量很多,而我们又不能保证每次修改的SDK都是对的,这就要求我们还有考虑回滚策略,以及如何灰度发布这些服务,这无疑让我们的升级成本变得非常之高。
除此之外,在同一家公司中往往会出现不同语言、不同框架的应用和服务,为了能够统一管控这些服务,以往的做法是为每种语言、每种框架都开发一套完整的 SDK,维护成本非常之高,而且给公司的中间件团队带来了很大的挑战。)
3)版本碎片化严重。
由于升级成本高,而中间件却不会停止向前发展的步伐,久而久之,就会导致线上不同服务引用的 SDK 版本不统一、能力参差不齐,造成很难统一治理。(备注:这种情况,最常见的例子是:不同的产品对SDK的需求不一致,这就导致了一些服务必须需要升级SDK版本,而另外一些不需要升级。)
4)中间件演变困难。
由于版本碎片化严重,导致中间件向前演进的过程中就需要在代码中兼容各种各样的老版本逻辑,带着 “枷锁” 前行,无法实现快速迭代。
5)内容多、门槛高。
Spring Cloud 被称为微服务治理的全家桶,包含大大小小几十个组件,内容相当之多,往往需要几年时间去熟悉其中的关键组件。而要想使用 Spring Cloud 作为完整的治理框架,则需要深入了解其中原理与实现,否则遇到问题还是很难定位。
6)治理功能不全。
不同于 RPC 框架,Spring Cloud 作为治理全家桶的典型,也不是万能的,诸如协议转换支持、多重授权机制、动态请求路由、故障注入、灰度发布等高级功能并没有覆盖到。而这些功能往往是企业大规模落地不可或缺的功能,因此公司往往还需要投入其它人力进行相关功能的自研或者调研其它组件作为补充。
问题3: Service Mesh能做什么?
1. 正是基于上面的这些痛点,Service Mesh产生了,它采用下面的方式来解决上面的痛点:
1)微服务治理与业务逻辑的解耦。
服务网格把 SDK 中的大部分能力从应用中剥离出来,拆解为独立进程,以 Sidecar 的模式进行部署。服务网格通过将服务通信及相关管控功能从业务程序中分离并下沉到基础设施层,使其和业务系统完全解耦,使开发人员更加专注于业务本身。(备注:如此以来,原本需要部署到业务逻辑中的SDK,就可以单独部署起来,就算对SDK进行更新,我们也不需要去升级业务的代码。)
2)异构系统的统一治理。
有了服务网格之后,通过将主体的服务治理能力下沉到基础设施,多语言的支持就轻松很多了。只需要提供一个非常轻量级的 SDK,甚至很多情况下都不需要一个单独的 SDK,就可以方便地实现多语言、多协议的统一流量管控、监控等需求。
2.对于Service Mesh来说,它天生就具有下面的一些优势:
1)可观察性。
因为服务网格是一个专用的基础设施层,所有的服务间通信都要通过它,所以它在技术堆栈中处于独特的位置,以便在服务调用级别上提供统一的遥测指标。这意味着,所有服务都被监控为“黑盒”。服务网格捕获诸如来源、目的地、协议、URL、状态码、延迟、持续时间等线路数据。这本质上等同于 web 服务器日志可以提供的数据,但是服务网格可以为所有服务捕获这些数据,而不仅仅是单个服务的 web 层。需要指出的是,收集数据仅仅是解决微服务应用程序中可观察性问题的一部分。存储与分析这些数据则需要额外能力的机制的补充,然后作用于警报或实例自动伸缩等。
(个人理解:这一特性尤为重要。一来, 在出了问题之后,它能 帮我们去监控和追踪当前的问题在哪里,我们可以通过log,告警,事件等来实现。二来,我们也可以利用这部分的数据信息,去做分析和预判,进而能够更从容的去自动化的调节我们的服务信息。)
2)流量控制。
可以为服务提供智能路由(蓝绿部署、金丝雀发布、A/B test)、超时重试、熔断、故障注入、流量镜像等各种控制能力。而以上这些往往是传统微服务框架不具备,但是对系统来说至关重要的功能。例如,服务网格承载了微服务之间的通信流量,因此可以在网格中通过规则进行故障注入,模拟部分微服务出现故障的情况,对整个应用的健壮性进行测试。由于服务网格的设计目的是有效地将来源请求调用连接到其最优目标服务实例,所以这些流量控制特性是“面向目的地的”。这正是服务网格流量控制能力的一大特点。
(个人理解:这一特性,算是Service Mesh对于微服务架构的核心贡献之一,它是SDK解耦之后的最大亮点之一,让服务发布变得简单,管理更加容易,甚至在我们设置好了规则之后,往自动化发布的方向迈了一大步。)
3)安全。
在某种程度上,单体架构应用受其单地址空间的保护。然而,一旦单体架构应用被分解为多个微服务,网络就会成为一个重要的攻击面。更多的服务意味着更多的网络流量,这对黑客来说意味着更多的机会来攻击信息流。而服务网格恰恰提供了保护网络调用的能力和基础设施。服务网格的安全相关的好处主要体现在以下三个核心领域:服务的认证、服务间通讯的加密、安全相关策略的强制执行。
3.所有的事情都有两面性,Service Mesh也不例外,它同样带来了新的问题和挑战,如下所示:
1)增加了复杂度,特别是网络拓扑的复杂度。服务网格将 Sidecar代理和其它组件引入到已经很复杂的分布式环境中,会极大地增加整体链路和操作运维的复杂性。
2)延迟。从链路层面来讲,服务网格是一种侵入性的、复杂的技术,可以为系统调用增加显著的延迟。这个延迟是毫秒级别的,但是在特殊业务场景下,这个延迟可能也是难以容忍的。(备注:Service Mesh引入了代理的这种方式,相当于在以前通讯的基础上面新增了一跳,这样从物理层面就会导致一些额外的延迟。)
3)平台的适配。服务网格的侵入性迫使开发人员和运维人员适应高度自治的平台并遵守平台的规则。
参考资料:
云原生社区:https://cloudnative.to/
servicemesher社区:https://www.servicemesher.com/
Iistio中文网:https://istio.io/latest/zh/
listio官网:https://istio.io/
Istio Handbook书籍:https://www.servicemesher.com/istio-handbook/
envoy英文文档:https://www.envoyproxy.io/docs
envoy中文文档:https://www.servicemesher.com/envoy/
开源代码:
Istio: https://github.com/istio/istio
mosn: https://github.com/mosn/mosn
envoy: https://github.com/envoyproxy/envoy