What`s a service mesh?And why do I need one?
service mesh 是云原生应用体系中独立的专用的基础层,用于提供安全、快速、可靠的服务间通讯。过去的几年里,service mesh 已发展成云原生应用体系中至关重要的组件,高流量公司如Paypal、Ticketmaster、Credit Karma都已经将service mesh应用到其生产环境中,而 Linkerd 也成为了(2017年)Cloud Native Computing Foundation 的官方项目。
什么是service mesh
service mesh是负责服务到服务通讯的基础层,负责在现代复杂的云原生系统中可靠地传递服务间的请求。在实际实现中,service mesh 通常以一组轻量的网络代理的形式出现,这些代理部署在应用侧,被代理服务无须知晓这些代理的存在。
service mesh 是随者云原生系统而发展的,在云原生模型,一个应用可能由数百个服务组成,每个服务又可能拥有数千个实例,而基于K8s 这类框架的调度,这些服务实例的状态处于持续变化的状态。在这样的情况下,服务间通讯变得异常复杂,但是服务间通讯又是应用运行的基础保障,因此,服务间通讯的管理是端到端性能和可靠性是非常重要的。
Service Mesh产生的原因
1、微服务内容多门槛高,springcloud 技术栈很多,开发团队需要很长时间才能熟练掌握
2、业务开发团队的强项往往不在于技术,而是对业务的理解。业务开发团队往往承受极大的业务压力,时间人力永远不足。说下月上线就是下月上线,说双十一促销就不会推到双十二。老板是不会管你有没有时间学习spring cloud的,也不会管你的业务团队能否搞得定微服务的方方面面。业务永远看的是结果。
3、服务治理功能不够齐全:需要投入很多时间和精力进去。
4、Dubbo for Python、 Dubbo for rust、Dubbo for go 需要提供不同的跨语言类库和框架。
5、版本升级无法要求所有的应用者都升级。设想一下框架的Java1.0客户端访问node.js的3.0的服务器端会发生什么事情,C++的2.0客户端访问golang的1.0服务器端会如何?你想把所有的兼容性测试都做一遍吗?这种情况下你的兼容性测试需要写多少个Case,这几乎是不可能的。
Service mesh 是网络模型吗
service mesh 是TCP/IP上的抽象层,它假设已经具备底层的L3/L4网络,并且能够在点到点之间传递数据,同时,它也假设网络是不可靠的,因此service mesh必须能够处理网络异常。
从某些角度来看,service mesh于TCP/IP很相似,如TCP抽象了在网络节点之间能够可靠传输数据,service mesh 保证了服务节点间请求的可靠传输。其次,如TCP一般,service mesh不关系负载的内容与负载的编码格式,它只负责完成自己的任务:将请求从A发送给B,若发生异常,则处理异常。
与TCP不同的是,service mesh不仅仅是“仅仅使其工作起来”,除了可靠传输请求,它还提供透明的、统一的对应用运行时的监测与控制,service mesh的目标是,将服务间通信从原先不可见的的基础服务中剥离出来,使得(服务间通信)可被监控、管理和控制。
Service mesh 能做什么
云原生的应用系统中实现请求的可靠传输是相当复杂的,service mesh的出现则是要承担这一复杂的任务。它提供一系列技术:熔断、基于延迟的负载均衡、最终一致的服务发现、重试以及截止线(deadlines),这些技术必须协同工作,同时处理好各项技术之间、与复杂的运行环境之间的微妙交互关系。
以使用Linkerd为例,一次请求的简化版时间线如下:
- Linkerd基于动态路由规则,判定该请求将发送给哪个服务。这个过程,Linkerd需要做如下判断:判定路由该请求至生产还是阶段性服务(in staging)?路由至本地还是远程?最新版本还是测试版本或者更老的服务?所有的这些路由规则都可以动态配置,可以应用到全局或者部分服务上。
- 判定出正确的目标服务后,Linkerd通过(若干)服务发现节点获取到目标服务的实例池,若通过服务发现节点获取的信息与运行时不一致,Linkerd会自动判断使用哪个信息源。
- 基于一系列因素,如延迟,Linkerd从服务实例池中选取可能最快响应的实例。
- Linkerd 尝试向该实例发送请求,并记录延迟与结果。
- 如果因为任何原因请求处理响应失败,在确定请求是幂等的前提下,Linkerd会重试。
- 如果一个服务实例持续响应异常,Linkerd将其从负载均衡池中剔除,但会尝试重连该服务实例。
- 若达到了请求的“死亡线”,Linkerd则判定该次请求失败,而不是持续重试。
- Linkerd 监控以上的所有因素,提供可追踪的度量数据,并发送给度量系统。
Linkerd还可以提供TLS启动/终止、协议升级、动态流量迁移(shift traffic)以及数据中心故障转移等功能。
值得一提的是,Linkerd的这些特性支持点/应用级别弹性(pointwise/application-wide resilience).大型的分布式系统,无论基于何种架构,都有一项特性:给了局部小规模故障很多发展到系统级别灾难性故障的机会。service mesh必须被设计为当某个服务组件快要达到极限时,能通过降低负载和快速失败来防止故障的转移与升级
Service mesh 的必要性
Service mesh并不是什么新功能,而是已有功能的转移。service mesh的发展历程:
传统的中等规模的MVC应用,层与层之间的通讯即使复杂,也在一定的程度内,毕竟是两点通讯,此时还没有mesh的概念。
随者应用规模的膨胀,应用开始进行微服务划分,服务之间的关系开始呈现拓扑结构。此时,通讯层如Finagle, Hystrix,Stubby出现了,但是这些组件都偏“重”。从某种角度,这些组件可看为初代service mesh,然而它们与应用的耦合程度都很高,并且局限特定的语言与框架。
现代的云原生应用体系,除了微服务的特点,还有容器化(如Docker)与服务编排(如 k8s),这三个特点使得云原生应用体系天然支持基于负载的动态扩容与处理局部异常。但是,因为服务编排层持续对数百个服务甚至数千个服务实例的调度,使得请求在服务之间的传递相当复杂,而且容器化的趋势,让多语言编写的服务同时运行在同一环境下越来越常见,因此,通过依赖某一组件来解决服务间通讯问题显得有点力不从心。
云原生应用体系服务间通讯的复杂性与重要性促使了“服务间通讯”从应用层解耦,需要发展曾为独立的基础层,即service mesh。
service mesh 的未来
尽管service mesh在云原生生态系统中发展迅猛,但service mesh仍有广阔的空间需要开拓。在命名与链接(naming and linking)方面,ServiceLess与service mesh天然适配。云原生环境中,服务标识与访问策略(service identity and access policy)仍是非常新的领域,service mesh 在这两个领域将会大展身手。最后,如TCP/IP一般,service mesh最终会发展为云原生体系的基础层。正如Linkerd由Finagle等系统发展而来,service mesh将会从现阶段“通过服务代理”的方式中进化出新的形式。
相关链接:
原文
https://www.infoq.com/news/2018/07/conduit-merges-linkerd2/
https://www.mailgun.com/blog/how-and-why-we-adopted-service-mesh-with-vulcand-and-nginx
https://kinvolk.io/blog/2019/05/performance-benchmark-analysis-of-istio-and-linkerd/
https://kinvolk.io/blog/2019/05/how-the-service-mesh-interface-smi-fits-into-the-kubernetes-landscape/
