最新公告
  • 新注册用户请前往个人中心绑定邮箱以便接收相关凭证邮件!!!点击前往个人中心
  • Istio 架构原理解析

    开篇 

    在云环境下,技术栈可谓是多种多样,通过不同的技术生成不同的应用。如何能将这些异构的服务或者应用有机地串联起来,成为了服务治理的重大课题,在这样的大背景下Istio架构为这样应用场景提供了服务治理的功能,Istio提供的流量治理、策略、遥测、访问安全等功能至今都被人津津乐道。

    今天就围绕Istio架构的实现原理为大家介绍如下内容:

    • 为什么选择Istio
    • 什么是Istio
    • Istio架构原理
    • Istio服务治理功能介绍

     

     为什么选择Istio 

    随着业务的复杂度提高,为了应对高并发、大流量,系统架构对服务/应用进行拆分。拆分以后的服务/应用可以进行分布式部署,来应对高并发带来的系统压力以及处理复杂的业务逻辑。

     

    这样的做法会造成系统中存在大量独立的服务或者应用,它们分布在不同的进程、主机上面,在它们之间互相调用的时候就存在服务治理的问题。微服务就是一个典型的例子,微服务的开发和运维对程序员来说是一个挑战。

     

    分而治之的思想使得业务本身的规模和复杂度不降反增。

     

    在分布式系统中,网络可靠性、通信安全、网络时延、网络拓扑变化等都成了关注的焦点,同时服务注册、服务发现、负载均衡、服务间通讯、分布式调用链追踪都是要解决的问题。

     

    为了解决这个问题,把服务治理部分抽象成公共库,让所有微服务都使用这个公共库。如图1所示,在Node 1 和 Node 2 上分别用Service 1 和Service 2两个服务,它们分别针对自己的业务逻辑都有对应的服务治理的SDK,通过这个SDK完成服务治理的服务发现、服务注册等功能。

     

    图1

    将服务治理的逻辑抽象成公共库

     

    如果将图1中的SDK包含到开发框架中(例如:Spring Cloud),当运用这种开发框架后就拥有服务治理的能力了。SDK的模式虽然解耦了业务逻辑和服务治理,由于在一个开发框架中,因此业务逻辑需要和 服务治理的SDK一起编译,发布以后业务逻辑和服务治理的代码在一个进程中运行。这会导致业务代码和 SDK 基于同一种语言,无法兼容其他语言开发的服务。同时,在服务治理升级时,需要升级整个服务,即使业务逻辑没有改变。如果说图1的模式,SDK和业务代码在同一进程,因此需要对其进行解耦,把服务治理从业务代码中剥离出来。如图2所示,红色的部分代替了原来的SDK,其使用了Sidecar模式。在这种形态下,业务逻辑和服务治理在独立的进程下运行。

     

    图2 

    Sidecar解耦业务逻辑和服务治理

    Sidecar的模式使两者代码和运行无耦合。如图3所示,业务逻辑就好像绿色的方块,再其右边的蓝色方块就是Istio提供的Sidecar(边车),也就是通过这个Sidecar与网络中其他服务的Sidecar进行链接,从而实现服务之间的通信。

     

    这样业务逻辑可以使用不同的语言进行开发,升级也相互独立,而其他的服务治理的工作,例如:服务注册、服务发现、负载均衡、通讯等都由Sidecar来完成。

     

    图3 

    Istio的Sidecar模式

    这里通过业务逻辑与服务治理的角度,将使用Istio之前和之后的微服务做区分,从以下三个维度进行对比。

     

    业务逻辑与服务治理
    使用Istio之前
    使用Istio之后
    运行进程
    两者在同一进程内
    两者在不同的进程
    技术栈
    两者使用相同技术栈
    两者使用不同技术栈
    服务升级
    两者同时升级
    两者分别升级

     

    因此在使用Istio架构以后,会将业务逻辑与服务治理在运行进程、技术栈和服务升级三个方面进行完全解耦,通过Sidecar模式打造分布式系统的最佳实践,接下来就来看看Istio包括哪些内容。

     什么是Istio 

    众所周知Istio是一个Service Mesh形态的,用于服务治理的开放平台。这里的服务 “治理”不仅限于“微服务”,可以推广到任何服务。只要存在服务或者应用,在它们之间存在访问,也存在对服务与应用的管理,都可以使用到 Istio

     

    如图4所示,在 Istio 官方介绍中,其功能包括:连接(Connect)、安全(Secure)、控制(Control)和观察(Observe)

     

    图4 

    Istio 官方功能介绍

    将上面四项功能总结如下:

    • 连接:通过流量规则控制服务间的流量和调用,实现负载均衡、熔断、故障注入、重试、重定向等功能。
    • 安全:提供认证机制、通道加密、服务访问授权等安全能力,增强访问的安全性。
    • 控制:通过可动态插拔、可扩展的策略实现访问控制、速率限制、配额管理、服务计费等能力。
    • 观察:获取服务运行数据和输出,提供调用链监控和日志收集能力。

    在微服务时代,Kubernetes提供了服务的部署、升级、扩容等运行管理能力,但在服务治理方面,如服务的熔断、限流、动态路由、调用链追踪显得能力不足。

     

    Istio作为服务治理的架构刚好在这一点上弥补了Kubernetes的不足,成为了Kubernetes的好搭档。

     

    既然把Istio吹上了天,就来看看Istio 在服务访问的过程中有哪些建树吧。如图5所示,有两个Pod容器,分别存放两个不同的服务,Service A和Service B。其中Service A Java进行开发,而Service B由Python进行开发。

     

    • Service A通过服务发现获取Service B服务实例列表,如果Service B存在多个水平扩展(Service B集群),还需要根据负载均衡策略选择一个具体的Service B实例。
    • 为了保证安全性,服务之间的请求和响应需要启用双向认证和通道加密。
    • 在一段时间内,Service A在访问Service B不断出现错误,需要进行熔断处理,停止对Service B的请求动作。
    • 针对Service B的处理能力,设置最大连接的请求数、访问超时等参数,从而对其进行服务保护。
    • 如果有需要可以将Service A对Service B发起的请求重定向到其他服务上。
    • 如果Service B 有新、老两个版本,在执行灰度发布的时候,将Service A请求的部分流量(20%)导入到Service B的新版本中,其他的流量(80%)导入到Service B的老版本上。随着Service B 新版本的逐步稳定,再将剩下的80% 流量导入到新版本上。
    • Service A调用 Service B 的调用链进行追踪,为提升服务之间的调用效率提供数据依据。

     

    图5 

    Istio 针对服务治理的功能

     

     Istio架构原理 

    在上一节中介绍了什么是Istio,是针对其功能进行的描述,看上去比较抽象,这里从Istio的工作机制和架构进一步进行描述。如图4所示,Istio整个架构可以分为控制面和数据面两部分,控制面主要包括Pilot、Mixer、Galley、Citadel等组件;数据面由伴随服务部署的代理Envoy组成,Envoy针对服务完成服务治理的逻辑。这里我们按照Istio的运行机制将每个步骤标上序号,逐个介绍。序号并不表示执行的顺序,只是为了方便标注,为的是讲解功能。在数据面中的交互通过带箭头的实线表示,数据面和控制面的交互通过虚线标注。其资源是通过Kubernetes进行部署的,在Node 1 和Node 2 通过Pod容器部署了服务A和服务B,其中服务B有两个版本V1 和V2,分别部署在Node 2 的两个Pod中。通过描述服务A调用服务B不同的版本,以及外部请求访问服务A的过程给大家讲述Istio各个组件的工作流程。

     

    图4 

    Istio的控制面和数据面

    1.自动注入 

    由于Istio使用了Sidecar代理的模式,将业务逻辑和服务治理进行了解耦。因此在 Kubernetes场景下创建 Pod时,同时创建Sidecar容器。实际上是注入并创建了istio-proxy和istio-init两个容器。其中istio-proxy包含了Pilot-agent和Envoy两个进程。Envoy作为处理服务之间请求流量的进程在服务调用中起到重要的作用,因此在图4中特别标注出来。

    2.服务发现 

    在注入Envoy以后,假设服务A调用服务B,因此需要通过Envoy向服务B发起请求。服务A如何得知服务B的访问地址能,就需要通过服务发现的方式完成。此时,Envoy 需要调用管理面组件 Pilot 的服务发现接口,获取服务B的实例列表。Pilot 直接从运行平台提取数据并将其转换成 Istio 的服务发现模型,这种服务发现的方式还支持Kubernetes、Consul等平台。

    3.流量拦截  

    当服务A得知服务B的地址以后,就会通过服务A向Envoy发送请求流量。发出的流量成为Outbound,在服务B端会接收到这个流量成为Inbound。图4中从服务A流出的流量(Outbound)会被服务A侧的 Envoy拦截,而当流量作为流入的流量(Inbound)到达服务B时,会被服务B侧的Envoy拦截。这里拦截的目的是对流量进行控制,特别是在高并发的情况下会对某些服务进行流量的限制。

    4.负载均衡

    服务A作为请求的发起方,Envoy根据配置的负载均衡策略选择服务实例,并连接对应的实例地址。这些负载均衡的策略是通过Pilot以配置文件的形式下发到Envoy上实现的,具体策略如RANDOM和ROUND_ROBIN。图4中访问服务B,V2版本的时候,发现该版本有多个服务B,此时就需要使用负载均衡策略访问其中某个服务B了。

    5. 流量治理 

    Envoy 从 Pilot 中获取配置的流量规则,在拦截到 Inbound 流量和Outbound 流量时执行治理逻辑。和流量拦截不同的是,其目的是为了访问同一服务的不同版本。服务A通过Envoy获取规则,通过规则判断将流量分发到服务B的V1或V2版本。

    6. 访问安全 

    在服务A和服务B之间建立双向认证和通道加密,并基于服务的身份进行授权管理。同样由Pilot下发安全配置,在服务A和服务B对应的Envoy上加载证书和密钥来实现双向认证,证书和密钥由管理面的Citadel组件维护。

    7. 服务遥测 

    在服务间通信时,通信双方的Envoy会连接管理面的Mixer组件上报访问数据。例如:监控指标、日志和调用链都可以通过这种方式进行收集。

    7. 外部访问 

    在左下角有个“外部请求访问”,其作为这个网格之外的请求访问网格内的服务A。因此在入口处有一个Envoy扮演入口网关的角色。外部服务通过Gateway访问服务A。如果需要负载均衡以及流量治理的策略,都在这个Gateway的Envoy进行设置。

    9. 管理配置 

    最后是管理面的galley组件。它不面向数据面提供服务,而是在控制面上向其他组件提供支持。主要负责验证控制面的配置信息格式和内容的正确性,并将配置信息提供给 Pilot和 Mixer组件使用。

    Istoio服务治理功能介绍 

    通过上面Istio架构原理的介绍,把控制面和数据面的组件给大家过了一遍。由于篇幅问题不能在这里逐个展开介绍,由于Istio的主要功能是服务治理,这里选取几个服务治理中经常使用的功能给大家介绍,也算是窥豹一斑吧。

     

    服务路由

    服务路由在实际场景中比较常见,如图5所示Service A根据不同的路由:Test.com/ServiceB, Test.com/ServiceC, Test.com/ServiceD,分别访问Service BCD

     

    5 

    服务路由

    正如在Istio架构原理”章节中提到的,Istio配置规则从Pilot发起传送到Envoy上执行。其配置文件格式基本与Kubernetes相似。具体到图5的配置文件会使用到VirtualService类型的配置。

     

    VirtualService定义了对特定目标服务的流量规则。它在表示一个虚拟服务,功能是将满足条件的流量转发到对应的服务(一个或者多个)。

     

    如代码段1所示,在Istio的配置文件中按照红色数字描述如下

    1. kind中定义VirtualService的类型
    2. 定义要访问的入口服务的名称,这里ServiceA作为入口服务,通过它访问后面的三个服务。
    3. hosts中定义主机的url地址作为路由的一部分,因为这里的地址访问按照“Test.com/ServiceB”的方式进行访问,因此定义为“Test.com”。
    4. 这里针对http请求进行路由,因此在http下面的match(匹配)中的uri中定义prefix,显然如果要访问“Test.com/ServiceB”,这里的prefix需要定义为“/ServiceB”。实际上就是具体服务路由的地址。
    5. 最后,针对uri地址制定对应的route,在destination(目标)的host中定义服务的名称:“ServiceB”。ServiceC、D的定义和B的基本一致,不再赘述。

    代码段1 

    流量切分

    上面描述了简单路由的规则设置,如果遇到需要更具访问内容进行流量切分的情况,或者需要按照比例切分流量的情况配置文件的内容就需要修改了。如图6 所示,Service A要访问Service B的三个不同版本 V1V2V3。当URI”Test.com/status””Test.com/data的时候会请求Service BV2 V3版本,导入的流量分别是20%80%(红线标注的部分)。其他URI路由到Service BV1 版本(绿线标注的部分)。

     

    图6 流量切分

    照旧看看配置文件的每个配置项的内容,按照红色数字描述如下:

    1. httpmatch的部分用来匹配URI,这里有两个prefix 分别是:data”和“status”,当请求URI满足这个两个条件中的一个时进入下面的路由选择。
    2. 在路由选择routedestination中对应了ServiceB服务的,subsetV2 也就是V2版本。Weight设置是20,意思是20%的流量,流入ServiceBV2版本。
    3. 在路由选择routedestination中对应了ServiceB服务的,subsetV3 也就是V3版本。Weight设置是80,意思是80%的流量,流入ServiceBV3版本。
    4. 最后,如果在没有命中上述两个prefix的情况下,流量会流入ServiceBV1版本。

     

    代码段2

    负载均衡

    负载均衡是服务治理中经常遇到的功能,来看看在Istio中是如何实现的。如图7 所示,Service A会访问Service B V2版本的集群以及Service B V1版本的集群。针对同一个服务的两个不同版本的集群,需要使用两种不同的负载均衡策略,分别是ROUND_ROBINRANDOM

     

    7 

    负载均衡

    在看完负载均衡的需求之后再来看看如何通过配置文件实现它,在介绍配置文件之前先来介绍一下DestinationRule 的规则描述。

     

    如果说VirtualService是一个虚拟Service其描述的内容是“从服务流出的请求被哪个服务处理”,那么 DestinationRule 描述的是“流入的请求到达服务之后如何处理,从字面意思理解就是目标规则,如果落到负载均衡的这个例子上来说,也就是流量到达Service B的两个版本(V1V2)以后如何进行访问。

     

    如代码段3所示,按照红色数字的顺序如下:

    1. 规则配置定义为DestinationRule,表示处理服务流入的请求。
    2. 这里请求流入的服务是Service B,其从在两个版本,每个版本都是以集群的方式存在的。
    3. 针对Service B 版本V2 的情况,在trafficPolicy(流量规则)的loadBalancer(负载均衡)中使用了ROUND_ROBIN 的策略。
    4. 同样,针对Service B 版本V1 的情况,在trafficPolicy(流量规则)的loadBalancer(负载均衡)中使用了RANDOM 的策略。

     

    代码段3

     

    上面Istio服务治理的功能介绍,主要围绕服务之间的关系展开的,通过配置文件中节点数据的调整定义服务之间的关系,获取这种方式对于开发者理解其工作原理有些抽象,为了方便理清服务之间的关系并且对其进行有效管理,Istio提供了可视化的服务网格工具-Kiali,针对服务拓扑图、全链路跟踪、指标遥测、配置校验、健康检查等功能提供可视化的界面。

     

    这里着重介绍服务拓扑图的功能,由于篇幅的关系这里不介绍Kiali的安装,有兴趣的同学可以去Istio的官网查看。如图8 所示,登陆Kiali以后可以看到其Overview界面,其中包括网格里面所有命名空间的服务。

     

    8 

    Kiali overview 界面

    如果要查看对应的服务,例如:Bookinfo,可以点击 Bookinfo 命名空间卡片,显示如图9所示的内容。这里展示了该命名空间下服务的调用情况。注意看上方红色框出的部分:Graph Type,这里可以选择服务显示的类型,也就是说通过不同形式展示服务之间的关系。目前有四种可以选择AppVersioned AppWorkload 以及 Service

     

    9 

    Bookinfo命名空间下的服务关系图

    选择App 类型会将同一应用的所有版本聚合到单点上,如图10所示,网格外部的请求通过istioingressgateway调用productpage服务,productpage分别会调用details服务和reviews服务。其中reviews会依次调用ratings服务和mongedbApp类型的服务关系展示,通过简洁的方式描述了服务之间的依赖(调用)关系,没有涉及到服务的具体版本。

     

    1

    App 类型调用

    Versioned App 类型会App类型的基础上,将每个服务的版本显示出来。如图11 所示,可以看出productpage服务只有一个版本v1,但是reviews服务有v1v2v3三个版本,ratings有两个版本。这种方式的现实让服务调用的版本更加清晰。

     

    图11 

    Versioned App 类型

    Workload 类型又在Versioned App 类型的基础上,针对每个服务的workload进行了显示上的转换。如图12 所示,将每个服务的版本作为一个workload,通过圆形的方式显示,实际上每个圆形的workload在实际调用中也是一个实体。

     

    图12 

    Workload 类型

    最后是Service 类型,如图13所示,它为网格中的每个服务生成一个节点,但是会排除所有的应用和工作负载。

     

    图13 

    Service 类型

     

     总结 

    本文从服务治理作为切入点,描述了在分布式、微服务的环境下为什么需要Istio提供服务治理的功能。Istio能够将业务逻辑与服务治理的SDK进行解耦,能够支持不同技术开发的分布式服务/应用的服务治理。同时指出Istio是包含的连接(Connect)、安全(Secure)、控制(Control)和观察(Observe)等功能。以及在这些功能的支撑下,Istio的基本架构是如何工作的。在架构原理中通过九个步骤,将控制面的Pilot、Mixer、Galley和Citadel,以及数据面的Envoy的工作流程给大家梳理了一遍。最后针对使用频度较高的服务治理功能:服务路由、流量切分、负载均衡进行了展开描述

    END

    征 稿

    有酬投稿

    愿意技术分享的朋友,欢迎投稿,每篇文章提供 800 ~ 1000 元的稿酬,投稿请扫描下方二维码,添加微信:jeversoncui

     

    本站所有文章均由网友分享,仅用于参考学习用,请勿直接转载,如有侵权,请联系网站客服删除相关文章。若由于商用引起版权纠纷,一切责任均由使用者承担
    极客文库 » Istio 架构原理解析

    常见问题FAQ

    如果资源链接失效了怎么办?
    本站用户分享的所有资源都有自动备份机制,如果资源链接失效,请联系本站客服QQ:2580505920更新资源地址。
    如果用户分享的资源与描述不符怎么办?
    可以联系客服QQ:2580505920,如果要求合理可以安排退款或者退赞助积分。
    如何分享个人资源获取赞助积分或其他奖励?
    本站用户可以分享自己的资源,但是必须保证资源没有侵权行为。点击个人中心,根据操作填写并上传即可。资源所获收益完全归属上传者,每周可申请提现一次。
    如果您发现了本资源有侵权行为怎么办?
    及时联系客服QQ:2580505920,核实予以删除。

    参与讨论

    • 155会员总数(位)
    • 3735资源总数(个)
    • 0本周发布(个)
    • 0 今日发布(个)
    • 382稳定运行(天)

    欢迎加入「极客文库」,成为原创作者从这里开始!

    立即加入 了解更多
    成为赞助用户享有更多特权立即升级