Service Mesh 基础理论与深入剖析

什么是 Service Mesh?

首先解释一下 Service Mesh 这个词,这确实是一个非常非常新的名词。如同之前调查的,大部分的同学都没听过。

这个词最早使用由开发 Linkerd 的 Buoyant 公司提出,并在内部使用。2016 年 9 月 29 日第一次公开使用这个术语。2017 年的时候随着 Linkerd 的传入,Service Mesh 进入国内技术社区的视野。最早翻译为“服务啮合层”,这个词比较拗口。用了几个月之后改成了服务网格。

根据Linkerd CEO William Morgan定义,Service Mesh是用于处理服务间通信的基础设施层,用于在云原生应用复杂的服务拓扑中实现可靠的请求传递。在实践中,Service Mesh通常是一组与应用一起部署,但对应用透明的轻量级网络代理。

Service Mesh 基础理论与深入剖析

Service Mesh与传统基础设施层不同之处在于,它形成了一个分布式的互连代理网络,以sidecar形式部署在服务两侧,服务对于代理无感知,且服务间所有通信都由代理进行路由。

Service Mesh 基础理论与深入剖析

什么需要Service Mesh?

“Smart endpoint and dumb pipes”是微服务架构在集成服务时采用的一个核心理念,这一理念改变了过去臃肿集中的ESB(企业服务总线),无疑是正确方向上的一大进步,但同时也给我们出了一些难题——多智能才不会过于智能,而服务轻重大小的程度如何拿捏?我们应该如何处理微服务系统中服务间交互的复杂性?放在服务内部还是外部?如果是内部,如何处理业务逻辑关系,或者应该与基础设施更为相关?如果是外部,如何避免重蹈ESB的覆辙?

首先,先来看看处理服务间通信时需要关注的点:

  • 服务发现
  • 负载均衡
  • 路由
  • 流量控制
  • 通信可靠性
  • 弹性
  • 安全
  • 监控/日志

存在于任何需要处理网络的分布式系统之中,区别在于,当所涉及微服务数量呈指数级增加,这些问题也会被相应放大。

一个已经被广泛应用的解决方案是利用api网关来处理服务外部和服务之间的请求,提供例如服务发现、路由、监控、流量控制等。

然而,api网关有一个比较致命的缺陷,它容易出现单点故障并且实践不当很有可能会变得异常臃肿。另一方面,api网关核心是面向用户,也就是说它可以解决从用户到微服务的流量问题,但不能解决所有问题,而我们需要的是一个完整的方案,或者至少是一些能够与api网关互补的方案和工具。

另一种选择是在网络堆栈的较低层级(4/3)进行可靠性、监控、流量控制等方面处理。这种选择的问题是,在较低较低的操作难易满足应用层的问题。联想end-to-end(端到端)的理论,我们前面提到的那几个关注点实际上还是集中在应用层,也只能在应用层成功实现。

像Netflix、Twitter等SOA/微服务的早期采用者,他们通过建立内部库的方式处理这些问题,然后提供给所有服务使用。这种方法的问题在于,把库扩展到成百上千个微服务中难度极高,而且这些库相对来说是比较”脆弱“的,我们很难保证他们可以适应所有的技术堆栈选择。

程度上来说,Service Mesh与这些库很类似,但Service Mesh是与服务相邻的

独立进程。服务连接到代理,代理反过来又与其他代理(HTTP_1.1/2、GRPC)进行通信。它们是相对独立的进程,在应用层或应用层之下分布和运行,进而解决了上述两个方案存在的缺陷

Service Mesh架构

Service Mesh由data plane构成,其中所有服务通过sidecar代理进行服务通信。(所有代理相互连接形成一个Mesh,Service Mesh由此得名)网格同时包含一个control plane——可以将所有独立的sidecar代理连接到一个分布式网络中,并设置网格还包括一个控制平面——它将所有独立的sidecar代理连接到一个分布式网络中,并设置由data plane指定的策略。

Service Mesh 基础理论与深入剖析

Control plane定义服务发现、路由、流量控制等策略。这些策略可以是全局的,也可以是限定的。Data plane负责在通信时应用和执行这些策略。

  • 每个微服务导入的library
  • 在特定节点提供服务给所有容器的节点agent
  • 与应用程序容器一起运行的sidecar容器

基于sidecar的模式目前是service mesh最受欢迎的模式之一,以至于它在某种程度上已经成为了service mesh的代名词。尽管这种说法并不严谨,但是sidecar已经引起了很大的关注,我们将在下文更详细地研究这一架构。

Service Mesh 基础理论与深入剖析

Service mesh的优势

Service mesh comes with its own terminology for component services and functions:

  • Container orchestration framework. As more and more containers are added to an application’s infrastructure, a separate tool for monitoring and managing the set of containers – a container orchestration framework – becomes essential. Kubernetes seems to have cornered this market, with even its main competitors, Docker Swarm and Mesosphere DC/OS, offering integration with Kubernetes as an alternative.
  • Services and instances (Kubernetes pods). An instance is a single running copy of a microservice. Sometimes the instance is a single container; in Kubernetes, an instance is made up of a small group of interdependent containers (called a pod). Clients rarely access an instance or pod directly; rather they access a service, which is a set of identical instances or pods (replicas) that is scalable and fault‑tolerant.
  • Sidecar proxy. A sidecar proxy runs alongside a single instance or pod. The purpose of the sidecar proxy is to route, or proxy, traffic to and from the container it runs alongside. The sidecar communicates with other sidecar proxies and is managed by the orchestration framework. Many service mesh implementations use a sidecar proxy to intercept and manage all ingress and egress traffic to the instance or pod.
  • Service discovery. When an instance needs to interact with a different service, it needs to find – discover – a healthy, available instance of the other service. Typically, the instance performs a DNS lookup for this purpose. The container orchestration framework keeps a list of instances that are ready to receive requests and provides the interface for DNS queries.
  • Load balancing. Most orchestration frameworks already provide Layer 4 (transport layer) load balancing. A service mesh implements more sophisticated Layer 7 (application layer) load balancing, with richer algorithms and more powerful traffic management. Load‑balancing parameters can be modified via API, making it possible to orchestrate blue‑green or canary deployments.
  • Encryption. The service mesh can encrypt and decrypt requests and responses, removing that burden from each of the services. The service mesh can also improve performance by prioritizing the reuse of existing, persistent connections, which reduces the need for the computationally expensive creation of new ones. The most common implementation for encrypting traffic is mutual TLS (mTLS), where a public key infrastructure (PKI) generates and distributes certificates and keys for use by the sidecar proxies.
  • Authentication and authorization. The service mesh can authorize and authenticate requests made from both outside and within the app, sending only validated requests to instances.
  • Support for the circuit breaker pattern. The service mesh can support the , which isolates unhealthy instances, then gradually brings them back into the healthy instance pool if warranted.

Service mesh和现有技术比较

Service mesh vs Kubernetes

如果你稍微熟悉基于容器的架构,你可能会想Kubernetes这个流行的开源容器编排平台能否适合这种情况。毕竟,Kubernetes不就是管理着你的容器之间如何互相通信的吗?你可将Kubernetes“服务”资源视为非常基础的service mesh,因为它提供服务发现和请求的轮询调度均衡。但是完整的service mesh则提供更丰富的功能,如管理安全策略和加密、“断路”以暂停对缓慢响应的实例的请求以及如上所述的负载均衡等。

请记住,大多数service mesh确实需要像Kubernetes这样的编排系统。Service mesh只是提供扩展功能,而非替代编排平台。

Service mesh vs API 网关

每个微服务都会提供一个API,它会作为其他服务与其通信的手段。这引发了service mesh与其他更传统的API管理形式(如API网关)之间的差异问题。API网关位于一组微服务和“外部”世界之间,它根据需要路由服务请求,以便请求者不需要知道它正在处理基于微服务的应用程序即可完成请求。而service mesh调解微服务应用程序内部的请求,各种组件完全了解其环境。

另一方面,service mesh用于优化集群内东西流量(server-server流量),API网关用于进出集群的南北流量(server-client流量)。但service mesh目前依旧处于早期阶段还在不断发展变化中。许多service mesh(包括Linkerd和Istio)现在已经可以提供南北功能。

三种服务发现模式

服务发现和负载均衡并不是新问题,业界其实已经探索和总结出一些常用的模式,这些模式的核心其实是代理 (Proxy,如下图所以),以及代理在架构中所处的位置。

Service Mesh 基础理论与深入剖析

在服务消费方和服务提供方之间增加一层代理,由代理负责服务发现和负载均衡功能,消费方通过代理间接访问目标服务。根据代理在架构上所处的位置不同,当前业界主要有三种不同的服务发现模式:

模式一:传统集中式代理

Service Mesh 基础理论与深入剖析

这是最简单和传统做法,在服务消费者和生产者之间,代理作为独立一层集中部署,由独立团队 (一般是运维或框架) 负责治理和运维。常用的集中式代理有硬件负载均衡器 (如 F5),或者软件负载均衡器 (如 Nginx),F5(4 层负载)+Nginx(7 层负载) 这种软硬结合两层代理也是业内常见做法,兼顾配置的灵活性 (Nginx 比 F5 易于配置)。

这种方式通常在 DNS 域名服务器的配合下实现服务发现,服务注册 (建立服务域名和 IP 地址之间的映射关系) 一般由运维人员在代理上手工配置,服务消费方仅依赖服务域名,这个域名指向代理,由代理解析目标地址并做负载均衡和调用。

国外知名电商网站 eBay,虽然体量巨大,但其内部的服务发现机制仍然是基于这种传统的集中代理模式,国内公司如携程,也是采用这种模式。

模式二:客户端嵌入式代理

Service Mesh 基础理论与深入剖析

这是很多互联网公司比较流行的一种做法,代理 (包括服务发现和负载均衡逻辑) 以客户库的形式嵌入在应用程序中。这种模式一般需要独立的服务注册中心组件配合,服务启动时自动注册到注册中心并定期报心跳,客户端代理则发现服务并做负载均衡。

Netflix 开源的 Eureka(注册中心)和 Ribbon(客户端代理)[附录 2] 是这种模式的典型案例,国内阿里开源的 Dubbo 也是采用这种模式。

模式三:主机独立进程代理

这种做法是上面两种模式的一个折中,代理既不是独立集中部署,也不嵌入在客户应用程序中,而是作为独立进程部署在每一个主机上,一个主机上的多个消费者应用可以共用这个代理,实现服务发现和负载均衡,如下图所示。这个模式一般也需要独立的服务注册中心组件配合,作用同模式二。

Service Mesh 基础理论与深入剖析

Airbnb 的 SmartStack是这种模式早期实践产品,国内公司唯品会对这种模式也有探索和实践。

比较三种服务发现模式

上面介绍的三种服务发现模式各有优劣,没有绝对的好坏,可以认为是三种不同的架构风格,在不同的公司都有成功实践。下表总结三种服务发现模式的优劣比较。业界案例和适用场景建议,供架构师选型参考:

Service Mesh 基础理论与深入剖析

服务网格 ServiceMesh

所谓的 ServiceMesh,其实本质上就是上面提到的模式三:主机独立进程模式,这个模式其实并不新鲜,业界 (国外的 Airbnb 和国内的唯品会等) 早有实践,那么为什么现在这个概念又流行起来了呢?我认为主要原因如下:

上述模式一和二有一些固有缺陷,模式一相对比较重,有单点问题和性能问题;模式二则有客户端复杂,支持多语言困难,无法集中治理的问题。模式三是模式一和二的折中,弥补了两者的不足,它是纯分布式的,没有单点问题,性能也不错,应用语言栈无关,可以集中治理。

微服务化、多语言和容器化发展的趋势,企业迫切需要一种轻量级的服务发现机制,ServiceMesh 正是迎合这种趋势诞生,当然这还和一些大厂 (如 Google/IBM 等) 的背后推动有关。

模式三 (ServiceMesh) 也被形象称为边车 (Sidecar) 模式,如下图,早期有一些摩托车,除了主驾驶位,还带一个边车位,可以额外坐一个人。在模式三中,业务代码进程 (相当于主驾驶) 共享一个代理 (相当于边车),代理除了负责服务发现和负载均衡,还负责动态路由、容错限流、监控度量和安全日志等功能,这些功能是具体业务无关的,属于跨横切面关注点 (Cross-Cutting Concerns) 范畴。

Service Mesh 基础理论与深入剖析

在新一代的 ServiceMesh 架构中 (下图上方),服务的消费方和提供方主机 (或者容器) 两边都会部署代理 SideCar。ServiceMesh 比较正式的术语也叫数据平面 (DataPlane),与数据平面对应的还有一个独立部署的控制平面 (ControlPlane),用来集中配置和管理数据平面,也可以对接各种服务发现机制 (如 K8S 服务发现)。术语数据平面和控制平面,估计是偏网络 SDN 背景的人提出来的。

Service Mesh 基础理论与深入剖析

每个主机上同时居住了业务逻辑代码 (绿色表示) 和代理 (蓝色表示),服务之间通过代理发现和调用目标服务,形成服务之间的一种网络状依赖关系,控制平面则可以配置这种依赖调用关系,也可以调拨路由流量。如果我们把主机和业务逻辑剥离,就出现一种网格状架构 (上图右下角),服务网格由此得名。

Service Mesh 基础理论与深入剖析


分享到:


相關文章: