istio的流量治理(负载均衡 熔断 故障注入 灰度)与各种配置实例 与VIrtualService(路由规则配置)

服务治理要解决的问题:
1) 服务的负载均衡
2)同一个服务有两个版本在线,将一部分流量切到某个版本上
3)服务保护,如限制并发连接数、请求数、隔离有故障的服务实例等
4)动态修改服务中的内容

istio流量治理目标:提供非侵入的流量治理,用户仅仅关注自己的业务逻辑,无须关注服务访问管理。

流量治理的流程:

控制面:
1)管理面创建流量规则
2)pilot将流量规则转换为envoy的标准格式
3)pilot将规则下发给envoy
数据面:
1)envoy拦截Pod上本地容器的Inbound和outbound流量
2)在流量经过envoy时执行对应的流量规则,对流量进行治理

具体流量治理的能力
3.1.1 负载均衡
含义:在服务发起方使用一个服务名发起访问的时候能找到一个合适的后端,把流量导过去。

传统的负载均衡方式:
一般是在服务端进行。如浏览器访问一个web网站时,一般在网站的入口处有一个负载均衡器来做请求的汇聚和转发,如常用的nginx。
原理:服务的虚拟IP和后端实例通过一个静态配置文件来维护,负载均衡器通过健康检查保证客户端的请求被路由到健康的后端实例中。
如图:


微服务的负载均衡
如下图:


主要流程:
1)服务注册:各服务将服务名和服务实例对应的信息注册到服务注册中心
2)服务发现:客户端发起服务访问前,以同步或异步的方式从服务注册中心获取服务对应的实例列表
3) 负载均衡:根据配置的负载均衡算法从实例列表中选择一个服务实例。


istio的负载均衡
跟微服务的方式类似,pilot就是服务注册中心,envoy执行负载均衡。
isito目前支持的负载均衡算法:轮询、随机、最小连接数算法

k8s中支持service的重要组件kube-proxy也是运行在工作节点的网络代理和负载均衡器。如下图:


3.1.2 服务熔断
熔断器:在检测到如短路、电流过大时自动断路,在故障时保证电路不受损。
延伸到it中,系统发生临时故障或意外时,通过立刻返回调用失败的方式,防止网络和服务调用故障级联发生,避免故障蔓延而导致系统整体雪崩或不可用。

熔断器的逻辑:
熔断器封装了被保护的逻辑,监控调用是否失败,当连续调用失败的数量超过阈值,熔断器就会跳闸;
在跳闸后的一定时间段内,所有调用远程服务的尝试都将立即返回失败;
同时,熔断器设置了一个计时器,当计时到期时,允许有限数量的测试请求通过;
如果这些请求成功,则熔断器恢复正常操作;如果这些 请求失败,则维持断路状态。

熔断器的状态,下面分别进行解释。
◎ 熔断关闭:熔断器处于关闭状态,服务可以访问。熔断器维护了访问失败的计数器,若服务访问 失败则加一。
◎ 熔断开启:熔断器处于开启状态,服务不可访问,若有服务访问则立即出错。
◎ 熔断半开启:熔断器处于半开启状态,允许对服务尝试请求,若服务访问成功则说明故障已经得到解决,否则说明故障依然存在。

1 Hystrix熔断
主要功能:
有一般熔断器的功能,且有如下功能:
对每个服务都维护一个连接池,连接池满时直接拒绝访问
提供实时监控、告警和操作控制

实现上:封装在一个HystrixCommand中,将熔断功能应用到调用的方法上,监视对该方法的失败调用,当失败次数达到阈值,后续调用自动失败并被转到Fallback方法上。
hystrix除了提供了熔断,还提供了对线程池的管理,减少和限制了当个服务故障对整个系统的影响。


2 Istio熔断
非侵入,包括isito提供的连接池管理和异常点检测
1)连接池管理:限制某个客户端对目标服务的连接数、访问请求数,避免对一个服务过量访问,如果超过配置的阈值,则快速断路请求。限制重试次数,避免增加系统压力。
2)异常点检测:如果服务实例平凡超时或出错,则将该实例隔离,不再对外提供服务。一段时间后再尝试重新启用。但istio可以控制驱逐比例:
当有太多实例被驱逐时,就会进入恐慌模式,这时会忽略负载均衡池上实例的健康标记,仍然会向所有的实例发送请求,保证服务的整体可用。

如 通过istio的连接池管理控制fronted服务队forecast服务的请求
1)fronted服务对目标服务forecast的请求不超过配置的最大连接数时,放行
2)fronted服务对目标服务forecast的请求超过配置的最大连接数时,但小于配置的最大请求等待数时,进入连接池等待
3)fronted服务对目标服务forecast的请求超过配置的最大请求等待数时,直接拒绝。

如图:

3.1.3 故障注入
故意在待测试的系统中引入故障,从而测试其健壮性和应对故障的能力。
实现方式:
1)编译期故障注入,需要通过修改代码来模拟故障。
2)运行期故障注入,运行阶段触发。而在分布式系统中,最常用的方法就是在网络协议栈中注入故障。
istio就是采用该方式:在网格中对特定的应用层进行故障注入,虽然在网络访问阶段进行注入,但其作用于应用层。
httpcode注入实例:
如图


慢响应注入实例
如图:

 

3.1.4 灰度发布
原因:技术上产品的稳定性或商业上考虑新版本被用户接受的程度,直接将老版本全部升级是有风险的。所以一般做法是,新老版本同时在线,新版本只接入少量流量。

典型场景包括蓝绿发布(新的替代老的)、ABtest(两个新对比)、金丝雀(只有新)。
三者的核心都是流量的管理,能否支持灵活的流量策略是核心。有如下几种方式:
1 基于负载均衡的灰度发布
该方式要求负载均衡器必须支持相应的流量策略,并且只能对入口的服务做灰度,不支持对后端的服务单独做灰度发布。

2 基于k8s的灰度发布
如:forecast服务的两个版本v2和v1分别有两个和3个实例,流量被均衡的分发到每个实例上时,v2得到40%流量,v1则60%。
问题:
1)要求分配的数量必须和pod的数量成比例
2)不支持根据请求的内容来分配流量,比如要求chrome和Ie的请求分别访问不同版本

3 基于istio的灰度发布
灰度发布是istio流量治理规则的一种典型应用。istio在每个pod中都注入了envoy,因此只要在控制面配置分流策略,对目标服务发起访问的每个envoy都会执行流量策略,完成会发布功能。

pilot中配置recommendation中80%流量到v1版本,20%到v1;pilot将规则下发到每个数据面的envoy。
如下图:

istio也支持基于请求内容的灰度策略。如根据header中的内容将请求分发到不同的版本上。
如下图:

3.1.5 服务访问入口
一般都会有一个入口服务,从外部可以访问,接收外部的请求并转发到后端的服务,还可以在入口处定义统一的过滤器实现限流、权限校验的功能。
1 k8s服务的访问入口
方式一:将服务发布成loadbalancer类型的Service,通过一个外部端口就能访问到集群中的指定服务。
方式二:针对七层协议的ingress方式,ingress作为一个总的入口,根据七层协议中的路径将服务指向不同的后端服务。

2 istio服务访问入口
istio中通过gateway访问内部服务。该gateway和其他网格内的sidecar一样,也是一个envoy,从istio的控制面接收配置,统一执行配置的规则。

3.1.6 外部接入服务治理
实现一个完整的功能,需要依赖外部的服务,那外部服务istio如何管理呢?
k8s中,使用service catalog的扩展机制可以方便的在集群中管理云服务商提供的第三方服务,
如下图:

istio如何管理呢?
在istio中是通过一个serviceEntry的资源对象将网格外的服务注册到网格上,然后像对网格内的普通服务一样对网格外的服务访问进行治理的。

如下图:


在pilot中创建一个serviceEntry,配置后端数据库的访问信息,在istio的服务发现中就会维护该服务,并对该服务配置规则进行治理,从forecast向数据库发起的访问进过envoy时就会被拦截和治理。

3.2 istio路由规则配置:VirtualService
VirtualService是istio流量治理的核心配置,重要而复杂。

3.2.1 路由规则配置示例

含义:对于forecast服务的访问,如果在请求的Header中location取值是north,则将该请求转发到服务的v2版本上,其他请求转发到服务的v1版本上。

3.2.2 路由规则定义
virtualService:用于定义对特定目标服务的一组流量规则。描述一个具体的服务对象,包含了对流量的各种处理。

virtualService中的术语:
service:服务
service version:服务版本
source: 发起调用的服务
Host: 服务调用方连接和调用目标服务时使用的地址

virtual Service完整规则的结构很复杂。

先看下virtualService的1级定义,包括通用字段hosts、gateways,复合字段HttpRoute、TCPRoute、TLSRoute,表示istio支持的http\TCP\TLS协议的流量规则。

hosts和gateways是每种协议都要用到的公共字段。
1 hosts
必选,表示流量发送的目标。用于匹配访问地址,可以是一个DNS名称或IP地址。
DNS可以使用通配符前缀,也可以使用短域名。但是建议在规则中明确写完整的域名。

对k8s平台来说,hosts中一般是Service的短域名。如forecast对应的完整域名是:
forecast.weather.svc.cluster.local,其中weather是forecast服务部署的命名空间。
isito中,hosts的全域名是forecats.default.svc.cluster.local。其中命名空间default是virtualService的命名空间,不是Service的命名空间。

2 gateways
标识应用这些流量规则的gateway。VirtualService描述的规则可以作用到网格里的Sidecar和入口处的Gateway。具体场景如下:
1)服务仅在网格内访问,规则也仅作用于网格内的sideCar。此时gateways字段可以省略。
2)服务仅在网格外访问,需要配置关联的Gateway,对应gateway进来的流量执行在这个VirtualService上定义的规则。
3)服务在网格内核网格外都要访问,那对gateways数组字段至少配置两个元素,一个是是外部访问的gateway,另一个是保留关键字”mesh“。

3 http
用于处理http的流量,是一个与HTTPRoute类似的路由集合

4 tls
用于处理非终结的TLS和HTTPS的流量,是一个TLSRoute类型的路由集合。

5 tcp
用于处理TCP的流量,所有其他非HTTP和TLS端口的流量,是一个TCPRoute类型的路由集合

说明:http tls tcp3各字段在定义上都是数组,可以定义多个元素;使用上都是一个有序列表,应用时匹配的第一个规则生效。

6 exportTo
新增字段,控制VirtualService跨命名空间的可见性,即VirtualService是否可以被其他命名空间下的sidecar和Gateway使用。
默认全局可见。 .表示仅应用到当前命名空间, *表示应用到所有的命名空间。

3.2.3 HTTP路由
1 http是当前最通用、内容最丰富的协议。除了可以路由,还可以进行如:重定向、重写、重试、流量镜像、故障注入、跨资源共享等操作。
实际的协议包括:http http2 grpc

2 http的配置规则
支持将uri schema method authority port等作为条件来匹配。
URI 的完整格式是:URI=scheme:[//authority]path [?query][#fragment]
Authority的标准定义是:“authority=[userinfo@]host[:port]

具体匹配规则:
1)uri schema method authority都是StringMatch类型,在匹配时支持extract-全部匹配、prefix-前缀匹配、regex-正则匹配
2)headers map类型,也可以采用全部、前缀、正则三种方式匹配。

匹配headers中source取值为north,并且uri以/advertisement开头的请求
3)port 请求的服务端口
4)sourcelabels map类型的键值对,标识请求来源的负载匹配标签。可以对一组服务都打一个相同的标签,然后使用sourceLabels字段对这些服务试试相同的流量规则。
k8s平台中,label就是pod上的标签。

标识请求来源是frontend服务的v2版本负载。
5)gateways:规则应用的gateway名称

匹配逻辑:HTTPMatchRequest中多个match是或的关系,
某个match中的诸多属性如uri、 headers、method等是“与”逻辑,而属性数组中几个元素间的关系是“或”逻辑。

match有两个,其条件的语义是:headers中的source取值 为“north”,并且uri以“/advertisement”开头的请求,或者uri以“/forecast”开头的请求。

3 httpRouteDestination
表示满足条件的流量目标。是一个HTTPRouteDestination类型的数组,主要有三个字段:destination(请求目标)、weight(权重)和headers(HTTP头操作),其中destination和weight是必选字段
1) destination
表示请求的目标。通过host、subset、port三个属性来描述。
host:必选字段,istio中注册的服务名,包括网格内服务和通过serviceEntry方式注册的外部服务。建议写全域名。
subset:表示host上定义的一个子集。如灰度发布中将版本定义为subset,路由策略将流量转发到不同版本的subset上。

2)weight
除了destination,route上的另一个必选字段时weight,表示流量分配的比例,在一个route下多个destination的weight的综合要求是100.
如果一个route仅有一个destination,那么可以不用配置weight。

3)headers
提供对http header的操作,可以修改http请求中request或response的值。
request:发请求给目标地址时修改request的header
response: 返回应答时修改response的Header

对应的操作包括:
set:使用map上的Key和Value覆盖Request或者Response中对应的Header。
add:追加map上的Key和Value到原有Header。
remove:删除在列表中指定的Header。

4 httpRedirect
发送301的重定向应答给服务调用方。如下场景:
有一个在线网站,网址变了,通过这样的重定向,可以在用户输入老地址时 跳转到新地址。

httpRedirect的两个字段:
uri:替换url的path部分
authority:替换url中的authority部分
如下所示,对 forecast 服务所有前缀是“/advertisement”的请求都会被重定向到new-forecast
的“/recommendation/activity”地址:

5 http重写
将请求转发给目标服务前修改http请求中指定部分的内容。重写 HTTPRewrite 也包括 uri 和 authority 这两个字段:
◎ uri:重写URL中的Path部分。
◎ authority:重写URL中的Authority部分。
前缀匹配“/advertisement”的请求,其请求 uri 中的这部分前缀会被“/recommendation/activity”替换:

6 http重试
重试规则可以一定程度上避免服务调用失败。
重试策略包括重试次数、超时、重试条件等,这里分别 描述相应的三个字段。
◎ attempts:必选字段,定义重试的次数。
◎ perTryTimeout:每次重试的超时时间,单位可以是毫秒(ms)、秒(s)、分钟(m)和小时 (h)。
◎ retryOn:进行重试的条件,可以是多个条件,以逗号分隔。包括5xx,gateway-error,connect-failure等。
下示例为 forecast 服务配置了一个重试策略,在“5xx,connect-failure”条件下进行最多5次重试,每次重试的超时时间是3秒:

7 http流量镜像
在流量转发到目标地址的同时,将流量给另外一个目标地址镜像一份。

8 http故障注入
修改HTTP请求或者 应答的内容。需要注意,在使用故障输入时不能启用超时和重试。故障类型包括:
1)延迟故障注入
表示在发送请求前 进行一段延时,模拟网络、远端服务负载等各种原因导致的失败,主要有如下两个字段。
◎ fixedDelay:一个必选字段,表示延迟时间,单位可以是毫秒、秒、分钟和小时,要求时间必须大于1毫秒。
◎ percentage:配置的延迟故障作用在多少比例的请求上,通过这种方式可以只让部分请求发生故 障。
如下所示为让forecast服务的v2版本上百分之1.5的请求产生10秒的延迟:

2)请求中止故障注入
模拟服务端异常,给调用的客户端 返回预先定义的错误状态码,主要有如下两个字段。
◎ httpStatus:是一个必选字段,表示中止的HTTP 状态码。
◎ percentage:配置的中止故障作用在多少比例的请求上,通过这种方式可以只让部分请求发生故 障,用法同延迟故障。
让forecast服务v2版本上百分之1.5的请求返回“500”状态码:

9.HTTP跨域资源共享(CorsPolicy)
当一个资源向该资源所在服务器的不同的域发起请求时,就会产生一个跨域的HTTP 请求。浏览器会限制从脚本发起的跨域HTTP请求。

◎allowOrigin:允许跨域资源共享的源的列表,在内容被序列化后,被添加到Access-Control-Allow- Origin的Header上。当使用通配符“*”时表示允许所有。
◎ allowMethods:允许访问资源的HTTP方法列表,内容被序列化到Access-Control-Allow-Methods的 Header上。
◎ allowHeaders:请求资源的HTTP Header列表,内容被序列化到Access-Control-Allow-Headers的 Header上。
◎ exposeHeaders:浏览器允许访问的 HTTP Header 的白名单,内容被序列化到Access-Control- Expose-Headers的Header上。
◎ maxAge:请求缓存的时长,被转化为Access-Control-Max-Age的Header。
◎ allowCredentials:是否允许服务调用方使用凭据发起实际请求,被转化为Access-Control-Allow- Credentials的Header。

给forecast服务配置跨域策略,允许源自news.com的GET方法的请求的访问:
请求示意图


配置 图

3.2.4 TLS路由
应用于https和TLS协议中。TLSRoute的规则定义比HTTPRoute要简单的多,只有匹配规则TLSMatchAttributes和路由规则目标RouteDestination

1 TLSRoute配置实例

说明:从外面访问weather应用内部的两个https服务;
访问目标端口是443且SNI是”frontend.weather.com“的请求会被转发到frontend上;
访问目标端口是443且SNI是”recommendation.weather.com“的请求会被转发到recommendation服务。


2 TLS匹配规则
TLSMatchAttributes的属性:
1)sniHosts:必选字段,server name indication,目标服务的名称定义,用来匹配TLS请求的SNI。SNI的值必须是VirtualService的hosts的子集
2)destinationSubnets:目标IP地址匹配的IP子网
3)port:访问的目标端口
4)sourceLabels:map类型的键值对,匹配请求的标签
5)gateways:表示规则适用的gateway名字
其中shiHosts和destinationSubnets属性是TLS特有的。
一般的用法是匹配ports和sniHosts,配置如下:
tls:
- match:
  - port: 443
      sniHosts:
      - frontend.weather.com

3 四层路由目标RouteDestination
转发的目的地址,包含两个必选属性destination和weight
destination:标识满足条件的流量的目标
weight:流量比例


3.2.5 TCP路由
所有不满足以上http和TLS条件的流量都会应用到本节要介绍的TCP流量规则。
1 TCPRoute配置示例
将来自forecast服务23003端口的流量转发到inner-forecast服务的3003端口。
如图:

TCPRoute 中,match 字段也是一个数组,元素类型是 L4MatchAttributes,支持以下匹配属性。
◎ destinationSubnets:目标IP地址匹配的IP子网。
◎ port:访问的目标端口。
◎ sourceLabels:源工作负载标签。
◎ gateways:Gateway的名称。

基于单口和亚UN公共做负载标签描述TCP流量的典型示例:
tcp:
- match:
 - sourceLabels:
   group:beta
 - port: 23003

2.3.6 三种协议路由规则的对比
http TLS TCp路由规则对比:

3.2.7 VirtualService的典型应用场景
1 多个服务的组合
即将weather应用的多个服务组装成大的虚拟服务。根据访问路径的不同,对weather服务的访问转发到不同的内部服务上。
配置如图

示意图

2 路由规则的优先级
通过路由顺序表达路由的规则。
以“/weather/data/”开头的流量被转发到v3版本;以“/weather/”开头的其他流量被转发到v2版本;其他流量 被转发到v1版本:
如图:

3 复杂条件路由
配置如图


对于forecast服务的请求,当请求的cookie满足“^(.*?;)?(local=north)(;.*)?”表达式,并
且 uri 匹配“/weather”,或者请求的 uri 匹配“/data”时,流量走 v2 和 v3 版本,其中v2版本的流量占20%, v3版本占80%;其他流量都走forecast服务的v1版本。

示意图如下:


4 特定版本间的访问规则
sourceLabels过滤访问来源。
如下配置就很有意思,只对frontend服务的v2版本到forecast服务的v1版本的请求设置20秒的延迟。
如图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值