Service Mesh 浅析:从概念、产品到实践

近几年,微服务架构逐渐发展成熟,从最初的星星之火到现在大规模的落地和实践,几乎已经成为分布式环境下的首选架构。然而软件开发没有银弹,基于微服务构建的应用系统在享受其优势的同时,痛点也越加明显。Service Mesh 技术也因此而生,受到越来越多的开发者关注,并拥有了大批拥趸。本文会从概念介绍开始,让大家理解 Service Mesh 技术出现的原因以及愿景;接着会对目前最主流的两个产品 Istio 和 AWS App Mesh 进行详细的比较;最后简要介绍一下我们目前在该领域的一些探索与实践。

Service Mesh – 服务通信的济世良方

Service Mesh 是什么?

Service Mesh(中文译做服务网格)这一概念由 Buoyant 公司的 CEO,William Morg」n 首先提出。2017 年 4 月该公司发布了第一个 Service Mesh 产品 Linkerd,这篇同一时间发表的文章 What’s a service mesh? And why do I need one? 也被业界公认是 Service Mesh 的权威定义。

“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 是一个处理服务通讯的专门的基础设施层。它的职责是在由云原生应用组成服务的复杂拓扑结构下进行可靠的请求传送。在实践中,它是一组和应用服务部署在一起的轻量级的网络代理,对应用服务透明。这段话有点晦涩难懂,但只要抓住下面 4 个关键点就能轻松理解:

  • 本质:基础设施层
  • 功能:请求分发
  • 部署形式:网络代理
  • 特点:透明

如果用一句话来总结,我个人对它的定义是:Service Mesh 是一组用来处理服务间通讯的网络代理。

为什么需要 Service Mesh?

上面晦涩抽象的定义很难让你真正理解 Service Mesh 存在的意义。你可能会想,服务间通信(service-to-service communication)无非就是通过 RPC、HTTP 这些方式进行,有什么可处理的?没错,服务间只需要遵循这些标准协议进行交互就可以了,但是在微服务这样的分布式环境下,分散的服务势必带来交互的复杂性,而规模越大的系统其通信越加错综复杂。分布式计算下的 8 个谬论很好的归纳了分布式环境下存在的网络问题。而为了解决这些问题,提高系统的容错能力和可用性,出现了服务注册与发现、负载均衡、熔断、降级、限流等等和通信相关的功能,而这些才是 Service Mesh 要真正处理的问题。

Pattern:Service Mesh 这篇文章详细的讲述了微服务架构下通讯处理的演进,由此引出 Service Mesh 出现的意义和核心价值。下图为服务通信演变的过程:

Service Mesh 浅析:从概念、产品到实践

上面的图展示了这几个概念的关系:当用户请求一个虚拟服务时,服务配置的路由器根据路由策略将请求指向对应的虚拟节点,这些节点最终会与集群中某个对外提供服务的 DNS 或者服务名一一对应。

那么这些 App Mesh 自创的术语是否能在 Istio 中找到相似甚至相同的对象呢?我归纳了下面的表格来做一个对比:

App MeshIstio服务网格(Service mesh)Istio 并未显示的定义这一概念,我们可以认为在一个集群中,由 Istio 管理的服务集合,它们组成的网络拓扑即是服务网格。虚拟服务(Virtual services)Istio 中也存在虚拟服务的概念。它的主要功能是定义路由规则,使请求可以根据这些规则被分发到对应的服务。从这一点来说,它和 App Mesh 的虚拟服务的概念基本上是一致的。虚拟节点(Virtual nodes)Istio 没有虚拟节点的概念,可以认为类似 Kubernetes 里的 Deployment。虚拟路由器(Virtual routers)Istio 也没有虚拟路由器的概念。路由(Routes)Istio 中的目标规则(DestinationRule)和路由的概念类似,为路由设置一些策略。从配置层面讲,其中的子集(subset)和 App Mesh 路由里选择的目标即虚拟节点对应。但 Istio 的目标规则更加灵活,也支持更多的路由策略。

从上面的对比看出,App Mesh 目前基本上实现了最主要的流量控制(路由)的功能,但像超时重试、熔断、流量复制等高级一些的功能还没有提供,有待进一步完善。

架构

AWS App Mesh 是一个商业产品,目前还没有找到架构上的技术细节,不过我们依然可以从现有的、公开的文档或介绍中发现一些有用的信息。

Service Mesh 浅析:从概念、产品到实践

熟悉 Istio 架构的朋友有没有觉得似曾相识?没错,这个控制平面的职责和 Pilot 基本一致。由此可见,不管什么产品的控制平面,也必须具备这些核心的功能。

那么在平台的支持方面呢?下面这张图展示了 App Mesh 可以被运行在如下的基础设施中,包括 EKS、ECS、EC2 等等。当然,这些都必须存在于 AWS 这个闭环生态中。

Service Mesh 浅析:从概念、产品到实践

Istio 的架构大家都比较熟悉,数据平面由 Envoy sidecar 代理组成,控制平面包括了 Pilot、Mixer、Citadel、Galley 等控件。它们的具体功能这里就不再赘述了,感兴趣的同学可以直接去官网查看详细信息。

功能与实现方式

部署

无论是 Istio 还是 App Mesh 都使用了控制平面 + 数据平面的模式,且 Sidecar 都使用了 Envoy 代理。Istio 的控制平面组件较多,功能也更复杂,1.0.x 版本完整安装后的 CRD 有 50 个左右。架构修改后 Mixer 的一些 adapter 被独立出去,crd 有所降低。下面是最新的 1.4 版本,安装后仍然有 24 个 crd。

复制代码

$ kubectl get crd -nistio-systemNAME                                     CREATED ATadapters.config.istio.io                  2019-12-24T03:46:41Zattributemanifests.config.istio.io        2019-12-24T03:46:41Zauthorizationpolicies.security.istio.io   2019-12-24T03:46:41Zclusterrbacconfigs.rbac.istio.io          2019-12-24T03:46:41Zdestinationrules.networking.istio.io      2019-12-24T03:46:41Zenvoyfilters.networking.istio.io          2019-12-24T03:46:42Zgateways.networking.istio.io              2019-12-24T03:46:42Zhandlers.config.istio.io                  2019-12-24T03:46:42Zhttpapispecbindings.config.istio.io       2019-12-24T03:46:42Zhttpapispecs.config.istio.io              2019-12-24T03:46:42Zinstances.config.istio.io                 2019-12-24T03:46:42Zmeshpolicies.authentication.istio.io      2019-12-24T03:46:42Zpolicies.authentication.istio.io          2019-12-24T03:46:42Zquotaspecbindings.config.istio.io         2019-12-24T03:46:42Zquotaspecs.config.istio.io                2019-12-24T03:46:42Zrbacconfigs.rbac.istio.io                 2019-12-24T03:46:42Zrules.config.istio.io                     2019-12-24T03:46:42Zserviceentries.networking.istio.io        2019-12-24T03:46:42Zservicerolebindings.rbac.istio.io         2019-12-24T03:46:42Zserviceroles.rbac.istio.io                2019-12-24T03:46:42Zsidecars.networking.istio.io              2019-12-24T03:46:42Ztemplates.config.istio.io                 2019-12-24T03:46:42Zvirtualservices.networking.istio.io       2019-12-24T03:46:42Z

而 App Mesh 就简单得多,只针对核心概念添加了如下 3 个 crd,用一个 controller 进行管理。

复制代码

$ kubectl get crd -nappmesh-systemNAME                               CREATED ATmeshes.appmesh.k8s.aws             2019-12-13T05:35:00Zvirtualnodes.appmesh.k8s.aws       2019-12-13T05:35:00Zvirtualservices.appmesh.k8s.aws    2019-12-13T05:35:00Z

尽管 Istio 更多的 crd 在一定程度上代表了更加丰富的功能,但同时也为维护和 troubleshooting 增加了困难。

流量控制

尽管两者的数据平面都基于 Envoy,但它们提供的流量控制能力目前还是有比较大的差距的。在路由的设置方面,App Mesh 提供了相对比较丰富的匹配策略,基本能满足大部分使用场景。下面是 App Mesh 控制台里的路由配置截图,可以看出,除了基本的 URI 前缀、HTTP Method 和 Scheme 外,也支持请求头的匹配。

Service Mesh 浅析:从概念、产品到实践

下图是网格内部的逻辑视图,展示了如何利用 App Mesh 进行智能路由。Forecast service 作为调用者被定义为虚拟节点,Data service 作为虚拟服务,挂载着虚拟路由,内部根据需要可以设定若干路由规则。用 App Mesh 实现一个金丝雀发布的过程非常简单:假设在 Data service 的新版本(V2)发布前,流量都被指向 V1 版本;此时我们在 App Mesh 里配置好一个新的路由规则,将 10% 的流量指向新的 V2 版本;只需要将新的规则通过 kubectl apply -f new-rule.yaml 应用到集群中,金丝雀发布就可以完成,且无缝切换,对用户透明。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注