什么是ServiceMesh
Service mesh中文名服务网格,最早由Buoyant公司的CEO Willian Morgan提出(2016年)是一个专门用于处理服务之间通信的基础设施层,主要来解决应用微服务化后应用治理问题。
特点
- 基础设施:完全根应用分离服务治理下沉到基础设施层;
- 透明无侵入:以sidecar模式插入轻量级的透明网络代理,应用程序间通讯的中间;
Service mesh能做什么?优缺点?
当传统的单体架构不能满足日益增涨的功能需求,我们需要将应用模块拆分应用架构调整转向微服务架构;微服务能极大的提高应用的灵活性和伸缩性,但同时带来一些新的问题
- 服务调用链路增长,出现问题时跟踪和分析难度加大;
- 不同服务之前存在互相交互,需要更好控制和协调能力;
- 拆分了多个服务,需要将工作流分担到多个模块上;
- 当一个服务模块出现问题时,能尽量不影响其他不影响其他服务模块;
所以我们需要一个微服务治理的东西,来解决引入微服务后所带来的问题。
SpringCloud顺势登场 ,Spring Cloud出自Pivotal公司,它整合了Netflix OSS套件,开发人员写代码时只需要去使用对应的SDK ,就可以实现服务注册、服务发现、负载均衡、熔断等功能。
SpringCloud缺点:
- 组件繁多,学习成本很高(用户需求不是掌握和精通各类微服务框架,而是开发微服务应用。实现应用治理);
- 服务治理功能不全;
- 代码侵入性强;
- 可维护性差(升级需要重新编译);
- 只支持JAVA语言不支持其他编程语言;
Service mesh作用:
- 服务模块链路追踪
- 流量负载均衡
- 服务熔断机制
- 动态路由
- 微服务之间安全加密通信
- 流量控制
…
主要解决应用微服务化后,应用治理问题。
优点:
- 透明代理代码无侵入;
- 不绑定编程语言,支持多种编程语言;
- 与代码解耦,可单独维护和升级;
- 云原生,完美兼容Kubernetes和其他云原生应用;
- 将之前通过代码和封装的类实现的功能,抽象出来下降变成了基础设施层,这样做的好处是,开发者可以专注写代码而不用关心服务模块之间治理。
缺点:
- 性能问题,通过sidecar调用,多了层转发;
- 学习成本,功能繁多,学习成本高;
- 运维成本,经过多次转发出现问题后排查后更复杂;
Service mesh功能的实现
Service mesh通过sidecar方式(车斗),Sidecar 作为一个单独的进程与业务服务部署在一起,在Kubernetes中部署在同一个POD中,不同container,共享网络栈。对应用来说它是透明的,所有的流量都会通过它,所以对应用程序流量的控制都可以在控制平面下发,在数据平面的sidecar中实现。
大量服务互相调用访问时,它们之间的连接关系就形成了一个网格;
sidecar方式和微服务框架SDK方式优缺点对比
特性 | SDK | sidecar |
---|---|---|
代码侵入性 | 需要修改代码,使用对应的类 | 透明代理方式,对应用无感知 |
多开发语言支持 | 只支持SDK支持的语言,比如springcloud只支持java | 支持多种编程语言 |
学习成本 | 成熟的微服务框架,文档丰富 | 服务治理,下层到基础设施,运维学习成本高 |
性能 | 代码层接入,性能好,基本上没有性能损耗 | 多了层透明代理转发,性能相对更差 |
Service mesh的演进史
Linkerd
https://github.com/linkerd/linkerd
Buoyant公司产品,scale语言编写运行于JVM,底层是基于Twitter的Finagle库做扩展,2016年发布最早一个0.0.7版本也是业内最早将Service mesh概念实现的产品,linkerd算是数据面产品,控制面由Namerd实现。
2016年1月15日,发布第一个0.07版本,
2017年1月23日,Linkerd加入CNCF,
2017年4月25日,Linkerd1.0版本发布
2017 年 4 月 25 日,Linkerd 1.0 版本发布
2017 年 7 月 11 日,Linkerd 发布版本 1.1.1,宣布和 Istio 项目集成,做istio数据面
最早的Service mesh实现,随后因为scale语言编写运行于JVM的性能问题和和缺少控制平面敌不过基于istio被放弃,转而用Rust开发Conduit。
Conduit
Conduit
https://github.com/linkerd/linkerd2
Buoyant公司产品,采用Rust+go语言编写,2017年12月5日, Conduit诞生 0.1.0版本发布,主要面向Kubernetes。
linkerd原作者抛弃了 Linkerd, 使用Rust重新编写了sidecar, conduit 各方面的设计理念与 Istio 非常类似,分外控制面和数据面控制面。数据面叫做 Conduit Data Plane由Rust语言编写,控制面则由Go编写叫Conduit Control Plane。
Conduit的优势在于整个数据平面采用Rust语编写,非常轻量级和占用资源极低。
2017年12月5日,发布第一个0.1.0版本;
2018年7月6日,发布0.5版本,宣布这将是Conduit的最后一个版本,将合并到Linkerd2;
Envoy
https://github.com/envoyproxy/envoy
Lyft公司2016年9月开源的高性能网络代理采用C++语言编写,业内第二个开源的Service mesh产品,根linkerd1.0一样也是一个数据平面产品,
2016年9月13日,发布第一个1.0.0版本
2017年9月14日,Envoy加入CNCF
2016年中,istio诞生google、IBM、lyft联手开始istio项目,lyft以贡献envoy的方式加入。
Istio
https://github.com/istio/istio
google联合IBM和Lyft发布istio,控制面采用go语言编写,数据面采用C++语言编写的Envoy实现。
2016年中,Istio诞生
2017年5月24日,第一个0.1.0产品发布
2018年7月31日,Istio1.0 release版本发布,可正式生产用
在社区热度
连接:通过简单规则配置可以进行流量细粒度控制、设置负载均衡、熔断、灰度发布、重试;
安全:服务间的通信加密、认证;
控制:服务通信的速率限制;
观测:分布式链路追踪,服务监控指标收集;
Istio 是独立于平台的,可以运行在各种环境中,包括跨云、内部部署、Kubernetes、Mesos 等Istio 目前支持:
在 Kubernetes 上部署的服务;
使用 Consul 注册的服务;
在虚拟机上部署的服务;
Istio架构
分为控制平面和数据平面
控制平面组功能及组件:下发各类策略,同时也收集数据平面返回的一些数据。组件: Pilot、Mixer、Citadel;
数据平面组件功能及组件: 透明proxy(Envoy)劫持应用容器流量,接受控制平面组件指令下发生成对应规则同时将采集到部分信息上报到控制平面;
控制平面
Pilot: 负责流量管理和智能路由(AB测试、金丝雀发布)及错误处理(超时、重试、熔断),Pilot会从k8s中读取服务信息,完成服务发现,Pilot会将用户和配置将网络流量管理请求下发到全部的sidecar中。
Mixer: 前期调用时条件检查和后期报告汇报,每次服务调用时mixer都需要检测调用者请求是否能正确认证,满足ACL规则,后期还需要收集服务上报的监控和跟踪数据。
Citadel:为服务间提供认证和证书管理,可以让服务自动升级为TLS。
Galleey: 整个控制平面的配置中心同时也负责配置管理和分发。
数据平面
Envoy: 扮演sidecar的功能,协调服务网格中所有服务的出入站流量,并提供服务发现、负载均衡、限流熔断等能力,还可以收集大量与流量相关的性能指标。
Sidecar流量劫持原理
istio会给服务配置一个init container ,这个init container会生成很多对应的iptables规则,然后这些规则会将对应inbound和outbound流量都转发给envoy。
但这种方式有个问题因为iptables采用的是线性匹配即一个数据包过来以线性的方式遍历整个规则集,直到找到匹配的否则退出,这种带来的问题,就是当iptables规则量很大时,性能会急剧下降,因为对应的匹配延时会增加。
所以目前社区也在考虑IPVS的方案,这点根k8s Service模式一样。
Service mesh局势分析