Service Mesh

1991/6/26 面试

# Service Mesh(服务网格)

Service Mesh是专用的基础设施层,轻量级高性能网络代理。提供安全的、快速的、可靠地服务间通讯,与实际应用部署一起,但对应用透明。

为了帮助理解, 下图展示了服务网格的典型边车部署方式:

图中应用作为服务的发起方,只需要用最简单的方式将请求发送给本地的服务网格代理,然后网格代理会进行后续的操作,如服务发现,负载均衡,最后将请求转发给目标服务。当有大量服务相互调用时,它们之间的服务调用关系就会形成网格,如下图所示:

在上图中绿色方块为服务,蓝色方块为边车部署的服务网格,蓝色线条为服务间通讯。可以看到蓝色的方块和线条组成了整个网格,我们将这个图片旋转90°,就更加明显了:服务网格呈现出一个完整的支撑态势,将所有的服务”架”在网格之上:

服务网格的细节我们今天不详细展开, 详细内容大家可以参考网上资料。或者稍后我将会推出一个服务网格的专题,单独深入介绍服务网格。

# Istio介绍

Istio是Google/IBM/Lyft联合开发的开源项目,2017年5月发布第一个release 0.1.0, 官方定义为:

Istio:一个连接,管理和保护微服务的开放平台。

Istio提供一种简单的方式来建立已部署的服务的网络,具备负载均衡,服务到服务认证,监控等等功能,而不需要改动任何服务代码。

简单的说,有了Istio,你的服务就不再需要任何微服务开发框架(典型如Spring Cloud,Dubbo),也不再需要自己动手实现各种复杂的服务治理的功能(很多是Spring Cloud和Dubbo也不能提供的,需要自己动手)。只要服务的客户端和服务器可以进行简单的直接网络访问,就可以通过将网络层委托给Istio,从而获得一系列的完备功能。

可以近似的理解为:Istio = 微服务框架 + 服务治理

# Istio的关键功能

  • HTTP/1.1,HTTP/2,gRPC和TCP流量的自动区域感知负载平衡和故障切换。

  • 通过丰富的路由规则,容错和故障注入,对流行为的细粒度控制。

  • 支持访问控制,速率限制和配额的可插拔策略层和配置API。

  • 集群内所有流量的自动量度,日志和跟踪,包括集群入口和出口。

  • 安全的服务到服务身份验证,在集群中的服务之间具有强大的身份标识。 这些特性在稍后的架构章节时会有介绍。

# Istio能做什么?

stio力图解决前面列出的微服务实施后需要面对的问题。Istio 首先是一个服务网络,但是Istio又不仅仅是服务网格: 在 Linkerd, Envoy 这样的典型服务网格之上,Istio提供了一个完整的解决方案,为整个服务网格提供行为洞察和操作控制,以满足微服务应用程序的多样化需求。

Istio在服务网络中统一提供了许多关键功能(以下内容来自官方文档):

  • 流量管理:控制服务之间的流量和API调用的流向,使得调用更可靠,并使网络在恶劣情况下更加健壮。
  • 可观察性:了解服务之间的依赖关系,以及它们之间流量的本质和流向,从而提供快速识别问题的能力。
  • 策略执行:将组织策略应用于服务之间的互动,确保访问策略得以执行,资源在消费者之间良好分配。策略的更改是通过配置网格而不是修改应用程序代码。
  • 服务身份和安全:为网格中的服务提供可验证身份,并提供保护服务流量的能力,使其可以在不同可信度的网络上流转。

除此之外,Istio针对可扩展性进行了设计,以满足不同的部署需要:

  • 平台支持:Istio旨在在各种环境中运行,包括跨云, 预置,Kubernetes,Mesos等。最初专注于Kubernetes,但很快将支持其他环境。
  • 集成和定制:策略执行组件可以扩展和定制,以便与现有的ACL,日志,监控,配额,审核等解决方案集成。

这些功能极大的减少了应用程序代码,底层平台和策略之间的耦合,使微服务更容易实现。

# 整体架构

Istio服务网格逻辑上分为数据面板和控制面板。

数据面板由一组智能代理(Envoy)组成,代理部署为边车,调解和控制微服务之间所有的网络通信。

控制面板负责管理和配置代理来路由流量,以及在运行时执行策略。

下图为Istio的架构详细分解图:

这是宏观视图,可以更形象的展示Istio两个面板的功能和合作:

以下分别介绍 Istio 中的主要模块 Envoy/Mixer/Pilot/Auth。

# 1、Envory

Istio 使用Envoy代理的扩展版本,Envoy是以C++开发的高性能代理,用于调解服务网格中所有服务的所有入站和出站流量。

Istio利用了Envoy的许多内置功能,例如动态服务发现,负载均衡,TLS termination,HTTP/2&gRPC代理,熔断器,健康检查,基于百分比流量拆分的分段推出,故障注入和丰富的metrics。

Envoy实现了过滤和路由、服务发现、健康检查,提供了具有弹性的负载均衡。它在安全上支持TLS,在通信方面支持gRPC。

概括说,Envoy提供的是服务间网络通讯的能力,包括(以下均可支持TLS):

  • HTTP/1.1
  • HTTP/2
  • gRPC
  • TCP 以及网络通讯直接相关的功能:
  • 服务发现:从Pilot得到服务发现信息
  • 过滤
  • 负载均衡
  • 健康检查
  • 执行路由规则(Rule): 规则来自Polit,包括路由和目的地策略
  • 加密和认证: TLS certs来自 Istio-Auth 此外, Envoy 也吐出各种数据给Mixer:
  • Metrics
  • Logging
  • Distribution Trace: 目前支持 Zipkin

总结: Envoy是Istio中负责”干活”的模块,如果将整个Istio体系比喻为一个施工队,那么 Envoy 就是最底层负责搬砖的民工,所有体力活都由Envoy完成。所有需要控制,决策,管理的功能都是其他模块来负责,然后配置给Envoy。

# 2、Pilot

# Pilot的架构

下图是Pilot的架构图:

  • Envoy API负责和Envoy的通讯, 主要是发送服务发现信息和流量控制规则给Envoy

  • Envoy提供服务发现,负载均衡池和路由表的动态更新的API。这些API将Istio和Envoy的实现解耦。(另外,也使得Linkerd之类的其他服务网络实现得以平滑接管Envoy)

  • Polit定了一个抽象模型,以从特定平台细节中解耦,为跨平台提供基础

  • Platform Adapter则是这个抽象模型的现实实现版本, 用于对接外部的不同平台

  • 最后是 Rules API,提供接口给外部调用以管理Pilot,包括命令行工具Istioctl以及未来可能出现的第三方管理界面

# Pilot的功能概述

我们在前面有强调说,Envoy在其中扮演的负责搬砖的民工角色,而指挥Envoy工作的民工头就是Pilot模块。

官方文档中对Pilot的功能描述:

Pilot负责收集和验证配置并将其传播到各种Istio组件。它从Mixer和Envoy中抽取环境特定的实现细节,为他们提供独立于底层平台的用户服务的抽象表示。此外,流量管理规则(即通用4层规则和7层HTTP/gRPC路由规则)可以在运行时通过Pilot进行编程。

每个Envoy实例根据其从Pilot获得的信息以及其负载均衡池中的其他实例的定期健康检查来维护 负载均衡信息,从而允许其在目标实例之间智能分配流量,同时遵循其指定的路由规则。

Pilot负责在Istio服务网格中部署的Envoy实例的生命周期。

  • 请求路由
  • 服务发现和负载均衡
  • 故障处理
  • 故障注入
  • 规则配置

# 流量管理

Istio最核心的功能是流量管理,前面我们看到的数据面板,由Envoy组成的服务网格,将整个服务间通讯和入口/出口请求都承载于其上。

使用Istio的流量管理模型,本质上将流量和基础设施扩展解耦,让运维人员通过Pilot指定它们希望流量遵循什么规则,而不是哪些特定的pod/VM应该接收流量。

对这段话的理解, 可以看下图:假定我们原有服务B,部署在Pod1/2/3上,现在我们部署一个新版本在Pod4在,希望实现切5%的流量到新版本。

如果以基础设施为基础实现上述5%的流量切分,则需要通过某些手段将流量切5%到Pod4这个特定的部署单位,实施时就必须和ServiceB的具体部署还有ServiceA访问ServiceB的特定方式紧密联系在一起. 比如如果两个服务之间是用Nginx做反向代理,则需要增加Pod4的IP作为Upstream,并调整Pod1/2/3/4的权重以实现流量切分。

如果使用Istio的流量管理功能, 由于Envoy组成的服务网络完全在Istio的控制之下,因此要实现上述的流量拆分非常简单. 假定原版本为1.0,新版本为2.0,只要通过Polit 给Envoy发送一个规则:2.0版本5%流量,剩下的给1.0。

这种情况下,我们无需关注2.0版本的部署,也无需改动任何技术设置, 更不需要在业务代码中为此提供任何配置支持和代码修改。一切由 Pilot 和智能Envoy代理搞定。

我们还可以玩的更炫一点, 比如根据请求的内容来源将流量发送到特定版本:

后面我们会介绍如何从请求中提取出User-Agent这样的属性来配合规则进行流量控制。

# 服务规范和实现

Pilot架构中, 最重要的是Abstract Model和Platform Adapter,我们详细介绍。

  • Abstract Model:是对服务网格中”服务”的规范表示, 即定义在istio中什么是服务,这个规范独立于底层平台。
  • Platform Adapter:这里有各种平台的实现,目前主要是Kubernetes,另外最新的0.2版本的代码中出现了Consul和Eureka。 来看一下Pilot 0.2的代码,pilot/platform 目录下:

瞄一眼platform.go:

服务规范的定义在modle/service.go中:

# 3、Mixer

功能概括:Mixer负责在服务网格上执行访问控制和使用策略,并收集Envoy代理和其他服务的遥测数据。

# Mixer的设计背景

我们的系统通常会基于大量的基础设施而构建,这些基础设施的后端服务为业务服务提供各种支持功能。包括访问控制系统,遥测捕获系统,配额执行系统,计费系统等。在传统设计中, 服务直接与这些后端系统集成,容易产生硬耦合。

在Istio中,为了避免应用程序的微服务和基础设施的后端服务之间的耦合,提供了 Mixer 作为两者的通用中介层:

Mixer 设计将策略决策从应用层移出并用配置替代,并在运维人员控制下。应用程序代码不再将应用程序代码与特定后端集成在一起,而是与Mixer进行相当简单的集成,然后 Mixer 负责与后端系统连接。

特别提醒: Mixer不是为了在基础设施后端之上创建一个抽象层或者可移植性层。也不是试图定义一个通用的Logging API,通用的Metric API,通用的计费API等等。

Mixer的设计目标是减少业务系统的复杂性,将策略逻辑从业务的微服务的代码转移到Mixer中, 并且改为让运维人员控制。

# Mixer的功能

Mixer 提供三个核心功能:

  • 前提条件检查。允许服务在响应来自服务消费者的传入请求之前验证一些前提条件。前提条件包括认证,黑白名单,ACL检查等等。
  • 配额管理。使服务能够在多个维度上分配和释放配额。典型例子如限速。
  • 遥测报告。使服务能够上报日志和监控。

在Istio内,Envoy重度依赖Mixer。

# Mixer的适配器

Mixer是高度模块化和可扩展的组件。其中一个关键功能是抽象出不同策略和遥测后端系统的细节,允许Envoy和基于Istio的服务与这些后端无关,从而保持他们的可移植。

Mixer在处理不同基础设施后端的灵活性是通过使用通用插件模型实现的。单个的插件被称为适配器,它们允许Mixer与不同的基础设施后端连接,这些后台可提供核心功能,例如日志,监控,配额,ACL检查等。适配器使Mixer能够暴露一致的API,与使用的后端无关。在运行时通过配置确定确切的适配器套件,并且可以轻松指向新的或定制的基础设施后端。

这个图是官网给的,列出的功能不多,我从Github的代码中抓个图给大家展示一下目前已有的Mixer Adapter:

# Mixer的工作方式

Istio使用属性来控制在服务网格中运行的服务的运行时行为。属性是描述入口和出口流量的有名称和类型的元数据片段,以及此流量发生的环境。Istio属性携带特定信息片段,例如:

请求处理过程中,属性由Envoy收集并发送给Mixer,Mixer中根据运维人员设置的配置来处理属性。基于这些属性,Mixer会产生对各种基础设施后端的调用。

Mixer设计有一套强大(也很复杂, 堪称Istio中最复杂的一个部分)的配置模型来配置适配器的工作方式,设计有适配器、切面、属性表达式,选择器、描述符,manifests 等一堆概念.

Mixer的配置示例:

  • 这是一个IP地址检查的Adapter,实现类似黑名单或者白名单的功能:

  • metrics的适配器,将数据报告给Prometheus系统

  • 定义切面, 使用前面定义的 myListChecker 这个adapter 对属性 source.ip 进行黑名单检查。

# 4、Istio-Auth

Istio-Auth提供强大的服务到服务和终端用户认证,使用交互TLS,内置身份和凭据管理。它可用于升级服务网格中的未加密流量,并为运维人员提供基于服务身份而不是网络控制实施策略的能力。

Istio的未来版本将增加细粒度的访问控制和审计,以使用各种访问控制机制(包括基于属性和角色的访问控制以及授权钩子)来控制和监视访问您的服务,API或资源的人员。

# Auth的架构

下图展示Istio Auth架构,其中包括三个组件:身份,密钥管理和通信安全。

在这个例子中, 服务A以服务帐户“foo”运行, 服务B以服务帐户“bar”运行, 他们之间的通讯原来是没有加密的. 但是Istio在不修改代码的情况, 依托Envoy形成的服务网格, 直接在客户端Envoy和服务器端Envoy之间进行通讯加密。

目前在Kubernetes上运行的 Istio,使用Kubernetes service account/服务帐户来识别运行该服务的人员。

# 运行环境支持

Istio目前只支持Kubernetes, 这是令人比较遗憾的一点. 不过 istio 给出的解释是istio未来会支持在各种环境中运行,只是目前在 0.1/0.2 这样的初始阶段暂时专注于Kubernetes,但很快会支持其他环境。

注意: Kubernetes平台,除了原生Kubernetes, 还有诸如 IBM Bluemix Container Service和RedHat OpenShift这样的商业平台。 以及google自家的 Google Container Engine。这是自家的东西, 而且现在k8s/istio/gRPC都已经被划归到 Google cloud platform部门, 自然会优先支持.

另外isito所说的其他环境指的是:

  • Mesos: 这个估计是大多人非K8s的Docker使用者最关心的了, 暂时从Github上的代码中未见到有开工迹象, 但是Istio的文档和官方声明都明显说会支持, 估计还是希望很大的. Cloud foundry: 这个东东我们国内除了私有云外玩的不多, Istio对它的支持似乎已经启动. 比如我看到代码中已经有了Consul这个服务注册的支持, 从Issue讨论上看到是说为上Cloud foundry做准备, 因为Cloud foundry没有k8s那样的原生服务注册机制。
  • VM: 这块没有看到介绍, 但是有看到Istio的讨论中提到会支持容器和非容器的混合(Hybrid)支持