前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《istio实战指南》第5章 流量管理

《istio实战指南》第5章 流量管理

作者头像
yeedomliu
发布2020-07-14 14:38:55
1.3K0
发布2020-07-14 14:38:55
举报
文章被收录于专栏:yeedomliuyeedomliu

第5章 流量管理


流量管理中的规则配置

  • 要控制流量,就需要定义一些规则。Istio中定义了一个简单的配置模型,可以很方便地进行规则的配置。在示例练习前,需要先了解一下与规则配置相关的重要概念和基本的配置方法
  • Istio中定义了4种针对流量管理的配置资源
代码语言:javascript
复制
定义路由规则,控制请求如何被路由到服务

VirtualService

  • VirtualService的主要功能是定义路由规则,使请求(流量)可以依据这些规则被分发到对应的服务。路由的方式也有很多种,可以根据请求的源或目标地址路由,也可以根据路径、头信息,或者服务版本进行路由
  • 要路由就必须定义目标主机,VirtualService中的目标主机定义使用hosts关键字。除了定义域名外,也可以直接定义可路由的服务。比如下面的配置定义了两个目标主机:reviews服务和bookinfo.com域名
  • 根据不同的版本对服务流量进行拆分是常用的功能。在Istio中服务版本依靠标签进行区分,可以定义不同种类的标签(如版本号、平台),对流量以不同的维度进行灵活的分配。拆分流量使用weight关键字来设置。如下面的配置,把75%的流量分配给v1版本的reviews服务,25%的流量分配给v2版本
  • 上面的配置中出现了subset(子集)关键字。subset其实就是特定版本的标签,它和标签的映射关系定义在DestionationRule里。比如在subset中设置标签为"version:v1",代表只有附带这个标签的Pod才能接受流量。Istio强制要求Pod设置带有version的标签,以此来实现流量控制和指标收集等功能
  • 比如下面的例子定义了两个子集,分别对应v1v2两个标签
  • 使用timeout关键字可以设置请求的超时时间,比如下面的例子,对访问ratings服务的请求设置10s超时
  • 除了超时还可以通过retries关键字设置重试。下面的设置表示最多重试3次,每次的超时时间为2s
  • 使用fault关键字来设置故障注入。在下面的例子中我们注入了一个延迟故障,使得ratings服务10%的响应会出现5s的延迟。除了延迟,还可以设置终止或者返回HTTP故障码
  • 另外一种有效的方式是定义匹配条件,这是通过match关键字实现的。比如下面的例子,对特定的URL进行匹配
  • 可以同时设置多个匹配项。匹配的策略有很多,比如头信息、标签等,读者可以通过下表查看设置可选项

字段

类型

描述

uri

[StringMatch]

大小写敏感

scheme

[StringMatch]

大小写敏感

method

[StringMatch]

大小写敏感

authority

[StringMatch]

大小写敏感

headers

map<string,[StringMatch]>

Header的键必须是小写的,使用连字符作为分隔符,比如x-request-id。Header的匹配同样是大小写敏感的

port

uint32

指定主机上的端口

sourceLabels

map<string,[StringMatch]>

用一个或多个标签选择工作负载

gateways

string[]

规则所涉及的Gateway的名称列表

  • 需要注意的是,VirtualService中的路由配置规则是有优先级的。如果在配置中定义了多条规则,则按照顺序优先匹配第一条,但是Header条件除外。如果匹配规则中设置了Header,则它具有最高优先级

DestinationRule

  • DestionationRule通过和VirtualService成对出现的。它的功能是当VirtualService的路由生效后,配置一些策略并应用到请求中。另外,subset和标签的对应关系也被定义在DestinationRule
  • 下面展示了DestinationRule的配置,除定义了VirtualService中要使用的两个subset外,还设置以随机的方式对reviews服务进行负载均衡
  • 微服务的弹性设计里有一种功能叫作熔断(Circuit Breaker),它是一种服务降级处理的方式。当某个服务出现故障后,为了不影响下游服务而对其设置断流操作。我们可以在DestinationRule中方便地实现这个功能。下面例子设置对reviews服务的最大连接只能有100个,如果超过这个数字就会断流
  • 需要注意一点,在上面例子中,如果特定的subset定义了策略,但没有定义对应的VirtualService,则该策略并不会执行。在这种情况下,Istio会以默认的方式(轮询)将请求改善给目标服务的全部版本。因此官方推荐的方式是给每个服务都定义路由规则,避免这种情况发生

ServiceEntry

  • 有时候我们希望服务能够访问外部系统,这就需要用到ServiceEntry。它也是一种配置资源,用来给服务网格内的服务提供外部URL的能力。Istio中的服务发现功能主要是依靠服务注册表实现的,ServiceEntry能够在注册表中添加外部服务,使得内部服务可以访问这些被添加的URL。因此,通过ServiceEntry就可以实现访问外部服务的能力。下面的例子展示了如何配置一个外部的URL“*.foo.com”,使得网格内部的服务可以通过HTTP协议的80端口来访问它

Gateway

  • ServiceEntry相反,外部请求想要访问网格内的服务就要用到GatewayGateway为进入网格的请求配置了一个负载均衡器,把VirtualService绑定到Gateway,这样就可以设置规则来控制进入的流量。比如下面的例子,为从外部进入Bookinfo网站的HTTPS流量配置了一个Gateway
  • 要实现路由,还需要定义一个VirtualService并与网关绑定起来。下面的例子在hosts中对上面定义的名为bookinfo-gatewayGateway进行了绑定
  • Istio中的流量控制主要是由这4个配置资源共同协作完成的。首先鸪请求的主机(host)在VirtualService中是否有路由规则,如果有,则将请求发往对应的subset。接下来,如果发现当前subsetDestinationRule中定义了策略,则执行此策略。同时,还可以设置Gateway负责负载均衡以及为服务定义出口

流量转移

  • 现实中常用的3种部署应用场景。本质上它们都是通过路由配置来实现流量的转移
  1. 蓝绿部署
  2. 金丝雀发布
  3. A/B测试

蓝绿部署(Blue-Green Deployment

  • 在生产环境中部署两套同样的应用,并通过路由进行切换。比如,绿色是线上环境,当我们要发布新版本时,可以在蓝色环境中进行代码更新、测试等操作,确保没有问题后,修改路由规则(如反向代理等)把流量切换到绿色环境 。蓝绿部署是一种热部署方式,目的是尽可能地减少系统下线的时间
  • 蓝绿部署的优点是可以让用户放心部署非在线环境,而不用担心部署出错影响生产环境。同时它也提供了快速回滚的能力,比如当我们发现蓝色环境(新版本)出现问题时,可以把流量切换回绿色环境(旧版本)。蓝绿部署无须停机更新,风险小。它也有一些不足之处,比如需要两套环境,成本较高;当有未完成的业务(如数据库事务)时,切换版本可能会出现问题。蓝绿部署适合增量更新,在微服务架构中很常用
  • 使用Bookinfo应用中reviews服务模拟蓝绿部署。reviews服务有3个版本,v1是线上正在运行版本,v2是我们要更新上线的版本。需要做的就是制定 路由规则,将流量转移到v2版本上
  1. 定义DestinationRule
  2. 定义VirtualService设置路由,将流量指向v1版本
  3. 定义VirtualService,将流量切换到v2版本
定义DestinationRule
定义VirtualService设置路由,将流量指向v1版本
代码语言:javascript
复制
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: productpage
spec:
  hosts:
  - productpage
  http:
  - route:
    - destination:
        host: productpage
        subset: v1
代码语言:javascript
复制
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
代码语言:javascript
复制
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - route:
    - destination:
        host: ratings
        subset: v1
代码语言:javascript
复制
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: details
spec:
  hosts:
  - details
  http:
  - route:
    - destination:
        host: details
        subset: v1
  • 设置完成后打开http://localhost/productpage,看到评分部分没有星标显示的就是v1版本
定义VirtualService,将流量切换到v2版本
  • 已经具备了蓝色部署(v1版本),接下来编写VirtualService,将所有流量切换到reviewsv2版本上(绿色部署)。需要将reviews服务目标子集subset设置成v2即可
代码语言:javascript
复制
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v2
  • 保存清单并替换原来配置
代码语言:javascript
复制
istioctl replace -f virtual-service-reviews-v2.yaml
  • 刷新浏览器,如下图所示带有黑色星标的评论页面,这代表流量都被切换到了v2版本上

金丝雀发布(Canary Release

  • 又叫灰度发布,是一种将流量逐渐转移到新版本的部署方式,以便出现问题后控制受影响范围,降低风险。和蓝绿部署相比,它是以渐进的方式进行流量转移,相对更安全
  • 新版本准备完毕后,将一小部分用户流量转移过来。有多种策略确定转移哪些用户(随机选择、用户ID尾号、公司内部用户或者地理位置等)
  • 新版本经过测试没有问题后,就可以把全部的流量切换到新版本上
  • 金丝雀的优点是可以利用真实的线上环境和用户数据进行测试。在很多情况下一些隐蔽的Bug很难在开发环境中被发现,只有在线上环境中才能暴露出来,因此能利用真实环境和数据测试是发现疑难杂症的重要手段。另外,当发现问题时也可以很安全地回滚,并控制受影响的范围。它的缺点是需要在同一时间点管理多个版本(通常是两个 ,也可以同时部署更多版本)。另一个案例是,当发布的是客户端版本(如手机的App)时,就很难控制终端用户去更新版本,此时如果不同的客户端版本和后端进行通信,则需要进行向后兼容
  • 金丝雀发布经常和A/B测试一起使用,只不过侧重点不同。金丝雀发布的最终目的是发布新版本并完全替代旧版本,而A/B测试的主要目的是收集数据,比较两个版本的优劣
  • 假设当前reviews服务的v2是老版本,现在要发布v3版本。在完全切换到新版本前,通过金丝雀发布先将10%的流量转移到v3版本。和蓝绿部署不同 ,我们并不是把全部流量一下全切换到新版本,而是需要在配置中通过设置权重来实现流量转移
  • 要实现它需要在VirtualService中设置两个版本的权重。为reviews服务增加到v3的目标节点,同时用weight标记分别设置v2为90,v3为10,即90%的流量指向v2老版本,10%的流量用来测试v3新版本
代码语言:javascript
复制
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
      weight: 90
    - destination:
        host: reviews
        subset: v3
      weight: 10
  • 执行命令替换路由规则
代码语言:javascript
复制
istioctl replace -f reviews-v3-10.yaml
  • 在浏览器中多刷新几次页面,会发现大约有10%的概率可以出现图中带红色星标的评论页面,这表示它们流向了v3版本

A/B发布(分割测试或桶测试)

  • 是比较两个选项并分析结果的一种方法。比如一个网站上线了新的页面,要想了解用户对新页面的反馈情况,可以将流量分发到不同的版本上,通过对点击率、留存率和转化率等一系列指标的分析来确定哪一种版本更好
  • A/B测试在本质上和金丝雀的配置没有区别,都是进行流量转移 。我们使用另一种策略来演示。假设我们的目标是给登录用户和非登录用户展示不同的页面,使用match来匹配不同的用户
代码语言:javascript
复制
istioctl replace -f login-abtest.yaml
  • 在浏览器以任何身份登录,会发现看到的都是红色星标的v3版本,而退出登录则只能看到没有星标的版本
  • 可以看到,在Istio里设置A/B测试非常方便,并且支持多种维度度。当然,A/B测试的最终目的是收集各项指标的数据,并根据数据做出决策

超时和重试

  • 对于分布式系统来说,网络故障的出现在所难免。比如在一个微服务应用中,服务A需要调用服务B。当网络故障造成B出现延误而无法及时响应时,如果A持续等待,那么它的上游服务也会受到影响,进而使得故障的面积扩散,造成更严重的问题。超时就是一种控制故障范围的机制,相当于一个简单的熔断策略
  • 网络有时候会出现抖动,这将导致通信失败;而重试的主要目的就是解决这一问题。在调用出现失败后进行重试,提高了服务间交互的成功率和可用性
  • 超时和重试都是微服务应用需要支持的功能 ,是提高系统弹性的重要保障

超时

  • Bookinfo中的reviews服务会调用ratings服务来进行评分显示(星标),我们给ratings服务设置一个7s的延迟,同时在reviews服务中设置1s超时,使得超过1s后停止对ratings服务的调用。超时使用timeout标记来配置
  • 首先,把路由规则恢复到默认状态,避免前面的设置影响当前的例子
代码语言:javascript
复制
istioctl replace -f samples/bookinfo/networking/virutlal-service-all-v1.yaml
  • 然后,把reviews服务切换为v2版本,使得它可以调用ratings服务
  • 接下来,在ratings服务中加入2s的延迟
  • 打开浏览器访问Bookinfo页面,可以看到正常显示星标,但页面需要加载2s左右。最后,为reviews:v2服务的请求加入1s的请求超时
  • 刷新页面,这时候可以注意到页面在加载1s后就返回了,页面右侧显示了错误信息
  • 出现错误的原因和我们预计的一样,reviews服务调用ratings时有2s的延迟,使得服务无法在1s限制内返回,这就触发了超时。在Istio中,服务默认的超时时间是15s

重试


控制入口流量

确定入口IP和端口

配置网关


熔断

熔断简介

  • 在一个电路系统中,电闸一般都带有保险丝这样的保护装置,一旦电压不稳或者短路,系统就自动跳闸切断电路,以免电流过大烧坏电器。同样,在分布式系统中也有类似的功能。这就是熔断。它的行为和电路系统中的跳闸非常类似,当下游服务出现错误时,通过重试发现服务暂时无法恢复,再进行无休止的重试已经没有意义了。此时上游服务为保护自己不受牵连,会切断对下游服务的调用。它是分布式系统应该具有的重要的弹性能力

设置后端服务

  • 启动httpbin作为后端服务
代码语言:javascript
复制
kubectl apply if samples/httpbin/httpbin.yaml
  • 定义一个DestinationRule,为httpbin服务创建熔断器
代码语言:javascript
复制
上游主机的连接池配置
  • 通过上面的配置项可知,在以上定义熔断是出现一次错误即发生熔断,间隔1s的检测是否恢复

设置客户端

  • 现在创建一个新的部署作为调用httpbin服务的客户端,来测试熔断机制。我们使用Istio官方推荐的负载测试工具Fortio,它能够以并发的方式发送HTTP请求来模拟多用户调用
代码语言:javascript
复制
kubectl apply -f <(istioctl kube-inject -f samples/httpbin/sample-client/fortio-deploy.yaml)>
  • 获取FortioPod,然后进入它的终端来调用httpbin服务。服务返回了状态码200,调用成功

触发熔断机制

  • 前面熔断设置中将最大连接数(maxConnections)和最大请求数(http1MaxPendingRequests)指定为1,即如果有一个并发请求,就会触发熔断。下面利用3个并发操作来发送30个请求进行测试
  • 通过输出日志可以看出,熔断生效了,只有70%的请求通过,其余的返回了503错误(合计允许 有一定误差)。可以通过查询istio-proxy的统计信息来进一步查看熔断的情况
  • upstreamrqpending_overflow的值 是9,说明有9次请求被熔断了
  • 熔断机制让系统更加稳定并具有 弹性,减少了错误对系统性能的影响,快速地拒绝对出错服务的调用 ,提高了响应时间,也控制了故障范围。在Istio中可以通过定义DestinationRule方便地实现熔断

小结

  • 流量管理是微服务应用在通信层面必需的功能 ,借助Istio可以非常方便地实现各种流量控制。Istio的流量管理功能主要是依靠Pilot组件和Envoy代理协作完成的。流量管理的规则配置由4个配置资源完成
  1. VirtualService定义路由规则
  2. DestinationRule在路由生效后定义对于请求的策略
  3. ServiceEntry提供了网格内服务可以访问外界服务的能力
  4. Gateway可以让外部服务调用网格内服务
  • 流量转移是微服务部署和更新的常用 功能。我们介绍了3种觉的部署和发布策略:
  1. 蓝绿部署
  2. 金丝雀发布
  3. A/B测试
  • 使用Istio可以很轻松地实现这些策略。分布式系统的弹性和应对故障的能力非常重要,决定了系统的稳定性和可用性。超时、重试以及熔断等功能都可以很容易地在Istio中实现
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-07-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 yeedomliu 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第5章 流量管理
    • 流量管理中的规则配置
      • VirtualService
      • DestinationRule
      • ServiceEntry
      • Gateway
    • 流量转移
      • 蓝绿部署(Blue-Green Deployment)
      • 金丝雀发布(Canary Release)
      • A/B发布(分割测试或桶测试)
    • 超时和重试
      • 超时
      • 重试
    • 控制入口流量
      • 确定入口IP和端口
      • 配置网关
    • 熔断
      • 熔断简介
      • 设置后端服务
      • 设置客户端
      • 触发熔断机制
    • 小结
    相关产品与服务
    服务网格
    服务网格(Tencent Cloud Mesh, TCM),一致、可靠、透明的云原生应用通信网络管控基础平台。全面兼容 Istio,集成腾讯云基础设施,提供全托管服务化的支撑能力保障网格生命周期管理。IaaS 组网与监控组件开箱即用,跨集群、异构应用一致发现管理加速云原生迁移。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档