• 【云原生】初识 Service Mesh


    目录

    一、什么是Service Mesh

    二、微服务发展历程

    2.1 微服务架构演进历史

    2.1.1 单体架构

    2.1.2 SOA阶段

    2.1.3 微服务阶段

    2.2 微服务治理中的问题

    2.2.1 技术栈庞杂

    2.2.2 版本升级碎片化

    2.2.3 侵入性强

    2.2.4 中间件多,学习成本高

    2.2.5 服务治理功能不全面

    三、Service Mash 发展历程​​​​​​​

    3.1 Service Mash 概述

    3.1.1 什么是Service Mash

    3.2  Service Mash 演进历史

    3.2.1 什么是服务代理

    3.2.2 Sidecar部署架构

    3.2.3 Service Mesh中的核心概念

    四、Service Mash 常用解决方案

    4.1 Istio + Envoy

    4.2 Linkerd

    4.2.1 Linkerd 主要功能

    4.3 Kong Mesh-Kuma

    4.4 Traefik Mesh

    4.5 NGINX Service Mesh

    五、聊聊Envoy与Istio

    5.1 Istio介绍

    5.1.1 Istio核心组件

    5.2 为什么使用Istio

    5.3 Istio 核心特性

    5.3.1 流量管理

    5.3.2 安全性好

     5.3.2 可观测性

    5.3 Istio支持平台

    5.4 Envoy介绍

    5.4.1 Envoy简介

    5.4.2 核心功能

    5.5 Envoy架构设计

    5.5 Envoy的边缘代理模式

    5.5.1 HTTP 标头清理

    5.5.2 超时控制

    5.5.3 连接限制

    5.5.4 Envoy使用场景

    六、写在文末


    一、什么是Service Mesh

    Service Mesh,即服务网格,通俗来讲就是将可配置的代理层和服务部署在一起,作为微服务基础设施层接管服务间的流量,并提供通用的服务注册发现、负载均衡、身份验证、精准路由、服务鉴权等基础功能。

    Mesh 这个词汇我们听到的应该非常多,家用路由器领域有 Mesh 组网,在智能家居领域有蓝牙 Mesh。之所以叫作 Mesh,是因为它们都有一个共同的特征——去中心化。这里讲到的 Service Mesh 同样具有这一特性,微服务之间通过 Sidecar 联通网络,移除了中心网关的概念。

    二、微服务发展历程

    2.1 微服务架构演进历史

    2.1.1 单体架构

    即所有的业务功能汇聚在一个模块中,团队中的所有人都在同一个模块中共同协作。

    优点:

    • 开发效率高,能够满足快速迭代上线;

    • 团队协作高效,配合简单;

    • 部署简单灵活,运维成本低;

    • 资源占用少,可以很好的控制资源成本;

    单体架构主要适用于业务模型简单,团队规模较小,对开发、上线、部署上线等时效要求较高的场景,一般在创业团队初期,为了适应市场的快速变化而使用的一种架构模式。

    缺点:

    • 扩展有限。由于整个应用程序是一个单一的单元,如果应用程序需要扩展,就需要对整个应用进行扩展,而不是某个模块,这就限制了模块的扩展性;

    • 难以维护,可持续性差。随着应用程序不断发展和演化,单体架构的代码可能会变得越来越复杂和难以维护。比如各个功能模块共享同一个代码库和数据库,一个很小的修改可能会对整个应用程序产生意想不到的影响。

    • 部署升级困难。由于整个应用程序是一个单一部署单元,当需要部署新的功能或者升级应用程序时,就要停止整个应用程序的运行,这可能会导致应用程序的长时间不可用。

    • 架构演进难。当单体应用中的某个模块,遇到性能瓶颈,如果希望以另外一种语言重新编写此模块,或者重构这个模块,这时候会发现单体应用完全无法演进。如果要替换语言,就得重写整个应用,花费的成本可想而知。

    • 程序稳定性问题。单体应用中,当某个模块出现 Bug 时,比如因为疏忽造成了 OOM (程序内存不足),导致程序 panic,这会导致整个网站或者 App 不可用。一个模块的问题,导致了整个应用挂掉,这在生产环境中是无法接受的。

    2.1.2 SOA阶段

    随着互联网业务的发展,整体业务越来越复杂,单体架构带来的问题越来越明显,单体服务已经无法应对如此复杂的业务场景了。于是互联网行业也从架构上逐步开始了服务拆分,进入了 SOA (Service-Oriented Architecture 面向服务的架构)时代。

    在 SOA 时代,比如淘宝网,采用了一种 ESB 总线的技术,就是所有服务的通信需要通过一个集中式的总线服务(可以理解为集中式网关),这大大降低了服务的通信效率并且增加了单点风险。但是随着业务进一步扩大, ESB 总线的弊端逐步凸显,比如每次服务变更节点都需要人工操作,这大大降低了互联网业务的迭代效率。

    2.1.3 微服务阶段

    随着互联网技术的发展,尤其是移动互联网的高速发展,对服务端的要求也越来越高,一个大家普遍认知的情况就是,如何规划服务架构,才能与企业未来快速增长的业务模式相匹配。微服务架构的出现不是一蹴而就的,而是基于单体架构与SOA的思想,基于业务模型划定一定的指标和边界,从而形成一系列边界相对清晰的服务单元,这些服务单元通过一定的服务治理组件连接并统一对外提供服务能力,这就是微服务的核心理念。

    微服务是一种架构模式,是面向服务的体系结构(SOA)软件架构模式的一种演变,它提倡将单一应用程序划分成一组松散耦合的细粒度小型服务,辅助轻量级的协议,互相协调、互相配合,为用户提供最终价值。

    微服务通常具有如下特点:

    单一职责

    微服务架构中每个服务单元高度服务化、独立存在,根据业务便捷对外输出服务能力,符合高内聚、低耦合原则以及单一职责原则的思想。不同的服务通过“管道”方式灵活组合,从而构建出庞大的系统。

    独立性

    微服务架构中,每个服务都是独立的单元对外提供服务,与其他服务高度解耦,可以完成独立的开发、测试、部署、运维。

    进程隔离

    在微服务架构中,应用程序由多个微服务模块组成共同对外提供服务能力,每个服务都是高度自治的独立业务单元。运行在各自独立的进程中,以实现高度自治和隔离。进程的隔离,能够方便的做到对服务进行动态扩缩容的能力,业务高峰期增加服务资源以提升并发能力,业务低谷期则可释放服务资源以节省开销。

    调用简单

    采用微服务架构,服务之间可以通过rest接口或RPC框架进行互相调用,以实现不同服务之间的轻量级交互和通信。

    治理简单

    使用微服务架构之后,不同的服务模块

    组件可以彼此独立地进行扩缩容和治理,从而减少了因必须缩放整个应用程序而产生的浪费和成本,因为单个功能可能面临过多的负载。

    多样化部署

    微服务架构下可以针对不同的服务模块采用不同的部署模式,私有云、公有云、混合部署,甚至容器化部署也是很方便的。

    关于微服务发展,也离不开微服务技术栈的发展和完善,以Java为例,伴随着微服务的出现,业界出现不少微服务治理的框架,以springcloud为首的第一代微服务,在国内,dubbo也成为很多企业做微服务治理的不错的选择,再到后来,springcloud-alibaba的微服务治理体系解决方案也逐步占据了不少的市场。

    2.2 微服务治理中的问题

    经管微服务架构的实践能够应对很多复杂的业务场景,并且在实际应用中还有着不错的伸缩性能,但是随着业务规模的不断增长,微服务模块也随之增加,微服务模块的增多,意味着系统的复杂性越来越高,调用链路到最后就呈现出大家熟知的蜘蛛网结构。

    这样一个复杂的调用链路,无疑给系统的运维,后续的可持续治理带来了极大的挑战,以一个简单的A\B\C三个微服务模块的互相调用来说,A调B,B调C,C调A,使用微服务框架进行调用时,ABC服务至少需要知道相互之间的服务名称,然后再在代码或配置中心进行服务寻址,最后发起调用,综合来说,ABC需要通过一种机制定位要调用的服务,同时需要集中维护和管理服务地址信息... 综合来说,微服务架构下,可能面临下面的这些问题:

    2.2.1 技术栈庞杂

    使用过dubbo或springcloud组件做微服务开发的同学应该不陌生,一个微服务治理框架并不是单纯的使用springcloud或dubbo自身的框架就可以解决的,以springcloud为例,有的微服务模块可能只需要集成feign,eureka即可,有的模块却需要feign,sentinel,更有的模块还需要集成消息中间件,很难真正意义上做到治理组件的技术栈的统一。技术栈的庞杂,给开发团队带来了不小的技术门槛,和后期的运维成本。

    2.2.2 版本升级碎片化

    在实践过程中可以发现,微服务架构下,各种中间件的版本迭代升级太快了,这对于微服务项目本身来说是一个很难绕开却棘手的事情,可能在某个高版本中某个组件提供了某个业务场景下的技术解决方案,但是目前你的版本并不支持,如果要升级,面临的将是整个微服务组件的版本升级,这样一来,你不得不投入大量的时间去解决各种包的版本冲突,甚至间接的依赖组件版本也得跟着升级,最后的结果就是,即便全部升级了版本,你得对整个系统进行重新的全面测试,这个成本是比较高的。

    2.2.3 侵入性强

    以springcloud为例,想要使用组件进行服务间的调用,需要集成服务组件的SDK,除了需要添加相关依赖,业务代码中需要添加各种依赖、注解、配置等,这是一种相当的耦合性,造成了一定程度上业务边界的不清晰。

    2.2.4 中间件多,学习成本高

    可以说当你开始使用springcloud这一套微服务框架做服务治理时,随着业务的发展,需要涉及的组件会越来越多,这对于后续加入团队的成员来说,是具有相当的学习成本。

    2.2.5 服务治理功能不全面

    尽管springcloud或dubbo提供了一站式的微服务解决方案,但是在具体实际过程中仍然可以发现,单独使用springcloud也无法满足所有的要求,诸如协议转换支持、多重授权机制、动态请求路由、故障注入、灰度发布等高级功能并没有覆盖到。遇到类似的情况还是需要考虑引入其他的组件,或者定制解决方案。

    三、Service Mash 发展历程

    3.1 Service Mash 概述

    3.1.1 什么是Service Mash

    Service Mash中文解释为服务网格,是一个专门处理服务通讯的基础设施层。在实践中,它是一组和应用服务部署在一起的轻量级的网络代理,并且对应用服务透明。

    通俗解释:将服务的网络代理,抽象出来统一纳管的一种网络架构

    具体来说:

    • Service Mesh主要解决的问题就希望开发⼈员对于业务的聚焦,服务发现、服务注册、负载均衡等对于 开发⼈员透明,可以更加专注业务逻辑的实现;
    • Service Mesh (服务网格)是一个用于处理服务和服务之间通信的基础设施层,它最重要的变革,就是引入了数据面和控制面的概念;
    • 通过 sidecar模式将原本在SDK中的代码独立出来,用控制面代替配置中心的部分功能,以透明代理的形式提供安全、快速、可靠的服务间通信,同时也能实现微服务所需的基本组件功能;
    • 实际上,Service Mesh 需要的基础组件和传统的微服务并没有太大的差别,很多公司选择自研控制面的原因,很多就是出于兼容老的微服务的基础组件的考虑,你可以把 Service Mesh 看作是分布式的微服务代理。

    3.2  Service Mash 演进历史

    下图是一张微服务治理过程中,从单体服务到service mash时代的演进图,从图中不难看出,这也是对应着微服务治理的过程。

    3.2.1 什么是服务代理

    在真正迈向Service Mesh时,必须要聊的就是Sidecar,服务代理,专业解释:Sidecar,翻译成中⽂是边⻋,能够很形象的说明。如下图所展示

    3.2.2 Sidecar部署架构

    在实际部署微服务的时候,服务之间的调用通常是非常频繁的,服务间的调用通常涉及到网络通信,协议转换,路由策略,网关配置等信息,如果将为微服务提供通信服务的这部分逻辑从应⽤程序进程中抽取出来,作为⼀个单独的进程进⾏部 署,并将其作为服务间的通信代理,可以得到下图所示的架构:

    当服务规模越来越大的时候,很难再单纯通过人力去理清服务之间的调用关系,引入Sidecar之后,随着服务部署的Sidecar代理之间的连接形成了⼀个如下图所示的⽹格,该⽹格成为 了微服务的通讯基础设施层,承载了微服务之间的所有流量,被称之为Service Mesh(服务⽹格)

    服务⽹格中有数量众多的Sidecar代理,如果对每个代理分别进⾏设置,这个⼯作量⾮常巨⼤。为了更⽅便对服务⽹格中的代理进⾏统⼀集中控制,在服务⽹格上增加了控制⾯组件,这个组件即用来管理Sidecar,如下图所示:

    如果我们从一个全局视角来看,绿色的为应用服务,蓝色的为SideCar,就会得到如下部署图:

    如果我们省略去服务,只看Service Mesh的代理边车的网格应该是这样的:

    外部流量经过时,会先被Sidecar拦截,之后才放行进入服务,所以它就是一个由若干服务代理所组成的错综复杂的网格。

    第一代Service Mesh由一系列独立运行的单机代理服务构成,为了提供统一的上层运维入口,演化出了集中式的控制面板,我们称之为控制面(control plane)。

    随着服务架构的继续演进,我们需要Sidecar提供更丰富的功能,比如策略下发、数据采集、动态路由、配置管理、流量治理、可观测性等,那么就需要控制面(控制面板)与Sidecar进行更多的交互。

    服务⽹格⽤来描述组成这些应⽤程序的微服务⽹络以及它们之间的交互。随着服务⽹格的规模和复杂性不断的增⻓,它将会变得越来越难以理解和管理。它的需求包括服务发现、负载均衡、故障恢复、度量和监控等。服务⽹格通常还有更复杂的运维需求,⽐如 A/B 测试、⾦丝雀发布、速率限制、访问控制和端到端认证。

    3.2.3 Service Mesh中的核心概念

    服务网格分为:控制层和数据层(或称之为数据面与控制面) 

    • 控制层或控制平面(control plane)是管理组件,负责与控制平面中的代理通信,下发策略和配置;
    • 数据层或数据平面(data plane)是网络代理,直接处理入站和出站数据包,转发、路由、健康检查、负载均衡、认证、鉴权、产生监控数据等。

    数据面特征

    • 通常是按照无状态目标设计的,但实际上为了提高流量转发性能,需要缓存一些数据,因此无状态也是有争议的;
    • 直接处理入站和出站数据包,转发、路由、健康检查、负载均衡、认证、鉴权、产生监控数据等;
    • 对应用来说透明,即可以做到无感知部署;

    控制面特征

    • 与控制平面中的代理通信,下发策略和配置;
    • 负责网络行为的可视化;
    • 不直接解析数据包;
    • 通常提供 API 或者命令行工具可用于配置版本化管理,便于持续集成和部署;

    四、Service Mash 常用解决方案

    随着服务网关开始在生产实践中的使用,加上近些年以k8s为代表的容器化编排能力的加强,Service Mash 也出现了很多解决方案,下面列举几种常用的解决方案。

    4.1 Istio + Envoy

    如今,Istio 几乎是 Service Mesh 的代名词了,Istio 包含控制面 Istiod 和数据面 Envoy 两个组件

    •  Istiod 是 Istio 的控制面,负责配置校验和下发、证书轮转等工作;
    • Envoy 则负责数据代理和流量路由等工作。

    准确来说 Istio 实际上只是 Service Mesh 的控制面,而 Istio + Envoy 才组成整个 Service Mesh 体系,这有点像 GNU/Linux,通常被简单地称为 Linux。

    Istio 包含负责配置下发的 Pilot、负责证书轮转的 Citadel 和负责配置校验的 Galley。在 1.5 版本去除 mixer 后, Istio 已经变得相对简单了,它的主要工作就是配置下发

    Envoy 是 C++ 编写的高性能边缘网关和代理程序,支持 HTTP、gRPC、Thrift、Redis、MongoDB 等多种协议代理。当然这里面支持最好的还是 HTTP,它几乎具备了 Service Mesh 数据面需要的所有功能,比如服务发现、限流熔断、多种负载均衡策略、精准流量路由等。

    4.2 Linkerd

    Linkerd 是云原生软件公司 Buoyant 开源的 Service Mesh 方案,而 Service Mesh 的概念也是 Linkerd 首先提出的。其主要⽤于解决分布式环境中服务之间通信⾯临的⼀些问题,⽐如⽹络不可靠、不安全、延迟丢包等问题。Linkerd使⽤Scala语⾔编写,运⾏于JVM,底层基于Twitter的Finagle库,并对其做相应的扩展。最主要的是Linkerd具有快速、轻量级、⾼性能等特点,每秒以最⼩的时延及负载处理万级请求,易于⽔平扩展,经过⽣产线测试及验证,可运⾏任何平台的产线级Service Mesh⼯具。

    不过由于 Java 的内存占用率等原因,并不适合 Sidecar 的编写,所以 Linkerd 开发了 2.0 版本,数据面使用 Rust 编写,控制面基于 Go 语言实现

    4.2.1 Linkerd 主要功能

    Linkerd 主要功能如下

    • mTLS:Linkerd 为所有网格内的服务提供双向 TLS 加密认证的功能,保证流量传输安全。
    • 可观测性:提供了 Grafana 的图形界面以及链路追踪功能。
    • 协议支持:提供了 gRPC、HTTP、HTTP/2 等多种协议支持。
    • 负载均衡:提供了多种负载均衡功能,包括基于当前请求数的 P2C 算法、基于 EWMA 的多种策略的 P2C 算法,以及常规的 WRR 和 RR 算法。
    • 动态路由功能:支持根据 header 设置不同的路由规则,支持流量转移功能,可以在不同服务之间、相同服务不同版本之间做流量转移。

    4.3 Kong Mesh-Kuma

    早期 Kong 采用了自研的 Kong 作为数据面,Istio 作为控制面的方案,但这个方案很快被抛弃了,现在 Kong 推出了基于 Envoy 的 Service Mesh 解决方案——Kuma。


    Kuma 最大的特点是同时支持 Kubernetes 和 VM 虚拟机,这样即便公司存在多种运行环境,也可以支持。另外它也支持单一控制面同时控制多套集群,由于使用 Envoy 作为数据面,所以在核心功能支持上和 Istio 相差不大,比较特别的是支持 Kong 作为入口网关层。此外,Kuma 采用 Go 语言编写,方便二次开发扩展。

    4.4 Traefik Mesh

    Traefik Mesh 由 Go 语言编写的开源网关系统 Traefik 演进而来,与其他提到的 Mesh 解决方案不同,Taeafik Mesh 将 Sidecar 部署在了 Kubernetes Node 节点上。这样的好处是在同一个 Node 节点上的 Pod,可以共享一个 Sidecar,不用为每个 Pod 单独分配 Sidecar 资源,从而达到节省资源的目的,同时相对于在 Pod 的 Container 里部署 Sidecar,这样也方便升级维护。

    但这种做法也有缺点,资源隔离性不好,容易相互影响,比如同一个 Node 节点上某个服务出现了问题,从而占用了更多的资源,其他的 Pod 可能就没有资源可用了。

    4.5 NGINX Service Mesh

    Nginx 包含一个处理东西流量的 NGINX Plus 数据面和一个用作入口网关(南北向流量)的NGINX Plus,都可以通过控制面进行控制。

    控制面专门为 NGINX Plus 开发,下发配置用于控制 NGINX Plus 的数据面,主要包含以下部分。

    • Grafana:用于收集 Metrics 指标的可视化展示。
    • Kubernetes Ingress Controllers:管理入口和出口流量。
    • SPIRE:复杂证书轮转。
    • NATS:负责下发配置,比如路由信息更新等。
    • Open Tracing:分布式链路追踪,同时支持 Zipkin 和 Jaeger。
    • Prometheus:收集 Metrics 信息,包括请求数,连接数,SSL 握手次数等。

    要注意的是,NGINX Plus 是 Nginx 收费版本,并不是开源软件,无法进行二次开发。

    更多的解决方案大家可以参阅相关的资料还有很多,下面列举了常用的一些Service Mesh解决方案,有兴趣的同学可以针对每种方案对应的组件进行深入的学习和了解

    五、聊聊Envoy与Istio

    5.1 Istio介绍

    谈到 Service Mesh,不得不提及 Istio,作为 Google、IBM、lynx 联合推出的 Service Mesh 解决方案,Istio 几乎成了 Service Mesh 的代名词,但实际上 Istio 仅仅是 Service Mesh 中的控制面,它的主要功能是为数据面下发服务治理策略。

    Istio 最近在 1.5 版本进行了一次大的变更,由早期的微服务架构变成了单体架构。之前版本的Istio 由 Pilot、Citadel、Galley、Sidecar 注入器等多个微服务组成,但现在只需要一个 Istiod 的单体服务

    Istio的架构图

    5.1.1 Istio核心组件

    结合上图,Istio核心组件如下

    • Pilot ,Istio 控制面中最核心的模块,负责运行时配置下发,具体来说,就是和 Envoy 之间基于 xDS 协议进行的各种 Envoy 配置信息的推送,包括服务发现、路由发现、集群发现、监听器发现等。为 Envoy 提供服务发现,流量管理和智能路由(AB 测试、⾦丝雀发布等),以及错误处理(超时、重试、熔断)功能。
    • Citadel:负责证书的分发和轮换,为服务之间提供认证和证书管理,可以让服务⾃动升级成 TLS 协议,使 Sidecar 代理两端实现双向 TLS 认证、访问授权等。
    • Galley:配置信息的格式和正确性校验,将配置信息提供给 Pilot 使用。Galley Istio 的配置验证、提取、处理和分发组件。它负责将其余的 Istio 组件与从底层平台(例如 Kubernetes)获取⽤户配置的细节隔离开来。

    5.2 为什么使用Istio

    通过负载均衡、服务间的身份验证、监控等⽅法,Istio 可以轻松地创建⼀个已经部署了服务的⽹络,⽽ 服务的代码只需很少更改甚⾄⽆需更改。通过在整个环境中部署⼀个特殊的 sidecar 代理为服务添加 Istio 的⽀持,⽽代理会拦截微服务之间的所有⽹络通信,然后使⽤其控制平⾯的功能来配置和管理 Istio,这包括:
    • 为 HTTP、gRPC、WebSocket 和 TCP 流量⾃动负载均衡。
    • 通过丰富的路由规则、重试、故障转移和故障注⼊对流量⾏为进⾏细粒度控制。
    • 可插拔的策略层和配置 API,⽀持访问控制、速率限制和配额。
    • 集群内(包括集群的⼊⼝和出⼝)所有流量的⾃动化度量、⽇志记录和追踪。
    • 在具有强⼤的基于身份验证和授权的集群中实现安全的服务间通信。

    Istio 为可扩展性⽽设计,可以满⾜不同的部署需求。

    5.3 Istio 核心特性

    Istio以统一的方式提供了许多跨服务网格的关键功能。

    5.3.1 流量管理

    1、Istio 简单的规则配置和流量路由允许您控制服务之间的流量和 API 调⽤过程。

    2、Istio 简化了服务级属性(如熔断器、超时和重试)的配置,并且让它轻⽽易举的执⾏重要的任务(如A/B 测试、⾦丝雀发布和按流量百分⽐划分的分阶段发布)。

    3、有了更好的对流量的可视性和开箱即⽤的故障恢复特性,就可以在问题产⽣之前捕获它们,⽆论⾯对什么情况都可以使调⽤更可靠,⽹络更健壮。

    5.3.2 安全性好

    安全性对于互任何一款互联网产品来说都至关重要,Istio 的安全特性解放了开发⼈员,使其只需要专注于应⽤程序级别的安全。

    Istio 提供了底层的安全通信通道,并为⼤规模的服务通信管理认证、授权和加密。有了 Istio,服务通信在默认情况下就是受保护的,可以让您在跨不同协议和运⾏时的情况下实施⼀致的策略——⽽所有这些都只需要很少甚⾄不需要修改应⽤程序。

    Istio 是独⽴于平台的,可以与 Kubernetes(或基础设施)的⽹络策略⼀起使⽤。但它更强⼤,能够在⽹络和应⽤层⾯保护pod到 pod 或者服务到服务之间的通信

     5.3.2 可观测性

    近些年,随着微服务架构的应用逐渐成熟,人们对于服务在运行过程中的各种指标监控的可视化需求也越来越高,简单来说,就是服务运行过程中的各种指标参数应当是可观测的。在这方面,Istio提供了较强大的功能。

    • Istio 健壮的追踪、监控和⽇志特性让您能够深⼊的了解服务⽹格部署。
    • 通过 Istio 的监控能⼒,可以真正的了解到服务的性能是如何影响上游和下游的,⽽它的定制
      Dashboard 提供了对所有服务性能的可视化能⼒,并让您看到它如何影响其他进程。
    • Istio 的 Mixer 组件负责策略控制和遥测数据收集。它提供了后端抽象和中介,将⼀部分 Istio 与后端的基础设施实现细节隔离开来,并为运维⼈员提供了对⽹格与后端基础实施之间交互的细粒度控制。

    所有这些特性都使您能够更有效地设置、监控和加强服务的 SLO。当然,底线是您可以快速有效地检测到并修复出现的问题

    5.3 Istio支持平台

    Istio 独⽴于平台,被设计为可以在各种环境中运⾏,包括跨云、内部环境、Kubernetes、Mesos 等等。可以在 Kubernetes 或是装有 Consul 的 Nomad 环境上部署 Istio,Istio目前支持:

    • Kubernetes 上部署;
    • 基于 Consul 的服务注册;
    • 独立虚拟机部署;

    5.4 Envoy介绍

    5.4.1 Envoy简介

    Envoy是Istio中的核心控件,Envoy 本质上是一个为面向服务的架构而设计的 7 层代理和通信总线。Envoy 基于 C++ 11 开发而成,性能出色、网络控制能力强大、监控能力良好。

    Envoy 是专为大型现代 SOA(面向服务架构)架构设计的 L7 代理和通信总线,它既可以作为 Service Mesh 中的数据面使用,也可以作为入口网关层使用,可以通过 xDS API 控制 Envoy 的监听、路由、负载均衡等行为。

    Istio 的流量管理是通过 Pilot 和 Envoy 这两个组件实现的,将流量和基础设施进行了解耦。

    • Pilot 位于控制层,负责配置规则,并把规则分发到 Envoy 代理去实施;
    • Envoy位于数据层,按照规则执行各种流量管理的功能,比如动态请求路由,超时、重试和熔断,还可以通过故障注入来测试服务之间的容错能力;

    5.4.2 核心功能

    高性能

    采用 C++ 编写,拥有良好的四层、七层代理性能,在 8 核的机器上,HTTP 代理可以达到 10w 的 QPS,gRPC 可以达到 15w QPS,完全满足了 Service Mesh 中 Sidecar 的应用场景。

    多种协议支持

    不仅支持 HTTP 和 HTTP/2,随着社区的发展,Thrift、gRPC、MongoDB、Redis、MySQL 等多种网络协议都被支持,甚至可以使用 Envoy 做 Redis 的 Mesh 方案,用来代替流行的 Redis 中间件。

    良好的 HTTP/2 支持

    随着 gRPC 框架的流行以及边缘层网络性能的要求提升,HTTP/2 越来越被重视。Envoy 原生支持 HTTP/2,可以在 HTTP 和 HTTP/2 之间做转换。比如在 Sidecar 模式中,无论应用协议是 HTTP 还是 HTTP/2,Envoy 之间默认使用 HTTP/2 通信,这样极大提升了服务性能和稳定性,避免了 HTTP 频繁建立连接带来的消耗和不稳定性。

    边缘网关

    Envoy 本身就是一个高性能的网络代理组件,完全可以作为入口网关层使用,在 Kubernetes 中,也可以作为 Egress 和 Ingress 使用。

    服务发现

    和其他常见的网络代理软件不同,Envoy 默认支持服务发现组件。Envoy 使用了一套xDS 的动态 API,获取服务的后端节点并实时更新,结合 Envoy 强大的负载均衡器,可以做到最终一致性。

    Filter 架构

    可以在四、七层编写 Filter 以扩展 Envoy 的功能,比如监听过滤器、四层网络过滤器,以及七层过滤器。不过 Envoy 支持最完善的还是HTTP 过滤器,支持了限流、路由转发、故障注入等多种服务治理功能,

    可观测性

    支持强大的统计系统。日志、Metrics、链路追踪都有良好的支持。

    Wasm 扩展

    Envoy 在最近的 1.17 版本增加了对 Wasm 的支持。Wasm 全称为 WebAssembly,最早用在浏览器端用来解决 JavaScript 性能问题和大型项目团队协作问题。近些年,它开始在一些后端技术上使用,用来代替 Lua,作为核心系统的扩展方式。因为 Wasm 可以使用多种语言进行开发,所以方便对核心系统进行扩展,不用担心语言问题。当然相对于原生的 C++ 扩展方式,它大概有 3 成的性能损耗。

    5.5 Envoy架构设计

    下图是 Envoy 架构的设计图,从这张图我们可以看到入流量经过 Iptables 劫持被转发到了 Envoy 的端口,Envoy 通过监听端口创建连接,提供七层代理服务。下面具体来看看每部分内容都做了什么工作。

    Iptable:

    通过 Iptable 劫持,将入口和出口流量都转发到 Envoy 上,达到劫持流量的目的。


    Listener:

    Envoy 通过建立多个监听器提供不同的服务。比如通过监听的两个端口分别负责 Sidecar 模式的出流量和入流量,Sidecar 多使用这种设计,这样可以简化编程逻辑,也可以增强 Filter 的通用性。如果提供不同协议,Envoy 也会建立不同的端口来提供服务。

    Worker:

    每个 Listener 维护一个对应的 Worker Pool,Envoy 为每个逻辑处理器创建一个 Worker 线程,当我们在一个新的端口启动一个新的 server 时,Envoy 也会根据 -concurrency 创建对应的 Worker 线程,要注意启动太多的 worker 线程并不一定是好事,特别是在 Sidecar 模式,我们并不会分配过多的逻辑核心给到 Sidecar,创建过多的 Worker 线程可能导致每个 Worker 线程维护的连接变多,Upstream 压力过大。

    Filters:

    可以理解为中间件,通过 Filter,可以做到四层和七层的流量过滤,支持服务治理需要的限流、熔断等功能。

    Cluster Manager:

    流量经过 Router,识别出需要转发的 Cluster,通过 Cluster Manager 进行服务发现和负载均衡等功能。

    Upstream:

    Upstream 维护了 EndPoint 的连接池,通过负载具衡器,将流量转发到合适的 EndPoint 上面。


    聊完了 Envoy 的架构,我们一起看一下 Envoy 作为 Service Mesh 中的数据面,也就是 Sidecar 模式下,整个数据流转过程。

    如上图所示,Envoy 作为 Sidecar 使用时,需要和服务部署在同一台机器或者 Pod 中,用户访问其他服务时,流量会被自动劫持到 Envoy 中。

    结合上图,主要的流程如下:

    • 通过 Iptables 对流量进行劫持,将 Productpage 访问 Reviews 的流量转发到 Envoy 的出流量 15001 端口上。
    • Envoy 先根据 virtual_hosts 进行匹配,再通过路由匹配,发现路由对应的 Cluster,通过服务发现找到 Cluster 对应的 EndPoint,将流量转发到 10.40.0.15:9080 的 Pod 上。
    • Reviews 的 Pod 通过 Iptables 对流量进行劫持,将流量劫持到 Envoy 的入流量端口 15006 上。
    • Envoy 将本地流量转发到对应的本地地址 127.0.0.1:9080,这里不需要对流量进行识别,因为流量被转发到入流量端口 15006 上,这个端口的配置用于本地流量的转发。

    到这里整个 Sidecar 的流量出入过程就结束了。出入流量都经由 Envoy,最终被正确的转发到了 Reviews 的 Pod 上面。

    5.5 Envoy的边缘代理模式

    Envoy 不仅可以用于 Sidecar 模式,也可以用作边缘网关,但是用作边缘网关层我们有一些注意事项,这些问题不仅在 Envoy 中存在,在其他的边缘网关中也应该处理。

    5.5.1 HTTP 标头清理

    一些外部传入的 header 可能会影响内部行为,应该统一做出清理操作,比如我们经常会用到的 x-forward-for,在反向代理中,未经过一层代理,都应该将代理的 IP 追加在 x-forward-for 中,以保证通过 x-forward-for 可以获取最原始的 IP,如果有客户端恶意传输 x-forward-for,不做清除操作可能会导致拿到错误的客户端 IP。在 Envoy 中可以通过 use_remote_address 设置为 true 来清理 HTTP 标头。

    5.5.2 超时控制

    超时控制分为连接超时、流超时和路由超时。这些超时控制不仅在边缘网关模式中需要注意,在 Sidecar 模式也需要注意,一些不合理的超时可能会引起服务的雪崩。虽然在内网服务调用时一般都会设置默认超时,但 Sidecar 应该设置一个默认的超时时间,避免服务没有设置有效超时的情况引起的问题。

    连接超时

    Envoy 为 HTTP 服务提供了空闲连接超时时间的设置,空闲超时是指一个连接在接收到请求后,会设置 TCP 的 idle Timeout 的参数,一段时间内没有收到代理服务的响应请求,则会断开连接。Envoy 默认的空闲超时是 1 小时。连接超时对所有流生效,连接一旦断开,所有流处理也会中断。


    流超时

    流是 HTTP/2 中的概念,在 HTTP/1 中没有流的概念,Envoy 通过将 HTTP 连接对应到流模式,统一进行处理。HTTP 连接管理器 stream_idle_timeout 默认超时时间为 5 分钟,推荐对所有流设置合理的超时时间,这个时间就是接收请求到返回数据的处理时间如果没有特殊需求,建议设置为 10s,默认超时时间偏长。如果触发此超时时间,则会出发 504 Gateway Timeout 的错误码。

    路由超时

    除了设置全局的流超时外,还可以设置路由层面的超时,为某些请求设置特殊的配置,一些请求可能需要更快的响应速度,所以要设置较短的超时时间,这个时候只要在路由层面设置即可,比如针对某些 Path 设置更短的超时时间。

    5.5.3 连接限制

    Envoy 可以针对全局或者监听器设置连接限制。一般单一服务器可承载的并发连接数有限,根据线上的峰值连接运行情况,设置合理的连接设置,可以避免因服务出问题时响应过慢,大量新建 HTTP 连接击垮 Envoy 的情况。

    5.5.4 Envoy使用场景

    Envoy使用场景主要有两类

    • 作为 Service Mesh 数据面组件选型,目前在 Istio 等多种服务网格框架落地;
    • 作为流量入口代理,目前较多的是以 API 网关形式实现,如 Gloo、Ambassador 等

    Envoy 不仅可以作为 Service Mesh 中的 Sidecar 使用,也可以作为边缘网关使用,它的本质就是一个反向代理服务器,Nginx、HAProxy 能做的事情 Envoy 也可以做得很好。

    六、写在文末

    随着容器化技术的逐渐成熟与大规模应用,加之有众多的成熟的开源组件生态的巩固,服务网格作为下一代微服务的趋势,从目前行业的布局和实践经验来看,一定会在不久的未来成为一个新的微服务形态的制高点,因此有必要对其做提前的了解和学习,本篇到此结束,感谢观看。

  • 相关阅读:
    自己动手从零写桌面操作系统GrapeOS系列教程——14.屏幕显示原理与文本模式
    Spring Cloud Alibaba整合Seata实战
    JuiceFS-开源分布式文件系统入门(一篇就够了)
    odoo17 web.assets_web.min.js 赏析
    《Vue.js 3.x+Element Plus前端开发实战》简介
    最新版阿里云Linux CentOS7 ecs-user用户安装Mysql8详细教程(超简单)
    2023.11.22 -数据仓库
    我为什么觉得程序员是个高危职业
    基于架构软件设计-架构真题(五十八)
    三菱PLC网络MC3E通信—读取或写入——字符串或数字
  • 原文地址:https://blog.csdn.net/zhangcongyi420/article/details/134497034