微服务实践:我们离Service Mesh还有多远

网易云社区2020-01-15 16:28

服务网格(Service Mesh)的横空出世让人眼前一亮,但初期实践者反馈的性能、可落地性等问题让技术决策者变得谨慎。随着社区蓬勃发展、更多大厂的加入,越来越多Service Mesh落地案例开始出现:网易严选业务在接入上线中,一些企业Service Mesh已经进入大促核心链路。那么问题来了:我们离Service Mesh还有多远?
本文由作者授权网易云发布,未经许可,请勿转载!

作者:裴斐,网易杭州研究院云计算技术部工程师


写在前面

网易轻舟微服务团队从2018年初开始对Service Mesh进行研究,从Istio 0.x版本时的不完善,到1.3.x release版本的逐步稳定,再到目前可以支撑网易严选、传媒逐步接入,我们对Service Mesh的认知也从浅入深,从疑虑到笃定。最初更多思考的是“Service Mesh离我们还有多远”,到目前落地期从业务出发产生“我们离Service Mesh还有多远”的思考。本文会以业务Service Mesh演进落地的思路为出发点,力求帮助对这项技术感兴趣的同行对微服务业务Service Mesh落地形成一定的认知。

基本面

业界关于Service Mesh的介绍、布道文章非常多(Istio官网,中文社区),这里不会对Service Mesh基础知识做过多展开介绍,尽量以扼要的方式介绍核心概念、架构、功能的基本面,以便读者尽快熟悉背景。

Service Mesh是什么?

Service Mesh中文译名 服务网格,是用以处理服务与服务之间通信的基础设施层。其最早由Buoyant公司(开发Service Mesh项目Linkerd的公司)提出,并在内部使用。该公司2016年9月29日第一次公开使用这个术语。

Service Mesh功能在于处理服务间通信,职责是实现请求的可靠传递。在实践中,Service Mesh通常由服务与轻量级网络代理(Sidecar,与服务部署在一起)组合而成。Sidecar中文翻译为边车,或者车斗,它在原有的客户端和服务端之间加了一个代理,但对应用程序透明。如下图所示为两个微服务之间通过Sidecar互相调用的情形:


当微服务(Service)集群扩大到一定规模后,就会形成网格状(Mesh),即形成了'Service Mesh'形态:


Service Mesh会接管整个网络,在服务之间转发所有的请求。在这种情况下,业务服务不再负责处理请求的具体逻辑,只负责完成业务处理。服务间通讯的环节就从服务里面剥离出来,呈现出一个抽象的基础设施层。对应的服务间通讯相关的治理功能,如流量路由(根据权重或参数分流、负载均衡、黑白名单)、流量治理(熔断、限流、容错)、请求认证鉴权、调用拓扑等均在下沉的Service Mesh层实现,微服务研发者专注于业务研发本身即可。

Service Mesh核心价值

对于通常的业务微服务而言, Service Mesh所带来的核心价值可以总结为:

微服务基础设施下沉 —— 微服务架构支撑、网络通信、治理等相关能力下沉到基础设施层,业务部门无需投入专人开发与维护,可以有效降低微服务架构下研发与维护成本;
降低升级成本 —— Sidecar支持热升级,降低中间件和技术框架客户端、SDK升级成本;
语言无关 —— 提供多语言服务治理能力;
降低复杂测试、演练成本 —— 降低全链路压测、故障演练成本和业务侵入性。

从功能上讲,以Google、IBM主推的Istio框架为例,其对Service Mesh核心功能表述如下所示:


连接 —— 智能控制服务之间的流量和API调用,进行一系列测试,并通过红/黑部署逐步升级。
保护 —— 通过托管身份验证、授权和服务之间通信加密自动保护服务。
控制 —— 应用策略并确保其执行使得资源在消费者之间公平分配。
观测 —— 通过丰富的自动追踪、监控和记录所有服务,了解正在发生的情况。

核心关注点

核心方案



整体架构说明如下:

1.整体基于Envoy+Istio方案。Istio由Google,IBM和Lyft联合开发,Go语言实现。2017年5月24日0.1 release发布,目前已经有1.3.x release版本发布。其与Kubernetes一脉相承,提供了完整的Service Mesh解决方案。核心组件包括数据面Envoy(https://www.envoyproxy.io/,CNCF第三个毕业项目,云原生数据面事实标准组件,具备高性能和丰富的数据面功能) ,控制面Pilot、Mixer、Citadel、Galley等。
2.数据面以 Envoy Proxy作为代理组件。通过Outbound流量拦截或显示指向Envoy Proxy地址的方式代理发起请求流量,经过Envoy Proxy的服务发现、负载均衡、路由等数据面逻辑后,选择目标服务实例地址进行流量转发;在Inbound流量接收端进行流量拦截(可配置是否拦截),对Inbound流量进行处理后转发至目标服务实例。
3.控制面以 Pilot为核心组件。通过建立与Envoy Proxy双向GRPC连接,实现服务注册信息、服务治理策略的实时下发与同步。其他控制面组件Mixer(策略检查、监控、日志审计等)、Citadel(认证与授权)、Galley(配置检查)可在实际场景中配置关闭。
4.平台开放与扩展主要通过Kubernetes CRD与Mesh Configuration Protocol(简称为MCP,一套标准GRPC协议)。平台默认支持Kubernetes基于ETCD的注册中心机制,可通过MCP机制对接更多诸如Consul、Eureka、ZooKeeper等多注册中心;对服务治理策略的配置可通过定义Kubernetes CRD或实现MCP GRPC服务对接实现。
5.高可用设计主要基于Kubernetes及Istio机制实现。数据面Envoy Proxy以Init-Container方式与业务Container同时启动,Istio提供了Pilot-agent组件实现对Envoy Proxy生命周期、升级的支持,保证Envoy Proxy的高可用。控制面所有Istio组件均由Kubernetes多副本探针机制保证高可用性。

容器化与Service Mesh

在基于Envoy+Istio方案中, 容器化是Service Mesh高效落地的基础。容器化+Kubernetes编排不仅为微服务本身带来灵活部署调度、扩缩容、高可用等诸多能力,对Service Mesh架构下Sidecar注入、生命周期管理、流量拦截、安全管理等也提供了十分重要的特性。简而言之,容器化与Service Mesh具备天生的亲和性。

Service Mesh架构本身并未限定业务微服务本身必须容器化,Istio社区也从未将支持非容器这扇“门”堵死(早期的版本Istio仅对Kubernetes进行了支持),轻舟Service Mesh方案中也提供了对非容器的支持。但 从微服务业务长期规划、Service Mesh核心价值最大化、压缩迁移成本等方面考虑,容器化+Service Mesh一定是微服务业务演进的重要方向。集团内 严选、传媒均已选择了上云+容器化+Service Mesh同步进行的演进规划,轻舟团队也为这两大业务提供了演进接入Service Mesh方案。

注册中心的选择

在基于Envoy+Istio方案下, Kubernetes基于ETCD的注册中心机制是社区注册中心的默认方案。对于其他注册中心,可以通过Istio的MCP机制接入(Consul、Eureka、ZooKeeper等)。

值得注意的是,Service Mesh架构下服务注册、发现与传统服务框架存在较大差异:
传统服务框架下,微服务的注册通常通过服务框架SDK将微服务注册到注册中心,通过SDK中的发现方法从注册中心发现服务与实例列表,即 通过客户端SDK完成注册发现。

在Service Mesh架构下,控制面组件(如Istio Pilot)负责对接注册中心。服务在创建Kubernetes Service、Deployment时会完成自动注册;服务的发现则是由控制面组件拉取或监听注册中心,将获取到的服务与实例信息转换为统一服务模型,再通过GRPC推送到Sidecar,这样Sidecar就获取到了服务与实例信息,即 通过控制面组件完成服务发现。通过控制面组件完成服务发现模式下,控制面组件可以通过实现不同注册中心的适配器,同时获取多种注册中心的服务与实例信息,即 可实现多注册中心服务的互相发现。示意图如下:


虽然Istio Pilot提供了对接多种注册中心能力, Kubernetes基于ETCD的注册中心机制依然是推荐的容器化+Service Mesh下的注册中心选择。原因不仅是这是Kubernetes的原生机制,能力完整性与健壮性强,在实践过程中,通过MCP机制实现各注册中心的对接并不像想象那样平滑:控制面组件对注册中心进行定时拉取或监听,对于不同注册中心会选择不同的策略:如果对接的注册中心没有提供增量式拉取获取监听的机制,控制面组件每次对注册中心全局的信息获取会是巨大的压力(轻舟团队在严选有过对接Consul的实践,终因对Consul服务器可能带来的巨大压力而作罢)。严选、传媒业务原有注册中心均为Consul,在进行容器化+Service Mesh演进时均选择迁移使用Kubernetes基于ETCD的注册中心机制(新老注册中心互相发现方案见后续“平滑迁移”章节)。

平滑迁移

在明确容器化、注册中心两大基本路线后,平滑迁移会是微服务业务演进到Service Mesh的最关键“战役”。纵使Service Mesh有着各种前瞻性的架构与功能特性,尽量少的让业务感知到迁移过程是Service Mesh大规模落地的关键。一般而言,涉及平滑迁移的主要包括业务/框架适配、灰度引流两大部分。

业务/框架适配


符合云原生微服务规范的业务可以自然平滑地尝试接入Service Mesh,这部分介绍可以直接跳过。对于一些没那么“云原生”的已有业务微服务来说,可能需要一些业务/框架的适配,以更好的接入Service Mesh。这里的适配一般是为了符合使用规范的服务调用配置(服务名/地址+path)。

在原生Istio方案下,对目标服务的调用配置需统一 为服务名+path的方式,如调用money-rich服务的getMoney接口,服务调用配置需要是money-rich/api/getMoney,这里还需要Iptables、DNS进行流量拦截的对应支持,以实现将调用流量拦截至Sidecar。轻舟团队对原生方案进行了扩展,支持了Sidecar地址指向的方式,如指向本地Sidecar的调用配置127.0.0.1:8550/money-rich/api/getMoney,这种方式不需要对Iptables或DNS进行修改,提供了相对简单的流量拦截方式,这一特性目前已经应用于严选环境。

适配方法上,如果业务本身需要在容器化过程进行工程改造,服务调用配置可以一起改造掉;如果不希望修改业务代码,可以通过统一框架的升级、引入增强型服务框架(如轻舟微服务框架NSF)来实现。

灰度引流


在业务完成容器化+Service Mesh改造与迁移后,已经可以在容器化服务范围内互相发现、调用、治理策略分发与生效了。但对于大部分线上环境在跑的微服务业务而言,需要逐步将原有流量灰度引流到Service Mesh体系内服务。以轻舟团队为严选提供的云内/云外互访方案为例,如下图所示:


上图中左半部分为业务实现容器化+Service Mesh改造后微服务部署、调用形态,右半部分为业务已有线上业务。在两个环境之间引入了 边缘网关进行跨环境方案代理、服务发现、访问控制。

1.服务间调用灰度引流
即原有云外服务的互相调用,通过服务框架的权重或参数分流功能,引部分服务间调用流量至云内,实现服务间调用灰度引流的测试验证。
2.用户调用灰度引流
即在终端USER访问负载均衡组件处进行灰度引流,如整体方案图中USER访问负载均衡部分。这种方式下同样可以按权重或参数控制用户流量,实现终端用户调用灰度引流的测试验证。

那些声音 —— 兼听则明

声音1:性能问题严重,尚需观望?

自从Istio发布以来,性能问题一直是很多质疑者所诟病的核心问题。一般而言所说的性能问题主要包括两部分:

服务间调用因为两层Sidecar,请求链路多两跳;
1.Istio Mixer V1集中式后端成为性能瓶颈。
2.如下为Istio 1.3版本最新的性能报告:(横轴代表并发连接数,纵轴代表延时ms)


社区性能报告基于两个服务间端到端HTTP协议测试得来:绿线代表端到端测试延时基准曲线,蓝线代表两层Sidecar基准曲线(不通过Mixer),黄线代表两层Sidecar同时开放Mixer的曲线。可以看出: 在中小规模访问时,延时损失可以忽略不计;在大规模访问时( 16并发1000RPS,系统负荷较大)情况来看,请求过两层Sidecar不开启Mixer情况下较基准调用延时增加约2.3ms(即请求链路多两跳带来的延时增加),这个数值在开启Mixer情况下增加到约7.2ms(即Istio Mixer带来约5ms的延时增加)。 注意:这里的数值非绝对值,是业务大规模访问场景时的HTTP协议的参考值。

从上面分析来看,正常负载情况下延时可以忽略;在大规模访问时,带来的延时有些不上不下:既没有做到业务真正无感(比如1ms以内),也没有带来对大部分业务来说算重大的损失(毕竟大部分业务处理本身产生的损耗要远高于10ms)。

为进一步优化大规模访问时Service Mesh带来的延时影响,轻舟团队主要从以下两个方面进行优化跟进:

1.优化网络协议栈,缩短网络路径。目前杭研云计算网络团队已经立项基于SR-IOV、DPDK的优化路线对Service Mesh网络协议栈进行优化,预计可以将延时降低1倍以上。
2.跟进Mixer V2,实现Mixer下沉至Sidecar。Mixer目前版本之所以带来5ms延时,是因为策略检查(如限流、鉴权、配额检查)都需要经过Envoy Proxy -> Mixer服务 -> 策略后端服务的同步链路,相当于所有请求需要经过若干服务处理并返回后才可以调用到真正的目标服务。社区之前也已经意识到这种模式下虽然为扩展后端策略服务提供了便利,但性能上的缺陷促使Mixer V2提上日程。解决思路是在Envoy Proxy提供可多语言实现扩展filter(基于WebAssembly),直接对接到目标策略后端服务。在Mixer V2正式release之前,轻舟团队提供了脱离Mixer的方案,仍然可以实现Mixer带来的Metrics、Trace、Logging功能。但由于Mixer本身并不是必需组件,如果不需要这部分功能的话,业务可以配置不启用Mixer。

声音2:Istio架构复杂,易用性差?

Istio提供了完整的Service Mesh框架,包含服务调用、流量治理、服务治理、遥测(监控,分布式追踪,日志)、安全等,整体上封装了数据面(Envoy Proxy,Pilot-agent)、控制面(Pilot-discovery,Mixer,Citadel,Galley)等诸多服务组件,架构上确实比较复杂,加上Istio为了使服务模型、治理策略、遥测策略等能够具备充分的扩展性,进行了较多抽象,形成了很多概念模型(数量堪比Kubernetes),想要全局理解掌握和直接使用成本偏大。

对应解决方案上,轻舟团队主要从以下两个方面进行优化:

1.轻舟团队在充分理解Istio架构、各组件基础上,突出了以 Envoy Proxy、Pilot为核心组件,其他可按需配置的策略,尽可能降低落地的架构复杂性。
2.提供了较原生CRD或MCP gRPC接口友好的 Service Mesh API平面,以Rest接口方式将Service Mesh核心功能进行封装,方便业务已有系统接入。当然轻舟也提供了产品化的Service Mesh管理系统,以方便业务服务对微服务进行治理策略配置、监控、拓扑查看等。

展望

随着Service Mesh架构的成熟,Service Mesh相关功能、性能及运维配套的完善,集团重点业务的逐步落地,相信会有越来越多的集团业务加入到演进接入中,我们离Service Mesh会越来越近。