CloudOpenShift

Service Mesh简介

本文将对Service Mesh做一个简单介绍。

1 什么是微服务?


要介绍Service Mesh,要先介绍一下微服务。

微服务是构建分布式应用的一种架构方案。微服务中的各个功能作为单独的服务运行。这些单独的服务可以独立更新、扩容,而不会影响到其它服务。

微服务通过构建易扩容的分布式系统,避免集中式数据存储存在的瓶颈。像Amazon和Netflix等公司,已经完成了从单体应用向微服务架构的演化,为业界树立起了容器技术的标准。

2 微服务的好处


微服务的最大好处就是简单。应用一旦被拆分成更小的粒度之后,会变得更加容易构建、优化和维护。微服务架构也会使得代码管理变得更加容易,因为各个微服务可以使用不同的编程语言编写,使用不同的数据库和相关的软件生态,而这些选择则都是根据该微服务所提供的业务特性来决定的。这样的架构在单体应用中是不可想象的,我们没法使用不同的语言来编写同一个单体应用。

微服务的其它好处还包括:

  • 敏捷性。微服务会比单体应用更好地适应敏捷流程。
  • 可扩展性。当业务增长时,微服务很容易进行扩容并满足业务的增长需求。而且往往只需要按需对某些关键的微服务组件进行扩容。
  • CI/CD自动化。微服务更适合自动化的CI/CD流程,针对各个微服务的CI/CD流程会比单体应用简单的多。
  • 使用不同的数据库。各个微服务可以根据自身业务特点使用不同类型的SQL或者NoSQL数据库。

3 什么是容器?


上面提到,对于微服务架构来说,不同的微服务可能使用不同的编程语言编写。在实际部署这些微服务时,运维人员会面临比部署单体应用更复杂的情况。有可能要为微服务A准备JDK环境和相关的依赖库;为微服务B准备Python运行环境和依赖库。另外,假如微服务A和微服务B运行在同一台虚拟机上,微服务A如果因为某个Bug把内存耗尽,可能会导致微服务B也跟着挂掉。

容器是一种可以让应用在不同的运行环境之间进行迁移的有效手段。容器是一种新的软件交付方式,它把应用和其运行环境以一个标准镜像格式打包, 能保证应用及其运行环境的统一。运行该应用所需的所有依赖,比如代码、运行时环境、系统工具、库文件、依赖等,都被打包进了容器。

基于上述特点,目前容器已经成为微服务的主要部署方式。

4 单体应用对比微服务架构


应用程序以前都是被构建成单体应用的。单体应用有比较长的生命周期,更新频率相对较低,而且改动往往会影响整个系统。单体应用更新所需的高成本和笨拙的流程,使得其难以对市场需求做出快速响应。

微服务则是为了解决这些问题而提出来的,所有服务单独构建、单独发布。微服务架构允许对某些节点按需扩容。

单体应用特点:

  • 应用是一个单一的、集成的软件实例。
  • 应用实例部署在单一的服务器或者虚拟机上。
  • 对功能的更新可能会导致全盘改动。

微服务架构特点:

  • 应用被拆分成子模块。
  • 应用可以分布在不同的数据中心或者云服务上。
  • 对功能的更新只会影响相关的微服务。

5 为什么微服务需要Service Mesh?


微服务程序往往需要一系列的基础服务,比如负载均衡、服务发现、流量控制、路由、健康状态监控、安全策略、用户/应用授权、预防各种入侵和Dos攻击等等。我们以负载均衡和服务发现为例,来说明下目前业界解决这类问题的几种主要手段。

5.1 Proxy代理模式

在微服务的提供方和消费方之间,由基础设施团队提供一个统一的代理服务负责微服务的服务发现和负载均衡。

这种模式下,微服务的注册、发现和调用过程往往涉及:

  1. 客户端使用域名来调用各个微服务,域名被解析后,会由代理内部的路由机制将请求路由到该微服务的各个实例。
  2. 微服务的注册过程,亦即在代理中建立域名和微服务实例ip地址映射的相关工作,一般由基础设施团队提供的软件或者手工完成。

很多大公司目前都采用这种模式,其中最具代表性的当属ebay。

该模式的优点:

  1. 运维简单,提供集中式的proxy。
  2. 无需专门的服务注册和发现组件。
  3. 服务调用方可以使用不同编程语言,只需要按照约定的协议(http、rpc)通过域名访问即可。

缺点:

  1. 使用域名访问,需要做一次DNS解析,所以客户端其实需要做两次请求,第一次用域名,第二次用IP。
  2. proxy是一个关键节点,存在单点故障,如果挂了整个系统就挂了。

5.2 客户端嵌入式代理模式

该模式是目前最流行的做法之一,大家所熟悉的Spring Cloud + Eureka/Zookeeper或者Dubbo都是这种模式。

微服务启动之后,会自动到服务注册中心比如Eureka/Zookeeper上注册,然后服务注册中心会将新的服务信息推送给服务消费方。服务消费方往往会在本地缓存所有微服务信息(比如微服务名称、ip和端口等信息),便于直接在客户端本地做负载均衡,常见的负载均衡方式包括轮询、随机等机制。这种模式下,新上线的微服务实例信息会被推送到客户端,请求时针对同一个微服务下多个微服务实例的负载均衡也发生在客户端。

5.3 主机独立进程代理模式

在该模式下,负载均衡和服务发现等功能作为一个单独的进程部署。

相交于proxy代理模式和客户端嵌入式代理模式,主机独立进程代理模式可以避免proxy代理模式的单点故障和性能问题,也可以避免客户端嵌入式代理模式的复杂性,无法支持多语言等问题。为微服务架构提供了一个分布式、无单点故障、跨编程语言的基础服务方案。

上面提到的主机独立进程代理模式就是Service Mesh的一种部署方式。通过部署在容器中的代理,来提供负载均衡、服务发现、流量控制、路由、健康状态监控、安全策略、用户/应用授权、预防各种入侵和Dos攻击等各种基础服务。各代理会作为容器之间、集群之间交互的网关,它们接收本地微服务客户端的请求并将请求路由至微服务实例所在的容器节点,这种方式最终形成了一张通信网格,这就是”Mesh”一词的由来。

6 Service Mesh如何工作?


上面提到,Service Mesh的proxy会作为单独的进程进行部署。其部署方式分为如下几类:

  • 每台主机一个服务代理。服务集群中的每一台主机上都部署了各自的代理,该主机上的所有应用共享这个代理来发起对其它主机上微服务的访问。
  • 每一个应用一个服务代理。每一个应用有其自己的服务代理,该应用的所有实例通过这个服务代理来发起对其它微服务的访问。
  • 每一个容器一个服务代理。亦即每一个应用实例一个服务代理。

7 Service Mesh提供的主要功能


7.1 流量管控

对微服务之间的调用流量做智能控制。能够实现灰度升级、AB 测试和红黑部署等功能。具体来说包括:

  • 包含DNS服务、黑名单/白名单和流量管控的入口网关。
  • 基于第四到第七层网络的,支持SSL、TLS的负载均衡功能。
  • 微服务自动发现和应用自动映射,帮助客户端发现新的微服务实例。

7.2 安全

为微服务之间的调用提供认证、授权和加密。具体来说包括:

  • Zero trust安全模型和加密。
  • 支持企业级认证和授权的SSO。
  • 分布式的WAF支持。更多关于WAF的介绍,请参考笔者的另外一篇文章Web应用防火墙WAF简介

7.3 可观测性

对于Service Mesh来说,可观测性非常重要。对于很多企业来说,从单体应用向微服务的改造过程都是逐步推进的。在这个过程当中,除了微服务之前会有相互调用,微服务和遗留的单体应用之间也可能会存在调用关系。Service Mesh需要能够观测到这些调用并且在发生错误时能清楚定位问题。

可观测性具体来说包括:

  • 应用和容器的实时监控和追踪。
  • 大数据驱动的日志分析。
  • 基于机器学习的应用健康状态分析。

8 你可能会听到的几种Service Mesh


Istio Service Mesh

Istio是Lyft、IBM和Google于2017年合作开发的一款开源Service Mesh框架。Istio默认和Envoy一起搭配使用,提供了一个统一的底层服务代理的管理方式。

AWS App Mesh

AWS App Mesh基于Envoy代理实现。它允许开发人员标准化微服务的通信方式、实现微服务之间的通信规则,并将指标、日志和跟踪信息直接捕获到AWS服务和第三方工具中。App Mesh实际上是由AWS托管的Envoy控制平台,Envoy是一个开源的服务网格数据代理。App Mesh目前可用于Amazon Elastic Container Service(ECS)、Amazon Elastic Container Service for Kubernetes(EKS)和EC2上的Kubernetes。

Google Service Mesh

Google Service Mesh也叫做GCP(Google Cloud Platform) Service Mesh。GCP其实是基于Istio实现的,它是作为云平台服务的一部分,被自动安装到Kubernetes引擎上的。

Envoy Service Mesh

Envoy是Lyft在2016年启动的一个开源Service Mesh项目。是一个面向服务架构的高性能网络代理,由C++语言实现。

Kubernetes Service Mesh

有很多种不同的Kubernetes Service Mesh提供方,Istio是其中最为出名的一个。Istio一般是当一家公司决定采用基于Kubernetes的容器化方案时使用的Service Mesh方案。其它Kubernetes Service Mesh还包括Linkerd和Consul。

Azure Service Mesh

由微软提供的一个可高度扩展的分布式系统平台,最大的特点是可以管理基于Windows和Linux的微服务和容器。

Conduit Service Mesh

Conduit是Buoyant于2017年开始的一个开源项目。Conduit的目的是为了优化Kubernetes的用户体验。Conduit包含了一个由Rust编写的数据面板和一个Go编写的控制面板。最大的特点是容易理解和使用。

Red Hat OpenShift Service Mesh

Red Hat OpenShift Service Mesh基于Istio项目开发而成。其最大特点是对于业务代码的无侵入性,可以在无需对业务代码进行修改的情况下为分布式应用添加服务代理。

LinkerD Service Mesh

Linkerd的最大功劳在于它让Service Mesh这个词流行起来。它是Buoyant于2016年开发的一个开源项目。Linkerd基于Twitter的Finagle库,由Scala语言编写。