服务网格:从Sidecar到Cluster
服务网格(Service Mesh)的概念于2016年被首次提出[1],并被CNCF列为云原生的代表技术[2]。但是经过了近10年的发展,服务网格似乎并没有得到广泛的使用。
本文回顾了服务网格产生的原因,并且希望说明,Sidecar只是服务网格一种可能的实现方式,并且Sidecar并没有达成服务网格“将应用和流量治理解耦”的最终目标。基于网关集群(可称之为Cluster)的方案可能是服务网格的一种更好的实现方式。
1. 微服务场景的通信需求
微服务是服务网格诞生的主要驱动力。
微服务就是一些协同工作的小而自治的服务[3]。
微服务的主要思想是:将单体程序拆分为多个微服务,从而降低代码复杂度和程序耦合性。

图1 从单体程序到微服务
在微服务架构下,有两个关键问题需要解决:
-
大量的服务如何管理和部署。这个问题已经被K8s解决。
-
服务间如何发现和通信。这个问题引发了服务网格的诞生。

图2 微服务间的通信
2. 基于“注册中心+客户端SDK”的方案
目前业界使用最广泛的微服务通信机制是基于“注册中心+客户端SDK”的方案。在这个方案中,调用方通过注册中心来发现服务实例;调用方和服务实例直接相连,依赖客户端策略实现流量调度。调用方通过集成客户端SDK来获得流量管理的能力。Spring Cloud是这个方案的代表。

图3 基于“注册中心+客户端SDK”的微服务通信机制
这个方案的思路非常简单,但是有明显的短板,主要包括:
-
应用侵入性强,接入成本高。每个应用都需要集成客户端SDK。
-
对于编程语言有限制。客户端SDK是针对特定编程语言的,多种语言的客户端SDK可能会有功能不一致。
-
升级成本高。发布新的功能依赖于客户端SDK的升级。对于一个大的机构来说,可能存在成千上万的应用,完成一次客户端SDK版本的升级需要很大的工作量。
-
流量调度精度不高。针对服务实例的流量调度的效果是大量调用方的客户端SDK共同作用的结果,可控性不强。对于服务实例来说,难以实现精确的限流控制。
-
安全和可观测能力弱。调用在调用方和服务实例之间“点对点”发生,缺乏统一的流量安全卡控点和流量观测点。
3. 服务网格的主要思想
服务网格的主要思想是将服务间通信的功能从应用程序中剥离出来,流量调度、安全、可观测等功能都由服务网格来支持。

图4 服务网格的本质是解耦
服务网格的优势包括:
-
实现了业务逻辑和流量治理逻辑解耦
-
对应用的代码无入侵,接入成本低
-
调度、安全、可观测功能强
服务网格其实是想在微服务通信场景下,再次回答分布式系统中的一个经典问题:在客户端和网络之间,应该如何划分功能。1984年发表的《End-to-End Arguments in System Design》[4] 是这方面的经典论文。
一个比较经典的对比发生在传统电信网络和互联网之间。传统电信网络的方案是网络复杂,客户端简单。而互联网选择的方案是客户端复杂,网络简单。对互联网来说,网络只负责IP报文的路由转发(甚至是不可靠的),其它功能都由客户端来实现。
“注册中心+客户端SDK”和服务网格的差异,本质上也是在客户端和网络之间的功能划分上选择了不同的方向。“注册中心+客户端SDK”的思路是网络(即注册中心)简单,客户端(即客户端SDK)复杂。而服务网格的思路是网络(即服务网格)复杂,客户端简单(针对流量治理不需要任何逻辑)。
对于微服务这个场景,服务网格这种“网络复杂、客户端简单”的选择可能更符合IT架构的发展趋势。云原生技术的目的就是使工程师能够轻松地对系统做出频繁和可预测的重大变更[2]。服务网格作为云原生的代表技术,可以更好的实现以上目的。
4. 基于Sidecar的服务网格
对于服务网格来说,Sidecar是目前使用最广泛的实现方式。这个方案的主要思路是在每个应用实例上部署代理网关(即Sidecar),在代理网关上实现调度、安全、可观测等功能。

图5 基于Sidecar的服务网格
经过作者的调研,并综合相关资料,基于Sidecar的服务网格存在以下问题:
-
Sidecar数量庞大,运维成本高。在容器场景,需要在每个Pod内注入Sidecar
-
Sidecar资源消耗大。经调研,在实际应用场景,每个Pod增加内存消耗约0.2-1GB(甚至2GB),这是一个比较大的资源消耗。
-
Sidecar自身是单点。在某些组织内,要求应用程序能够处理Sidecar故障的情况,这增加了应用程序的实现难度。
-
Sidecar升级成本高。Sidecar方案虽然解决了程序的耦合,但是还存在部署的耦合。升级Sidecar需要重新部署业务Pod。经调研,在实际应用场景,大范围升级Sidecar的周期非常长(数月),甚至是很难推动的。
5. 基于网关集群(Cluster)的服务网格
在实践中,还出现了另外一种形态的服务网格,是基于集中式网关集群的方案。
在这种方案中,代理网关的部署和应用程序完全解耦,由多个代理网关实例形成应用网关集群;对于每个服务,分配独立的域名,域名指向应用网关集群的IP地址。在应用网关集群上实现调度、安全、可观测等功能。

图6 基于应用网关集群(Cluster)的服务网格
和基于Sidecar的方案相比,基于Cluster的方案有如下优势:
-
网关数量少,资源消耗低。在一个有数十万应用实例场景中,基于Cluster的方案只需要几百个网关实例。如果使用Sidecar方案,则需要几十万的网关实例。
-
不存在单点风险。在一个应用网关集群内,每个实例的作用是等同的。单个实例的失效并不会影响网关集群的转发能力。
-
升级成本低。网关的部署和应用程序完全解耦,可以独立升级。
基于Cluster的服务网格方案具有很好的分布可扩展能力。在服务发现方面,这个方案利用了DNS系统的分布式能力,内网Local DNS和内网权威DNS都可以实现分布式部署。对于应用网关集群来说,可以按照需要划分为多个集群,用于支持不同的服务。

图7 基于Cluster的服务网格方案的分布可扩展能力
6. 基于Cluster服务网格的实践落地
基于Cluster的服务网格方案已经在招商银行大规模落地[6]。
在这个案例中,使用BFE[5]搭建应用层网关集群,利用了BFE的“集群化”和“自服务”能力[7],满足了在这个场景下弹性扩展、频繁变更的需要。
基于Cluster的服务网格方案接入了超过10万个应用。实践证明,基于Cluster的服务网格方案实现了资源消耗小、可靠性高、升级成本低等收益。
7. 总结
服务网格的主要目标是实现业务逻辑和流量治理逻辑解耦。基于Sidecar的方案虽然解决了程序的耦合,但是还存在部署的耦合,升级非常困难,并且还存在资源消耗大、运维成本高的问题。
基于Cluster的方案是服务网格的另外一种可能的技术路线。相比基于Sidecar的方案,基于Cluster的方案具有升级成本低、资源消耗小等优势。虽然使用了集中式的网关集群,但基于Cluster的方案也有很强的分布可扩展能力。基于Cluster的方案已经过了大规模的实践验证。
参考文献
[1] Service Mesh的发展历程,https://blog.csdn.net/wang_luwei/article/details/131812473
[2] CNCF Cloud Native Definition,https://github.com/cncf/toc/blob/main/DEFINITION.md
[3] 《微服务设计》,https://baike.baidu.com/item/微服务设计/19846914
[4] End-to-end arguments in system design, https://dl.acm.org/doi/10.1145/357401.357402
[5] BFE开源项目,https://github.com/bfenetworks/bfe
[7] 走向现代化的流量管理
作者简介
章淼,博士,1994年进入清华大学计算机科学与技术系学习,2004年获得博士学位,2004年至2006年在清华大学留校任教,在清华期间曾参与中国第一代核心路由器的研制工作。2012年起在百度工作超过十年,聚焦云网络基础架构的研发工作,是BFE开源项目的发起人。在百度期间积极推动软件工程能力提升,曾担任百度代码规范委员会主席,2021年10月被授予百度代码规范委员会荣誉主席。2022年出版《代码的艺术:用工程思维驱动软件开发》。2023年4月起担任瑛菲网络CEO,聚焦研发面向云和大模型场景的现代化流量管理平台。
更多推荐
所有评论(0)