Service Mesh 入门理论篇

727 阅读13分钟

微服务架构

微服务架构特性

  • 特性1:围绕业务构建团队 image.png 左边是单体应用的一个典型模式,一个开发团队按照职能划分成不同的层次。一起开发一个应用,包括前端页面,中间的业务逻辑,以及最后的数据库。 右边是微服务架构,整个开发团队会围绕这业务去构建,不同的职能会被划分成一个个小的团队,一个小团队去实现独立业务。

  • 特性2:去中心化数据管理
    image.png 左边的单体应用整个数据库是一个整体(在逻辑上是一个整体,有可能物理上部署不是一处),数据是中心化的。 右边的微服务架构下,数据库和业务是绑定在一起的,不同业务有不同数据库,这就是去中心化数据的特点。

微服务架构优势

  • 团队层面:内聚,独立开发业务,没有依赖,沟通成本会急剧降低。

  • 产品层面:服务彼此独立,独立部署,没有依赖。
    独立部署主要有两个好处:

    • 第一个好处就是可以充分利用系统资源,比如说,模块一它可能访问量比较高,可以多部署几份或者机器配置好一些,模块二访问比较低,就可以少部署几份或者机器配置低一些。
    • 第二就是可以独立部署,不用协调等待其他模块。

微服务架构面临问题

微服务构建面临的痛点就是,服务间网络通信的问题。比如下图,假设服务调用时,网络出现中断,你怎么调试问题在哪里?
image.png

如果你的微服务非常复杂如下面两个图,你如何找到问题的节点
image.png

如何管理和控制服务间网络通信

  • 服务注册/发现
  • 流量控制,需要进行路由,流量转移
  • 系统弹性能力,当系统故障时,通过熔断、超时、重试这些弹性能力提升系统的健壮性和可靠性
  • 网络安全,需要网络授权,身份认证
  • 对于微服务来说,服务的可观化非常重要,可视化的观察服务的状态,系统资源使用情况

以上的这些功能,其实就是 Service Mesh 的主要功能。

Service Mesh 演进

第一阶段:控制逻辑和业务逻辑耦合

image.png

上面图中,服务A的业务逻辑和两个流控相关(熔断,服务发现)的逻辑耦合在一起,在业务代码里面加了很多网络控制相关的逻辑。比如下面这段代码,发起一个http或者RPC请求,如果失败就重试3次,最后退出。 image.png 这样的代码将业务逻辑和控制逻辑耦合在一起,使得业务逻辑变得凌乱不堪。

为了解决这样的问题,就发展了第二阶段:公共库

第二阶段:公共库

image.png 公共库的意思是把这些控制逻辑全都集中在一起,形成一个公共的工具包,这样网络控制相关逻辑和业务逻辑分开。这些公共库市面上也有很多产品,比如 TwitterFinagle , SpringCloud 的一些组件, 以及 Netflix 开源的一些产品。

公共库好处就是 解耦,不需要再业务代码里写控制逻辑,另外,公共库消除代码重复
但是公共库还是有些问题:
比如需要专门维护公共库,假如公共库升级了,就需要重新去部署一份。
另外公共库一般都是语言绑定的,如果你用的语言和公共库语言不一样,那你就需要引入不同的语言和技术栈,增加学习和维护成本。
虽然公共库可以消除代码重复,但是本质上它依然是和应用同时运行的,仍然有侵入。

公共库的不完美,就促使发展第三阶段:代理

第三阶段:代理

image.png 由于公共库的一些缺点,就想着通过代理来解决网络控制相关的能力。从图上可以看出一些差别,公共库不在和业务逻辑部署在一起了,而是单独抽出一个模块,这个模块就是代理,由代理去包含相应的控制逻辑。

但是代理也有一个最大问题就是,功能比较简陋,但是思路是正确的,因此就发展代理的下一个阶段,Sidecar 模式。

第四阶段:Sidecar 模式 (边车模式)

image.png

image.png
由上图,在应用旁边(ServiceA、ServiceB)部署一个 Sidecar,由这个 Sidecar 去处理网络请求,完成之后再把请求转发给应用本身。Sidecar 模式下,网络代理服务在微服务旁边,为微服务提供通信和链路治理功能。

Sidecar 模式非常接近现在的 Service Mesh,可以看作是第一代 Service Mesh

Sidecar 模式有个突出的问题,将通信和通信链路治理的所有功能都放到这个代理服务中,导致数据平面代理很重,并且由于承载了太多的特性和功能,使得数据平面代理的更新和修改特别频繁,频繁的更新和升级会导致代理服务出问题的概率增大,影响代理服务的稳定性。

同时,Service Mesh 模式下,数据平面代理承载了微服务通信的全部流量,对稳定性要求极高,这个服务的任何故障都会对整个系统的稳定性产生很大的影响。

为了解决上述频繁升级和稳定性之间的矛盾将策略和配置决策逻辑从代理服务中脱离出来,形成了独立的控制平面,这就是第二代 Service Mesh

第五阶段:Service Mesh

image.png
这张图表明 1 个 pod 有两个部分组成,一个是微服务,一个是 Sidecar,一个应用中包含多个不同的微服务,就形成了上图的 Service Mesh 产品形态。

第二代 Service Mesh 最重要的标志就是控制平面和数据平面分离

image.png

  • 数据平面
    数据平面负责代理微服务之间的通信,具体包含RPC通信、服务发现、负载均衡、降级熔断、限流容错等,数据平面完全聚焦在变更频率很低的流量路由和转发逻辑上,提升了数据平面的稳定性。

  • 控制平面
    控制平面负责对数据平面进行管理,定义服务发现、路由、流量控制、遥测统计等策略,这些策略可以是全局的,也可以通过配置某个数据平面节点单独指定

Service Mesh 演进总结

image.png
在一开始阶段没有形成对网络控制逻辑的完整思路,一般都是在业务中添加网路控制逻辑,使得代码难以维护。
为了解决这个问题,出现了公共库,公共库把网络管控的功能整合单独工具包,解决了耦合,但是它的复杂性以及语言绑定还有侵入问题不得不寻求其他方案。
代理这种思路方向是正确的,彻底的把应用和网络控制解耦,但是它的功能比较简陋。
于是在代理思路基础上发展 Sidecar 模式。随着它的发展逐渐形成 Service Mesh形态,Service Mesh可以简单的理解为一个网络拓扑组合。
到了18年以后,为了管理整个 Sidecar 网络,在 Service Mesh 产品形态上又增加了控制平面,也就是现在说的第二代 Service Mesh

Service Mesh 概念

image.png

大体意思就是 ,Service Mesh 是一个致力于解决服务间通信的基础设施层,其负责在现代云原生应用的复杂服务拓扑下实现请求的可靠传递,在实践中 Service Mesh 通常实现为一组轻量级网络代理,这些代理与应用程序部署在一起,并且对应用程序透明

从上面的定义可以看出一个简介的概念,Service Mesh 就是一个用来进行请求转发的基础设施层,它通常是以 Sidecar 的形式部署,并且对应用透明。

综合来看,它主要解决了用户3个维度的需求痛点

  • 完善的微服务基础设施
    Service Mesh 将微服务通信下沉到基础设施层,屏蔽了微服务处理各种通信问题的复杂度,这就意味着,有了 Service Mesh 之后,你不需要关注RPC通信(包含服务发现、负载均衡、流量调度、限流降级、监控统计等)的一切细节,真正像本地调用一样使用微服务

  • 语言无关的通信和链路治理
    Service Mesh 改变的是通信和服务治理能力提供的方式,通过将这些能力实现从各语言业务实现中解耦,下沉到基础设施层面,以一种更加通用和标准化的方式提供,屏蔽不同语言、不同平台的差异性

  • 通信和服务治理的标准化

    • 微服务治理层面Service Mesh 是标准化、体系化、无侵入的分布式服务治理平台。
    • 标准化方面Sidecar 成为所有微服务流量通信的约束标准,同时 Service Mesh 的数据平面和控制平面也通过标准协议进行交互。
    • 体系化方面,从全局考虑,提供多维度立体的微服务可观测能力,并且提供体系化的服务治理能力(限流、熔断、安全、灰度),以及 Service Mesh 透明无侵入

image.png Service Mesh 实际上是由 Sidecar 组成的一个网络,上图的右侧是 Service Mesh 增加一层控制平面,用来管理和控制整个 Sidercar 网络。这就是第二代 Servcie Mesh 技术,它的产品形态包括两部分,一部分叫 数据平面(也就是所有的 Sidercar 组合),另外一部分叫控制平面,用来进行总体控制。

Service Mesh 的主要功能

image.png

  • 流量控制:主要包括路由(比如蓝绿部署、灰度发布、A/B测试),流量转移,超时重试,熔断,故障注入,流量镜像。
  • 策略:Service Mesh 提供策略功能, 就像家里的路由器一样,可以在路由器上配置流量限制,黑白名单这样的设置,这是典型的策略。
  • 网络安全:授权和身份认证
  • 可观测性:对整个微服务进行观察,通过指标收集和展示,通过日志收集以及分布式追踪来完整的观测系统的运行状态。

Service MeshKubernetes 的关系

  • Kubernetes

    • 主要目的是解决容器编排与调度问题
    • 本质上是管理应用生命周期(简单的理解为一个调度器)
    • Kubernetes 会给予 Service Mesh 支持和帮助,在 Kubernetes 中 Pod是最小的调度单元,Pod天生支持多容器的部署,这就为植入 Sidecar 提供了非常大的便利
  • Service Mesh

    • 主要目的是解决服务间网络通信问题
    • 本质上是管理服务通信(简单的理解为一组 Sidecar 代理)
    • 反过来说 Service MeshKubernetes 网络功能方面提供了扩展和延伸

image.png
从这张图可以看出,Kubernetes 是处于最底层的,相当于云原生应用的一个操作系统,而 Service Mesh 是附着在这个系统之上的云原生应用的网络通信层。

Service MeshAPI 网关异同点

现有的 API 网关已经提供了 Service Mesh 的相关功能,比如负载均衡、服务发现以及一些基本的流量控制。那具体它们有什么异同呢?

image.png

这个是 Service Mesh 的部署结构,由代理 Sidecar 完全接管发送到应用的请求,处理完成之后再发送到另外的微服务

image.png

这个是 API 网关的模型,可以看到API网关实际上是部署在应用的边界的,并没有侵入到应用的内部,主要功能是对内部API进行进行聚合和抽象,以便于外部进行调用

Service Mesh 技术主要是对应用内部的网络细节进行一个描述,而API网关主要是附着在应用的边界,对流量进行一个抽象,所以它们的功能有重叠,但是角色不同,另外 Service Mesh 在应用内,API 网关在应用之上(边界)

Service Mesh 技术标准

  • 第一个标准叫 UDPA
    UDPA 就是统一的数据平面API,这个标准的目的主要是为不同的数据平面提供一个统一的API,方便你进行无缝接入。因为不同的数据平面有很多,比如 EnvoyLinkerd,它们的接入标准是不一样的,有了这个 UDPA 之后,就不用关系具体的实现细节了,直接用统一的标准接入就行。这个标准由云原生基金会提出来的。 image.png

  • 另外一个标准是 SMI
    SMI 标准目标实际上跟 UDPA类似,只不过它侧重于控制平面,它希望为用户提供一个统一的使用体验,通过这样的一个标准去接入你的控制平面,而不用关心控制平面具体实现细节。 image.png

主流的 Service Mesh 产品

image.png

Linkerd

  • Linkerd 被公认是第一个 Service Mesh 产品,
  • 2016 年底在 GitHub 上发布 0.x
  • 2017 年加入 CNCF,4 月发布 1.0 版本
  • Conduit – Linkerd2.0:支持 Kubernetes,轻量化
  • Linkerd 的败局? 从17到18年 Linkerd 可以说败得体无完肤,主要问题出现在策略上,首先,Linkerd作为一个数据平面,对比 Envoy 没有什么优势,导致产品竞争力不如 Envoy。 第二,在开发语言上,Linkerd 选择小众的 RUST 语言得不到社区的技术支持。 第三,Linkerd作为一个独立的产品,背后没有云厂商的支持

envoy

  • 2016 年 9 月发布
  • 定位于 Sidecar 代理
  • 第 3 个从 CNCF 毕业的产品
  • 稳定可靠,性能出众
  • Istio 的默认数据平面
  • xDS 协议成为数据平面的事实标准

Istio

  • 2017 年 5 月发布 0.1
  • 光环加身:Google,IBM,Lyft 背书
  • 第二代 Service Mesh,增加了控制平面,奠定目前 Service Mesh 的产品形态
  • 收编 Envoy,直接拥有高水准的数据平面
  • 受到社区强烈追捧

AWS App Mesh

  • 2018 年 re:Invent 公布
  • 2019 年 4 月 GA 发布
  • 支持自家的多种计算资源的部署,比如说它不仅仅支持 EKS(亚马逊自身平台上的 Kubernetes),还能支持 EC2、ECS,甚至支持实体机 image.png

国内 Service Mesh 发展情况

  • 蚂蚁金服:SOFA MeshMOSN 数据平面,基于 Istio 开发的,主要使用了 Istio 内部的 Pilot 控件,同时弃用了 Envoy 使用自研的 MOSN 作为数据平面
  • 几大云厂商(腾讯、阿里、百度)
  • 华为、微博