一、服务网格发展历史
1.微服务进化史
1.1微服务发展历史
从服务架构的演绎过程来看,服务架构经历了从单体架构到SOA架构,并到微服务架构的演进。
单体架构:
特点:
- 所有的功能集成在一个项目工程中;
- 应用部署时表现为单进程,应用与数据库分开部署;
- 通过部署应用集群和数据库集群来提高系统的性能。
优点:
- 开发和测试简单,容易部署
缺点:
- 业务复杂后,代码编译构建慢,持续交付困难,伸缩扩容代价大
- 可靠性差,异常出错等问题导致整个项目Down掉;
- 技术栈受限,一般只能使用单种语言框架;
SOA架构:
特点:
- 基于 SOA 的架构思想将重复公用的功能抽取为组件,以服务的形式给各系统提供服务。
- 各项目(系统)与服务之间采用 WebService、RPC 等方式进行通信。
- 使用 ESB 企业服务总线作为项目与服务之间通信的桥梁。
优点:
- 将重复的功能抽取为服务,提高开发效率,提高系统的可重用性、可维护性。
- 可以针对不同服务的特点制定集群及优化方案;
- 采用 ESB 减少系统中的接口耦合。
缺点
- 系统与服务的界限模糊,不利于开发及维护。
- 虽然使用了 ESB,但是服务的接口协议不固定,种类繁多,不利于系统维护。
- 抽取的服务的粒度过大,系统与服务之间耦合性高。
- 涉及多种中间件,对开发人员技术栈要求高。
- 服务关系复杂,运维、测试部署困难
微服务架构
特点:
- 将系统服务层完全独立出来,并将服务层抽取为一个一个的微服务。
- 微服务中每一个服务都对应唯一的业务能力,遵循单一原则。
- 微服务之间采用 RESTful 等轻量协议传输。
优点:
- 团队独立:每个服务都是一个独立的开发团队,这个小团队可以一个Pizza人数(2-5人)的开发人员组成;
- 技术独立:采用去中心化思想,服务之间采用 RESTful 等轻量协议通信,语言和框无关;
- 前后端分离:采用前后端分离开发,提供统一 Rest 接口,后端不用再为 PC、移动端开发不同接口;
- 数据库分离:每个微服务都有自己的存储能力,可以有自己的数据库。也可以有统一数据库;
- 服务拆分粒度更细,有利于资源重复利用,提高开发效率;
- 微服务易于开发人员理解,修改和维护,产品迭代周期更短;
- 可以更加精准的制定每个服务的优化方案(比如扩展),提高系统可维护性;
缺点:
- 微服务将原来的函数式调用改为服务调用,不管是用 rpc,还是 http rest 方式,都会增大系统整体延迟;
- 服务治理难度增大,服务之间的拓扑关系,服务调用链路跟踪等简单的手段无法运维;
- 测试的难度提升。服务和服务之间通过接口来交互,改动测试将复杂化。
1.2微服务面临的挑战
客户端与服务通信
在单体架构中,客户端直接连接后端服务就可以完成通信过程,在微服务架构中,后端存在多个微服务,需要通过API Gateway来完成这个过程。
APIGateway的作用:
- 提供统一服务入口,聚合接口使得服务对调用者透明,客户端与后端的耦合度降低
- 聚合后台服务,节省流量,提高性能,提升用户体验
- 提供安全、流控、过滤、缓存、计费、监控等 API 管理功能
服务间怎么通信
由于服务之间是独立的,服务之间怎么通信,需要通用的通信层要解决,目前业界主要有以下方式 :
- 同步通信:REST(JAX-RS,Spring Boot)、RPC(Dubbo,Thrift)
- 异步通信:RabbitMQ,RocketMQ,Kafka
服务怎么查找
当一个业务存在多个微服务时,如果业务量大增加新增加服务节点,那么这个服务如何被其它服务发现并调用。服务之间如何相互感知?服务如何管理?
目前行业的普遍的做法时把服务注册到服务注册中心上进行管理 ,常见的服务注册中心有Eureka、Nacos、Consul,ZooKeeper。
服务故障怎么处理
当一个服务如果问题时,可能出现级联故障,故障传播,造成整个服务雪崩,此时需要对故障的服务进行降级、熔断等处理手段。常见的组件主要有Hystrix、Sentinel。
1.3 服务治理
SpringCloud是目前比较成熟的微服务治理全家桶方案:
- Eureka:服务注册和发现
- zuul/springcloud gateway:服务网关
- Ribbon:客户端负载均衡
- Hystrix:故障隔离、熔断
- Feign:服务调用
阿里也形成了以Dubbo为基础的微服务技术体系,包括服务注册中心Nacos、隔离熔断Sentinel、分布式事务seata、分布式任务调度SchedulerX等
日志与监控能力,多由独立的组件提供解决方案,如日志ELK,监控Promethues、Skywalking、Zipkin
2.服务网格
过去几年,以Java为主导的SpringCloud/Dubbo框架提供的服务治理能力是代码侵入的,主要支持Java,其它语言像go/nodejs/python等需要定制开发对应的SDK才能享有完整的服务治理能力。
SpringCloud诞生于2015,在2016时,由Twitter工程师初创的Buoyant公司发布了Linkerd项目,结合了Kubernetes的能力,并发表”A Service Mesh For Kubernetes“为题的连载博客进行介绍,Service Mesh正式走进开发者的视线中。2017年,Google、IBM和Envoy的开发公司Lyft发布了Istio项目,并逐步成为SeviceMesh的主导。基于Sidecar的服务治理模式和Kubernetes结合后,呈现出强大的生命力。
ServiceMesh在国内开始翻译为”服务啮合层“,后来才重新翻译为服务网格。国内大的云厂商阿里腾讯华为基于Istio,结合自身的微服务技术栈,纷纷推出自己的服务网格产品。蚂蚁金服的SOFAMesh,在Istio架构基础上,采用自研的MOSN取代了Envoy,并开始在产品上落地。
Sidecar的优势:
将与应用业务逻辑无关的功能抽象到共同基础设施,降低了微服务代码的复杂度。
因为不再需要编写相同的第三方组件配置文件和代码,所以能够降低微服务架构中的代码重复度。
Sidecar 可独立升级,降低应用程序代码和底层平台的耦合度。
二、技术选型
上图是CNCF ServiceMesh技术栈的产品,除了目前有代表性的istio和linkerd外,像老牌的代理Nginx,traefik纷纷入局,Kong推出Kuma,连Consul都想沾点边。
1.Istio
Istio为服务网格解决了什么问题:
Istio 提供了一个完整的解决方案,通过为整个服务网格提供行为洞察和操作控制来满足微服务应用程序的多样化需求。
Istio提供了哪些能力来解决服务网格的痛点问题:
流量管理:Istio 简单的规则配置和流量路由允许您控制服务之间的流量和 API 调用过程。Istio 简化了服务级属性(如熔断器、超时和重试)的配置,并且让它轻而易举的执行重要的任务(如 A/B 测试、金丝雀发布和按流量百分比划分的分阶段发布)。
安全:Istio 提供了底层的安全通信通道,并为大规模的服务通信管理认证、授权和加密。有了 Istio,服务通信在默认情况下就是受保护的。
可观察性:通过 Istio 的监控能力,可以真正的了解到服务的性能是如何影响上游和下游的。
Istio的优势:
通过负载均衡、服务间的身份验证、监控等方法,Istio 可以轻松地创建一个已经部署了服务的网络,而服务的代码只需很少更改甚至无需更改。通过在整个环境中部署一个特殊的 sidecar 代理为服务添加 Istio 的支持,而代理会拦截微服务之间的所有网络通信,然后使用其控制平面的功能来配置和管理 Istio,这包括:
为 HTTP、gRPC、WebSocket 和 TCP 流量自动负载均衡。
通过丰富的路由规则、重试、故障转移和故障注入对流量行为进行细粒度控制。
可插拔的策略层和配置 API,支持访问控制、速率限制和配额。
集群内(包括集群的入口和出口)所有流量的自动化度量、日志记录和追踪。
在具有强大的基于身份验证和授权的集群中实现安全的服务间通信。
2.Linkerd
Linkerd是CNCF的官方项目,基于Twitter的Finagle项目并和后者一样,最初是由Scala语言编写,设计理念是支持基于主机(物理主机或者虚拟节点)的部署模式。由于最初版本的内存占用广受诟病,导致了Conduit项目的开发,Conduit是一个轻量级的服务网格,为Kubernetes定制,用Rust和Go语言编写。Conduit项目目前已经合并到Linkerd项目,并在2018年7月发布为Linkerd 2.0 版本。鉴于Linkerd 2.x 基于Kubernetes,而Linkerd 1.x 可以基于节点的模式部署,当面临复杂环境的场景时,人们可以有更灵活的选择。
架构
控制平面
Linkerd 的控制平面是一组提供了服务网格的核心功能的服务。它聚合了遥测数据、提供面向用户的 API,并为数据平面代理提供控制数据。以下是控制平面的组件:
- 控制器 — 它包含一个公共 API 容器,该容器为 CLI 和仪表盘提供 API。
- 目标 — 数据平面中的每个代理都将访问此组件以查找将请求发送到的位置。它有用于每个路由指标、重试和超时的服务描述信息。
- 身份 — 它提供了一个证书颁发机构,该证书颁发机构接受来自代理的 CSR 并返回以正确身份签发的证书。它提供了 mTLS 功能。
- 代理注入器 — 它是一个准入控制器,用于查找注解(linkerd.io/inject: enabled)并更改 pod 规范以添加 initContainer 和包含代理本身的 sidecar。
- 服务配置文件验证器 — 这也是一个准入控制器,用于在保存新服务描述之前对其进行验证。
- Tap — 它从 CLI 或仪表盘接收实时监控请求和响应的指令,以在应用程序中提供可观察性。
- Web — 提供 Web 仪表盘。
- Grafana — Linkerd 通过 Grafana 提供开箱即用的仪表盘。
- Prometheus — 通过 /metrics 在端口 4191 上代理的断点来收集和存储所有 Linkerd 指标。
数据平面
Linkerd 数据平面由轻量级代理组成,这些轻量级代理作为边车容器与服务容器的每个实例一起部署。在具有特定注解的 Pod 的初始化阶段,将代理注入(请参见上面的代理注入器)。自从 2.x 由 Rust 中完全重写以来,该代理一直非常轻量级和高性能。这些代理拦截与每个 Pod 之间的通信,以提供检测和加密(TLS),而无需更改应用程序代码。
3.Istio与Linkerd比较
Linkerd是CNCF的推荐项目,但Istio在Google、IBM等大厂的强力推进下,后来者居上,在服务网格领域逐步成为标配项目。Istio在控制平面的Mixer设计上曾经被诟病很多,但在1.5版本重构后扭转了局面,直到目前事实成为了控制平面的标准,再加上Envoy作为代理的强大治理能力,Istio基本胜出了。这让人想起Docker Swarm和Kubernetes的容器编排之争。
三、Istio
1. Istio架构
1.1 架构
Istio 服务网格逻辑上分为数据平面和控制平面。
数据平面
数据平面由一组以 sidecar 方式部署的智能代理(Envoy)组成。这些代理可以调节和控制微服务之间所有的网络通信。数据平面的特点:
通常是按照无状态目标设计的,但实际上为了提高流量转发性能,需要缓存一些数据,因此无状态也是有争议的。
直接处理入站和出站数据包,转发、路由、健康检查、负载均衡、认证、鉴权、产生监控数据等。
对应用来说透明,即可以做到无感知部署。
控制平面
控制平面负责管理和配置代理来路由流量。此外控制平面配置 Mixer 以实施策略和收集遥测数据。控制平面的特点:
不直接解析数据包。
与数据平面中的代理通信,下发策略和配置。
负责网络行为的可视化。
通常提供 API 或者命令行工具可用于配置版本化管理,便于持续集成和部署。
1.2 核心概念
- Sidecar( 边 车): Sidecar 自定义资源描述了Sidecar代理的配置,该代理协调与其连接的工作负载实例的入站和出站通信。
- 服务(Service):在服务注册表中的具有唯一名称的应用单位。服务由运行在pod、容器、虚拟机上的工作负载实例实现的多个网络端点组成。
- 服务版本(Service Versions):也称为服务子集(Subsets),在持续部署场景中,灰度发布常用到的术语。
- 源(Source):调用目标服务的下游客户端。
- 主机(Host):客户端在连接服务时的地址
- 访问模型(Access Model): 应用程序在不知道各个服务版本(子集)的情下仅对目标服务( 主机)进行寻址。 版本的实际选择由Sidecar代理确定,使应用程序代码能够脱离依赖服务的演变。
- 虚拟服务(Virtual Service):一个虚拟服务定义了一系列针对指定服务的流量路由规则。每个路由规则都针对特定协议定义流量匹配规则。如果流量符合这些特征,就会根据规则发送到服务注册表中的目标服务(或者目标服务的子集或版本)。
- 目标规则(Destination Rule):目标规则定义了在路由发生后应用于服务的流量的策略。这些规则指定负载均衡的配置,来自Sidecar代理的连接池大小以及异常检测设置,以便从负载均衡池中检测和驱逐不健康的主机。
Kubernetes、xDS、Istio 三者之间的资源抽象对比。
Kubernetes | xDS | Istio 服务网格 |
---|---|---|
Endpoint | Endpoint | WorkloadEntry |
Service | Route | VirtualService |
kube-proxy | Route | DestinationRule |
kube-proxy | Listener | EnvoyFilter |
Ingress | Listener | Gateway |
Service | Cluster | ServiceEntry |
2. Istio组件
2.1 控制平面
从istio1.5 开始,简化了控制平面,将先前由 Pilot,Galley,Citadel 和 sidecar 注入器执行的功能统一为一个二进制文件istiod 。其提供服务发现,配置和证书管理功能。
Pilot 组件
在Istio架构中,Pilot组件属于最核心的组件,负责了服务网格中的流量管理以及控制面和数据面之间的配置下发。Pilot提取了特定于平台的服务发现机制,并将它们合成为标准格式,任何符合Envoy API的Sidecar都可以使用。
目前蚂蚁金服开源的mosn 就可以开箱即用,替代envoy。
Galley 组件
Galley主要提供配置管理的能力,用来验证用户编写的 Istio API 配置。同时,它负责将其他的 Istio 组件与从底层平台(例如 Kubernetes)获取用户配置的细节中隔离开来。
Citadel 组件
负责处理系统上不同服务之间的TLS通信。 Citadel充当证书颁发机构(CA),并生成证书以允许在数据平面中进行安全的mTLS通信。
2.2 数据平面
Envoy 和 pilot-agent 打在同一个镜像中,即Proxy。
Envoy 组件
目前Istio使用Envoy代理的扩展版本。 Envoy是使用C++开发的高性能代理,可为服务网格中的所有服务路由控制所有入站和出站流量。 Envoy代理是与数据平面流量交互的唯一Istio组件。
目前Istio使用的不是Envoy官方版本,不过随着Envoy对于wasm的支持已经merge到了master,也许未来的istio的版本会直接使用官方版本。
Pilot-agent 组件
pilot-agent负责的工作包括:
- 生成envoy的配置
- 启动envoy
- 监控并管理envoy的运行状况,比如envoy出错时pilot-agent负责重启envoy,或者envoy配置变更后reload envoy
istio-init 组件
Istio需要透明拦截服务的进站流量,实现原理为写入iptables,让该 pod 所在的 network namespace 的网络流量转发到 proxy 进程。
默认情况下,Istio在网格中部署的Pod中注入一个initContainer istio-init
。 istio-init容器设置了与Istio Sidecar代理之间的Pod网络流量重定向。这要求该Pod用户或服务帐户,必须具有足够的Kubernetes RBAC权限才能部署具有NET_ADMIN和NET_RAW功能的容器。
3. Istio核心实现原理
3.1 SideCar注入
- Kubernetes 通过 Admission Controller 自动注入,或者用户使用 istioctl 命令手动注入 sidecar 容器。
- 应用 YAML 配置部署应用,此时 Kubernetes API server 接收到的服务创建配置文件中已经包含了 Init 容器及 sidecar proxy。
- 在 sidecar proxy 容器和应用容器启动之前,首先运行init-container,init-container用于设置 iptables(Istio 中默认的流量拦截方式,还可以使用 BPF、IPVS 等方式) 将进入 pod 的流量劫持到 Envoy sidecar proxy。所有 TCP 流量(Envoy 目前只支持 TCP 流量)将被 sidecar 劫持,其他协议的流量将按原来的目的地请求。
- 启动 Pod 中的 Envoy sidecar proxy 和应用程序容器。
- 不论是进入还是从 Pod 发出的 TCP 请求都会被 iptables 劫持,inbound 流量被劫持后经 Inbound Handler 处理后转交给应用程序容器处理,outbound 流量被 iptables 劫持后转交给 Outbound Handler 处理,并确定转发的 upstream 和 Endpoint。
- Sidecar proxy 请求 Pilot 使用 xDS 协议同步 Envoy 配置,其中包括 LDS、EDS、CDS 等,不过为了保证更新的顺序,Envoy 会直接使用 ADS 向 Pilot 请求配置更新。
3.2 流量管理
3.2.1 架构
- Pilot:下发流量规则
- xDS:数据面标准协议
- Sidecar:集群内出入流量
- Ingress gateway:集群外流量入口
- Egress gateway:集群外流量出口
3.2.2 控制面
数据模型
包含两类数据
- 服务数据:包含ServiceEntry和通过CRD定义的数据
- 自定义流量规则:通过CRD定义的流量规则数据
服务发现模型
服务发现的数据来源
- Pilot直接支持K8S的service数据
- ServiceEntry:外部服务可以添加到pilot的注册表
- WorkloadEntry:支持虚拟机服务以workload方式添加
- MCP:适配模式,由第三方服务注册组件实现,如nacos、eureka、consul
pilot与Envoy数据流
Pilot是控制平面和envoy主要通信的组件,包括Discover Service和Agent两部分,其中agent运行在容器pod sidecar内,但是也是属于控制平面的一部分,这两部分共同构成pilot。
Discover Service获取服务信息、流量规则等,envoy通过xDS获取到配置信息修改。
Agent负责envoy的配置管理、生命周期管理,同样也是通过xDS和agent交互。
3.2.3 数据面
数据面以istio官方例子分析
Envoy配置模型&xDS协议&Sidecar配置
Envoy主要概念:
- Downstream:连接到 Envoy 的下游 Host,发送请求并接收响应。
- Upstream: 上游 Host 接收来自 Envoy 的连接和请求,并返回响应。
- Listener:监听器是命名网地址(可以是TCP socket 或者 Unix domain socket),可以被下游客户端连接。在 Envoy 中,Listener 可以绑定到端口上直接对外服务,也可以不绑定到端口上,而是接收其他 listener 转发的请求。
- Cluster:集群是指 Envoy 连接的一组上游主机,集群中的主机是对等的,对外提供相同的服务,组成了一个可以提供负载均衡和高可用的服务集群。Envoy 通过负载均衡策略决定将请求路由到哪个集群成员。
xDS 协议概念:
xDS提供了标准的控制面规范,通过此规范传递信息到数据面,控制平面和数据平面Envoy所使用的通信协议,目前xDS版本主要是v3版本,为一组不同数据源的服务发现协议总称。该协议是由envoy组件定义规范,istiod实现响应envoy的请求。
主要包括LDS、RDS、CDS、EDS、SDS、HDS、MS等多种类型,其中LDS、RDS、CDS、EDS为流量管理常用资源类型,ADS为聚合发现服务,一次请求能够获取LDS、RDS等所有信息。
- Listener Discovery Service (LDS) : 监听器发现服务。Listener监听器控制Envoy启动端口监听(目前只支持TCP协议),并配置L3/L4层过滤器,当网络连接达到后,配置好的网络过滤器堆栈开始处理后续事件。这种通用的监听器体系结构用于执行大多数不同的代理任务(限流,客户端认证, HTTP连接管理, TCP代理等)
- Route Discovery Service(RDS) : 路由发现服务。路由配置包含HTTP头部修改(增加、删除HTTP头部键值),virtual hosts (虚拟主机),以及virtual hosts 定义的各个路由条目。
- Cluster Discovery Service (CDS): 集群发现服务。Envoy cluster管理器管理着所有的上游cluster。鉴于上游cluster或者主机可用于任何代理转发任务,所以上游cluster一般从Listener或Route中抽象出来。
- Endpoint Discovery Service (EDS) :集群中的服务实例发现服务。Endpoint为上游主机标识。
- Secret Discovery Service (SDS) :证书发现服务。用于运行时动态获取TLS证书。
- Aggregated Discovery Service(ADS): 通过一个Aggregated Server提供所有xDS服务,以解决各个不同xDS服务的顺序导致的数据一致性问题。
Istio中的 Envoy Sidecar 配置:
Istio 通过 Listener、Route Config 和 Cluster 为 Mesh 中的 Envoy 生成了入向和出向两个不同方向的处理流程的配置。
在 Envoy 的基础上增加了 VirtualInboundListener,VirtualOutboundListener、OutboundCluster、InboundCluster 等概念。
端到端请求流程
下图显示了Envoy的inbound和outbound处理过程:
以Bookinfo 为例说明服务间 HTTP 调用的流量拦截及处理流程:
- Productpage 发起对 reviews 服务的调用:http://reviews:9080/reviews/0 。
- 请求被 productpage Pod 的 iptables 出向流量规则拦截,处理后重定向到本地 15001 端口。
- Envoy 在 15001 端口上监听的 VirtualOutbound listener 收到了该请求。
- 请求被 VirtualOutbound listener 根据原目标 IP(通配)和端口(9080)转发到 0.0.0.0_9080 这个
outbound listener。 - 根据 0.0.0.0_9080 listener 的 http_connection_manager filter 配置,该请求采用 9080 route 进行分发。
- 9080 这个 route 的配置中,host name 为 reviews:9080 的请求对应
的 cluster 为 outbound|9080||reviews.default.svc.cluster.local。 - outbound|9080||reviews.default.svc.cluster.local cluster 配置为通过EDS获取对应的Endpoint,通过 EDS
查询得到该 cluster 中有3个 endpoint。 - 请求被 Envoy 转发到其中一个 endpoint 10.40.0.15,即 reviews-v1 所在的 pod。
- 然后该请求被 reviews-v1 pod 的 iptables 入向流量规则拦截,处理后重定向到本地的 15006 端口。
- 10.Envoy 在 15006 端口上监听的 VirtualInbound listener 收到了该请求。
- 根据匹配条件,请求被 VirtualInbound listener 内部配置的 Http connection manager filter 处理,该 filter
设置的路由配置为将其发送给 inbound|9080|http|reviews.default.svc.cluster.local 这个 inbound cluster - inbound|9080|http|reviews.default.svc.cluster.local cluster 配置的 host 为 127.0.0.1:9080。
- 请求被转发到 127.0.0.1:9080,即 reviews 服务进行业务处理。
3.3 可观测性
istio在v1.5之前的遥测数据主要是Mixer提供的,Mixer因为性能问题在v1.5后废弃,它的功能被Envoy Proxy承载,以上是Telemetry V2的架构。
根据Istio的文档,新的遥测系统将延迟减少了一半——延迟从7ms减少到3.3 ms。 不仅如此,Mixer废弃后CPU的总消耗降低了50%,降至每1,000个请求每秒0.55 vcpu。 新的API主要实现是在Envoy代理中提供wasm的运行环境Google的V8引擎,然后提供自定义的wasm插件来提供遥测数据。
service-level的指标主要通过两个插件提供,在源代码istio/proxy/extension中可以看到:
metadata exchange:会做reqeust和response的上下游标记,记录请求,
在Http Header中添加envoy.wasm.metadata_exchange.upstream
,
envoy.wasm.metadata_exchange.downstreamstats: 请求相关监控指标,暴露Prometheus 可采集的接口。
其它access_log_policy,stackdriver 是用于往Google StackDriver推送数据
3.4 安全
istio 为微服务提供了无侵入,可插拔的安全框架。应用不需要修改代码,就可以利用 Istio 提供的双向 TLS 认证实现服务身份认证,并基于服务身份信息提供细粒度的访问控制。上图为istio官方的安全架构,安全主要分为认证和授权两个部分。安全需要通过控制面和数据面的协作来实现
- 控制面:Istiod 中实现了一个 CA (Certificate Authority,证书机构) 服务器。该 CA 服务器负责为网格中的各个服务签发证书,并将证书分发给数据面的各个服务的边车代理。
- 数据面:在网格中的服务相互之间发起 plain HTTP/TCP 通信时,和服务同一个 pod 中的边车代理会拦截服务请求,采用证书和对端服务的边车代理进行双向 TLS 认证并建立一个 TLS 连接,使用该 TLS 连接来在网络中传输数据。
4.Istio开源生态
下表中罗列的是基于 Istio 的开源项目。
项目名称 | 开源时间 | 类别 | 描述 | 主导公司 | Star 数量 | 与 Istio 的关系 |
---|---|---|---|---|---|---|
Envoy | 2016年 9 月 | 网络代理 | 云原生高性能边缘/中间服务代理 | Lyft | 18300 | 默认的数据平面 |
Istio | 2017 年 5 月 | 服务网格 | 连接、保护、控制和观察服务。 | 28400 | 控制平面 | |
Emissary Gateway | 2018 年 2 月 | 网关 | 用于微服务的 Kubernetes 原生 API 网关,基于 Envoy 构建 | Ambassador | 3500 | 可连接 Istio |
APISIX | 2019 年 6 月 | 网关 | 云原生 API 网关 | API7 | 7400 | 可作为 Istio 的数据平面运行也可以单独作为网关 |
MOSN | 2019 年 12 月 | 代理 | 云原生边缘网关及代理 | 蚂蚁 | 3400 | 可作为 Istio 数据平面 |
Slime | 2021 年 1月 | 扩展 | 基于 Istio 的智能服务网格管理器 | 网易 | 204 | 为 Istio 增加一个管理平面 |
GetMesh | 2021 年 2 月 | 工具 | Istio 集成和命令行管理工具 | Tetrate | 91 | 实用工具,可用于 Istio 多版本管理 |
Aeraki | 2021 年 3 月 | 扩展 | 管理 Istio 的任何七层负载 | 腾讯 | 280 | 扩展多协议支持 |
Layotto | 2021 年 6 月 | 运行时 | 云原生应用运行时 | 蚂蚁 | 325 | 可以作为 Istio 的数据平面 |
Hango Gateway | 2021 年 8 月 | 网关 | 基于 Envoy 和 Istio 构建的 API 网关 | 网易 | 187 | 可与 Istio 集成 |
5. Istio扩展
5.1 eBPF
目前的流量劫持方案主要是通过iptables实现的,主要过程如下。
- istio-init 是一个 init container,负责创建流量劫持相关的 iptables 规则,在创建完成后会退出
- istio-proxy 中运行着 envoy,负责代理 Pod 的网络流量,iptables 会将请求劫持到 istio-proxy 处理
方案主要存在以下问题:
- 需要借助于 conntrack 模块实现连接跟踪,在连接数较多的情况下,会造成较大的消耗,同时可能会造成 track 表满的情况,为了避免这个问题,业内有关闭 conntrack 的做法。
- iptables 属于常用模块,全局生效,不能显式的禁止相关联的修改,可管控性比较差。
- iptables 重定向流量本质上是通过 loopback 交换数据,outbond 流量将两次穿越协议栈,在大并发场景下会损失转发性能。
目前行业里面认为eBPF是更好的解决流量劫持性能问题的技术,以下是腾讯团队提供的方案:
CNI插件Cilium主要的技术就是eBPF,cilium一直想在服务网格占有一席之地,eBPF可能是istio社区会引入的技术,需要重点关注。
5.2 Wasm
wasm是目前在云原生领域和eBPF一样热门的技术,上面Telemetry API介绍过wasm plugin。Envoy 通过Filter机制加载自定义的wasm plugin:
要具备优化istio的能力,wasm也是必须要掌握的手艺。
5.3 协议扩展
istio目前只劫持HTTP、TCP和gRPC协议,但目前微服务流行的协议还有dubbo、thrift等,为此腾讯团队开源了一个项目Aeraki(希腊语”微风“),专门解决L7协议扩展问题:
Aeraki的目标是创建一种非侵入的,高扩展的可以管理服务网格L7流量的能力。Aeraki 从 Istio 中拉取服务数据,根据 ServiceEntry 和 Aeraki 流量规则生成 Envoy 配置,并采用 EnvoyFilter 将生成的配置推送到 Istio 中。简而言之,你可以把 Aeraki 看做 Istio 中管理的七层协议的 Operator 。
Aeraki对服务网格落地很有帮助,可以持续关注。
5.4 Istio与函数计算
在Google开源的Knative函数计算项目中,istio担任了入口流量管理和分发的角色。
5.5 Istio与机器学习
在机器学习开源项目kubeflow中,istio充当网关和授权的角色。
四、总结
服务网格是继续容器和容器编排技术之后,云原生技术体系中新的基础技术,逐渐成为云原生应用的通信标准,具备和k8s同等重要的地位。在多云多集群、Serverless和机器学习等领域,istio也充当着重要的角色。虽然数据面技术envoy、MOSN、eBPF等呈多样化趋势,但istio的控制面技术已经基本成为服务网格的标准,深入了解istio技术原理和源码,做好产品设计,并在落地实践上不断推陈出新,快速迭代演进,是当前的重要任务。
1.行业实践
以下的分析主要基于网络上发表的技术文章。
网易
轻舟是网易的微服务平台,前期主要以无侵入Agent(Java字节码拦截)作为服务治理的方式,引入服务网格后,从”低门槛“和”高性能“两个维度进行设计。
低门槛从业务平滑接入、Sidecar热升级、多协议支持、网关平滑迁移、流量拦截和染色等维度进行设计,高性能从大规模微服务集群支持、请求时延、配置懒加载,按需按量分发,数据面性能等维度进行设计。
针对服务网格进程内无法治理的问题,通过Agent织入治理的方式解决,网易轻舟的最终方案是双引擎和多服务模式服务治理。平台需要服务业务,以Java体系为主的网易,这种做法也是适合的。
百度
百度主要实践Proxyless sevicemesh的方案,开始使用proxy方案时延对业务影响比较大,从百度业务来说,高并发和高吐量是它的特征,虽然每个网格延迟控制在0.2毫秒,但整个服务拓扑复杂,调用链非常长。因此他们的方案是在内部的bRPC框架上打主意,扔掉了envoy。
- bRPC直接支持和Istio通信,获取xds配置并进行转换;
- Proxyless模式,bRPC联编到业务进程中进行请求转发;
- Proxy模式,bRPC作为一个独立的Sidecar进程进行请求转发。
对性能要求高的用这个proxyless模式,其它语言还是基于sidecar模式。
腾讯
腾讯在服务网格方面也大力投入,在开源社区上也比较活跃,TCM的特点:
- 生态完善,兼容 Istio
- 全生命周期管理,控制面灰度升级 •
- 两种部署:独立版,托管版
- 全托管遥测系统
- 深度性能优化
- 协议和服务发现扩展,Aeraki(已开源)
- 能力拓展:边缘网关证书,跨地域互通…
- 和腾讯云深度集成:TKE,云监控,CLS
阿里
阿里云上的服务网格产品(ASM)是国内中功能最丰富并和周边产品协同度最高的。阿里集团服务网格演进分为三个阶段:无侵入部分规模化、无侵入全面规模化、云原生终态,目前集群业务 Mesh 化处于第二阶段。
- 第一阶段:存量业务 Mesh 化存在一个过渡阶段,而且需要保障这个过渡阶段相对无侵入,让业务开发者无感知;这是为什么我们需要采用无侵入方案的背景和前提;并且需要采用 Mesh 覆盖已有的微服务治理的能力,同时提供 Mesh 的增量价值;
- 第二阶段:全面规模化,同时解决规模化带来的资源开销和性能问题,通过 Sidecarcrd 实现服务配置懒加载,达到配置隔离的问题,通过对 Metrics 的优化裁剪,降低 Sidecar 内存开销,同时通过优化 Dubbo/HSFFilter 实现惰性编解码,提高数据面处理性能降低延迟。
- 第三阶段:云原生终态,随着基础设施向 Kubernetes 演进,在云原生场景下,服务发现、服务治理能力下沉,通过 Mesh 可以解耦业务逻辑和服务治理,实现配置和代码逻辑分离,从而更好地 DevOps 化,并享受 Mesh 带来的丰富的可扩展流量调度能力和可观察性。
工行
工行是传统行业,在服务网格这块的使用上,主要也是围绕着平滑迁移和性能优化两块进行的。
五、资料参考
How to write WASM filters for Envoy and deploy it with Istio
王夕宁. Istio服务网格技术解析与实践 北京华章图文信息有限公司. Kindle 版本.
崔秀龙. 深入浅出Istio:Service Mesh快速入门与实践. 电子工业出版社. Kindle 版本.
张超盟 等. 云原生服务网格Istio:原理、实践、架构与源码解析 . 电子工业出版社. Kindle 版本.