Istio流量管理的核心组件是Pilot,它管理和配置部署在特定Istio服务网格中的所有Envoy代理实例。它允许您指定在Envoy代理之间使用什么样的路由流量规则,并配置故障恢复功能,如超时,重试和熔断器。它还维护了网格中所有服务的规范模型,并使用这个模型,来通过发现服务让Envoy了解网格中的其他实例。每个Envoy实例维护负载均衡信息,负载均衡信息是基于从Pilot获得的信息,以及其负载均衡池中的其他实例的定期健康检查。从而允许其在目标实例之间智能分配流量,同时遵循其指定的路由规则。
流量管理的好处:使用Istio的流量管理模型,本质上解耦流量和基础设施扩展,让运维人员通过Pilot指定他们希望流量遵循什么规则,而不是哪些特定的pod/VM应该接收流量 - Pilot和智能Envoy代理搞定其余的。因此,例如,您可以通过Pilot指定您希望特定服务的5%流量可以转到金丝雀版本,而不考虑金丝雀部署的大小,或根据请求的内容将流量发送到特定版本。Pilot负责在Isti服务网格中部署的Envoy实例的生命周期。下图是pilot架构:
Pilot维护了网格中的服务的规范表示,这个表示是独立于底层平台的。Pilot中的平台特定适配器负责适当填充此规范模型。例如,Pilot中的Kubernetes适配器实现必要的控制器来查看Kubernetes API服务器,以得到pod注册信息的更改,入口资源以及存储流量管理规则的第三方资源。该数据被翻译成规范表示。Envoy特定配置是基于规范表示生成的。Pilot公开了用于服务发现 、负载均衡池和路由表的动态更新的 API。这些API将Envoy从平台特有的细微差别中解脱出来,简化了设计并提升了跨平台的可移植性。运维人员可以通过Pilot的Rules API指定高级流量管理规则。这些规则被翻译成低级配置,并通过discovery API分发到Envoy实例。如Pilot所述,特定网格中服务的规范表示由Pilot维护。服务的Istio模型和在底层平台(Kubernetes,Mesos,Cloud Foundry等)中的表示无关。特定平台的适配器负责用平台中元数据的各种字段填充内部模型表示。Istio介绍了服务版本的概念,这是一种更细微的方法,可以通过版本( v1 , v2 )或环境( staging , prod )细分服务实例。这些变量不一定是API版本:它们可能是对不同环境(prod,staging,dev等)部署的相同服务的迭代更改。使用这种方式的常见场景包括A/B测试或金丝雀推出。Istio的流量路由规则可以参考服务版本,以提供对服务之间流量的附加控制。
服务间的通信:服务的客户端不知道服务不同版本间的差异。他们可以使用服务的主机名/IP地址继续访问服务。Envoy sidecar/代理拦截并转发客户端和服务器之间的所有请求/响应。运维人员使用Pilot指定路由规则,Envoy根据这些规则动态地确定其服务版本的实际选择。该模型使应用程序代码能够将它从其依赖服务的演进中解耦出来,路由规则允许Envoy根据诸如header,与源/目的地相关联的标签和/或分配给每个版本的权重的标准来选择版本。Istio还为同一服务版本的多个实例提供流量负载均衡。可以在服务发现和负载均衡中找到更多信息。Istio不提供DNS。应用程序可以尝试使用底层平台(kube-dns,mesos-dns等)中存在的DNS服务来解析FQDN。
虚拟服务和路由规则:Virtual Service让您配置如何在服务网格内将请求路由到服务,这基于 Istio 和平台提供的基本的连通性和服务发现能力。每个虚拟服务包含一组路由规则,Istio 按顺序评估它们,Istio 将每个给定的请求匹配到虚拟服务指定的实际目标地址。通过对客户端请求的目标地址与真实响应请求的目标工作负载进行解耦来实现。虚拟服务同时提供了丰富的方式,为发送至这些工作负载的流量指定不同的路由规则。如果没有虚拟服务,Envoy 会在所有的服务实例中使用轮询的负载均衡策略分发请求。使用虚拟服务,您可以为一个或多个主机名指定流量行为。在虚拟服务中使用路由规则,告诉 Envoy 如何发送虚拟服务的流量到适当的目标。路由目标地址可以是同一服务的不同版本,也可以是完全不同的服务。整体来说就是作用,1)通过单个虚拟服务处理多个应用程序服务,可以配置一个虚拟服务处理特定命名空间中的所有服务。2)和网关整合并配置流量规则来控制出入流量。以示例解读具体参数:
apiVersion: networking.istio.io/v1alpha3 hosts
字段列举虚拟服务的主机—即用户指定的目标或
kind: VirtualService 是路由规则设定的目标。这是客户端向服务发送请求时
metadata: 使用的一个或多个地址,值可以是IP地址、DNS名称等
name: reviews 可以用通配符(“*”)前缀,创建一组匹配所有服务的路
spec: 由规则在http
字段包含了虚拟服务的路由规则,用来描
hosts: 述匹配条 件和路由行为,把不同协议流量发送到hosts字
- reviews 段指定的目 一个路由规则包含了指定的请求要流向哪个
http: 目标地址,具有0或多个匹配条件,取决于使用场景
- match: destination
字段指定了符合此条件的流量的实际目标地
- headers: 址destination的host要是存在于Istio服务注册中心的实
end-user: 址。destination的Envoy不知该将请求发送到哪里。可
route: 以是一个有代理的服务网格,或者是一个通过服务入口
- destination: 被添加进来的非网格服务路由规则按从上到下的顺序选
host: reviews 择,虚拟服务中定义的第一条规则有最高优先级。本示
subset: v2 例中不满足第一个路由规则的流量均流向一个默认的目
- route: 标该目标在第二条规则中指定。因此,第二条规则没有
- destination: match 条件直接将流量导向v3子集。路由规则是将特定
host: reviews 流量子集路由到指定目标地址的强大工具。可以在流量
subset: v3 端口、header 字段、URI 等内容上设置匹配条件
目标规则:可以将虚拟服务视为将流量如何路由到给定目标地址,然后使用目标规则来配置该目标的流量。在评估虚拟服务路由规则之后,目标规则将应用于流量的“真实”目标地址。可以将虚拟服务视为将流量如何路由到给定目标地址,然后使用目标规则来配置该目标的流量。在评估虚拟服务路由规则之后,目标规则将应用于流量的“真实”目标地址。默认情况下,Istio 使用轮询的负载均衡策略,实例池中的每个实例依次获取请求。Istio 同时支持如下的负载均衡模型,可以在 DestinationRule
中为流向某个特定服务或服务子集的流量指定这些模型。三种常用算法:1)随机:请求以随机的方式转到池中的实例。2)权重:请求根据指定的百分比转到实例。3)最少请求:请求被转到最少被访问的实例。
网关:Ingress和Egress。使用网关为网格来管理入站和出站流量,可以指定要进入或离开网格的流量。网关配置被用于运行在网格边界的独立 Envoy 代理,而不是服务工作负载的 sidecar 代理。Istio假定进入和离开服务网络的所有流量都会通过Envoy代理进行传输。通过将Envoy代理部署在服务之前,运维人员可以针对面向用户的服务进行A/B测试,部署金丝雀服务等。类似地,通过使用Envoy将流量路由到外部Web服务(例如,访问Maps API或视频服务API),运维人员可以添加故障恢复功能,例如超时,重试,熔断器等,并在访问这些服务的连接上获得详细指标。
处理故障:Envoy提供了一套开箱即用, 选择加入的故障恢复功能,可以在应用程序中受益。功能包括:
1. 超时:超时是 Envoy 代理等待来自给定服务的答复的时间量,以确保服务不会因为等待答复而无限期的挂起,并在可预测的时间范围内调用成功或失败。HTTP 请求的默认超时时间是 15 秒,这意味着如果服务在 15 秒内没有响应,调用将失败。
2. 带超时预算有限重试和重试之间的可变抖动:重试设置指定如果初始调用失败,Envoy 代理尝试连接服务的最大次数。通过确保调用不会因为临时过载的服务或网络等问题而永久失败,重试可以提高服务可用性和应用程序的性能。重试之间的间隔(25ms+)是可变的,并由 Istio 自动确定,从而防止被调用服务被请求淹没。默认情况下,在第一次失败后,Envoy 代理不会重新尝试连接服务。
3. 熔断器:熔断器是 Istio 为创建具有弹性的微服务应用提供的另一个有用的机制。在熔断器中,设置一个对服务中的单个主机调用的限制,例如并发连接的数量或对该主机调用失败的次数。一旦限制被触发,熔断器就会“跳闸”并停止连接到该主机。使用熔断模式可以快速失败而不必让客户端尝试连接到过载或有故障的主机。
4. 故障注入:在配置了网络,包括故障恢复策略之后,可以使用 Istio 的故障注入机制来为整个应用程序测试故障恢复能力。故障注入是一种将错误引入系统以确保系统能够承受并从错误条件中恢复的测试方法。使用故障注入特别有用,能确保故障恢复策略不至于不兼容或者太严格,这会导致关键服务不可用。
这些功能可以通过Istio的流量管理规则在运行时进行动态配置。重试之间的抖动使重试对重载的上游服务的影响最小化,而超时预算确保主叫服务在可预测的时间范围内获得响应(成功/失败)。主动和被动健康检查的组合最大限度地减少了在负载平衡池中访问不健康实例的机会。当与平台级健康检查(例如由Kubernetes或Mesos支持的检查)相结合时,应用程序可以确保将不健康的pod/container/VM快速地从服务网格中去除,从而最小化请求失败和延迟产生影响。总之,这些功能使得服务网格能够容忍故障节点,并防止本地化的故障级联不稳定到其他节点。Istio 故障恢复功能对应用程序来说是完全透明的。在返回响应之前,应用程序不知道 Envoy sidecar 代理是否正在处理被调用服务的故障。这意味着,如果在应用程序代码中设置了故障恢复策略,那么您需要记住这两个策略都是独立工作的,否则会发生冲突。例如,假设您设置了两个超时,一个在虚拟服务中配置,另一个在应用程序中配置。应用程序为服务的 API 调用设置了 2 秒超时。而您在虚拟服务中配置了一个 3 秒超时和重试。在这种情况下,应用程序的超时会先生效,因此 Envoy 的超时和重试尝试会失效。虽然 Istio 故障恢复特性提高了网格中服务的可靠性和可用性,但应用程序必须处理故障或错误并采取适当的回退操作。例如,当负载均衡中的所有实例都失败时,Envoy 返回一个HTTP 503
代码。应用程序必须实现回退逻辑来处理HTTP 503
错误代码。
规则配置实例:Istio提供了简单的领域特定语言(DSL),用来控制应用部署中跨多个服务的API调用和4层流量。DSL允许运维人员配置服务级别的属性,如熔断器,超时,重试,以及设置常见的连续部署任务,如金丝雀推出,A/B测试,基于百分比流量拆分的分阶段推出等。例如,将“reviews”服务100%的传入流量发送到“v1”版本的简单规则,可以使用规则DSL进行如下描述:
apiVersion: config.istio.io/v1alpha2 destination是服务的名称,流量将被导向到这里route
kind: RouteRule lables标记将接受流量的特定服务实例,destination 的
metadata: 值隐式或者显式地指定一个完全限定域名FQDN) Pilot
name: reviews-default 用它来给服务匹配规则。通常服务的FQDN由三个部分
spec: 组成:name, namespace,和domain:namespace的默
destination: 认值是规则自身的namespace.路由规则控制如何在Istio
name: reviews 服务网格中路由请求。例如路由规则可以将请求路由到
route: 服务的不同版本。可以基于源和目的地,HTTP header
- labels: 字段以及与个别服务版本相关联的权重来路由请求。
version: v1 2)如过限制为调用者的特定版本,规则书写为如下方
weight: 100 蓝色部分,仅适用于"reviews"服务的"v2"版本的调用
spec: 3)选择基于HTTP header的规则,以下规则仅适用于传
destination: 入请求包含"cookie" header, 并且内容包含"user=jason"
name: ratings 规则定义如橙色部分,只需在match下添加相应规则如果
match: 提供了多个属性值对,则所有相应的 header 必须与要应
source: 用的规则相匹配。可以同时设置多个标准。在这种情况下
name: reviews AND语义适用。如仅适用于请求的source为"reviews:v2",
request: 并且有包含"user=jason"的"cookie" header。与这个规则
headers: 的差别在source:里定义name: reviews labels:version: v2。
cookie: 当规则被激活时,每个路由规则标识一个或多个要调用的
regex: "^(.*?;)?(user=jason)(;.*)?$" 加权后端。每个后端对应于目标服务的特定版本,其
route: 超时和重试缺省情况下,http请求的超时时间为15秒,但
- labels: 可以在路由规则中覆盖,如左边规则设置为10秒,对于给
version: v1 定的http请求,重试次数可以也可以在路由规则中指定,只
httpReqTimeout: 将httpReqTimeout改为httpReqRetries: 将simpleTimeout
simpleTimeout: 改为simpleRetry:最后timeout改为attempts: 3
timeout: 10s
httpFault: 4)在请求路径中注入故障,在将http请求转发到规则的相
delay: 应请求目的地时,可以指定一个或多个要注入的故障如左
percent: 10 侧的延时路由规则。中断可以用来提前终止请,求将服务
fixedDelay: 5s 的10%请求返回HTTP 400错误代码fixed改为httpStatus:400
规则有优先权:多个路由规则可以应用于同一目的地。当有多个规则时,可以指定规则的评估顺序。这些规则与给定目的地相对应的,通过规则的precedence字段来设置。规则配置precedence: 1。precedence字段是可选的整数值,默认为0。首先评估具有较高优先级值的规则。如果有多个具有相同优先级值的规则,则评估顺序是未定义的。优先级什么时候有用? 只要特定服务的路由故障纯粹是基于权重的,可以在单个规则中指定,如前面的示例所示。另一方面,当正在使用的其他标准(例如,来自特定用户的请求)来路由流量时,将需要多于一个的规则来指定路由。这是必须设置规则precedence字段的时候,以确保以正确的顺序对规则进行评估。一般路由规范的通用模式是提供一个或多个较高优先级的规则,通过到特定destination的source/header来修饰规则,然后提供单个基于权重的规则,连最低优先级的匹配准则都不具备,以在所有其他情况下,提供流量的加权分发。
source : 5)目的地策略:描述与特定服务版本相关联的各种路由
name: reviews 相关策略,例如负载均衡算法,熔断器配置,健康检查等
labels: 与路由规则不同,目的地策略不能根据请求的属性进行修
version: v2 饰,但是,可以限制策略适用于某些请求,这些请求是使
destination: 用特定标签路由到destination后端的。例如左侧负载均
name: ratings: 衡策略仅适用于针对"reviews"服务器的"v1"版本的请求
labels: 6)熔断器:可以根据如连接和请求限制的多个标准来设
version: v1 置简单的熔断器。如目的地设置到服务版本为"v1"后端
loadBalancing: 为100个连接的限制。 将loadBalancing换成circuitBreaker,
name: ROUND_ROBIN 然后添加simpleCb:,在添加maxConnections: 100
apiVersion: config.istio.io/v1alpha2 7)出站规则:出站规则用于配置需要在服务网格中被调用
kind: EgressRule 的外部服务。左面规则可以被用来配置在 *.foo.com域名下
metadata: 下的外部服务。外部服务的地址通过svc字段指定,该字段可
name: foo-egress-rule 以是一个完全限定域名(Fully QualifiedDomain Name,FQDN)
spec: 也可以是一个带通配符的域名。它代表了可在服务网格中
destination: 访问的外部服务的一个白名单,该名单包括一个(字段值
service: *.foo.com 为完全限定域名的情况)或多个外部服务(字段值为带通配符
ports: 域名的情况)。这里可以找到svc字段支持的域名通配符
- port: 80 格式总的来说:目的地策略和路由规则的流量重定向和前
protocol: http 转,重试超时,故障注入策略等特性都可以很好地支持外
- port: 443 部服务。但是由于外部服务没有多版本的概念,和服务版
protocol: https 本关联的按权重的路由规则是不支持的。