前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >istio实现灰度发布的流量策略

istio实现灰度发布的流量策略

作者头像
dogfei
发布2020-07-31 15:19:58
2K0
发布2020-07-31 15:19:58
举报
文章被收录于专栏:devops探索devops探索

istio流量管理

将流量从基础设施扩展中解耦,这样就可以让 Istio 提供各种独立于应用程序代码之外的流量管理功能。除了 A/B 测试的动态请求路由,逐步推出和金丝雀发布之外,它还使用超时、重试和熔断器来处理故障恢复,最后还可以通过故障注入来测试服务之间故障恢复策略的兼容性。这些功能都是通过在服务网格中部署的 Envoy sidecar/代理来实现的。

Pilot 和 Envoy

Istio 流量管理的核心组件是 Pilot,它管理和配置部署在特定 Istio 服务网格中的所有 Envoy 代理实例。它允许您指定在 Envoy 代理之间使用什么样的路由流量规则,并配置故障恢复功能,如超时、重试和熔断器。它还维护了网格中所有服务的规范模型,并使用这个模型通过发现服务让 Envoy 了解网格中的其他实例。每个 Envoy 实例都会维护负载均衡信息信息,这些信息来自 Pilot 以及对负载均衡池中其他实例的定期健康检查。从而允许其在目标实例之间智能分配流量,同时遵循其指定的路由规则。Pilot 负责管理通过 Istio 服务网格发布的 Envoy 实例的生命周期。

如上图所示,在网格中 Pilot 维护了一个服务的规则表示并独立于底层平台。Pilot中的特定于平台的适配器负责适当地填充这个规范模型。例如,在 Pilot 中的 Kubernetes 适配器实现了必要的控制器,来观察 Kubernetes API 服务器,用于更改 pod 的注册信息、入口资源以及存储流量管理规则的第三方资源。这些数据被转换为规范表示。然后根据规范表示生成特定的 Envoy 的配置。Pilot 公开了用于服务发现 、负载均衡池和路由表的动态更新的 API。

请求路由

如 Pilot 所述,特定网格中服务的规范表示由 Pilot 维护。服务的 Istio 模型和在底层平台(Kubernetes、Mesos 以及 Cloud Foundry 等)中的表达无关。特定平台的适配器负责从各自平台中获取元数据的各种字段,然后对服务模型进行填充。

Istio 引入了服务版本的概念,可以通过版本(v1、v2)或环境(staging、prod)对服务进行进一步的细分。这些版本不一定是不同的 API 版本:它们可能是部署在不同环境(prod、staging 或者 dev 等)中的同一服务的不同迭代。使用这种方式的常见场景包括 A/B 测试或金丝雀部署。Istio 的流量路由规则可以根据服务版本来对服务之间流量进行附加控制。

服务之间的通讯

如上图所示,服务的客户端不知道服务不同版本间的差异。它们可以使用服务的主机名或者 IP 地址继续访问服务。Envoy sidecar/代理拦截并转发客户端和服务器之间的所有请求和响应。

运维人员使用 Pilot 指定路由规则,Envoy 根据这些规则动态地确定其服务版本的实际选择。该模型使应用程序代码能够将它从其依赖服务的演进中解耦出来,同时提供其他好处(参见 Mixer)。路由规则让 Envoy 能够根据诸如 header、与源/目的地相关联的标签和/或分配给每个版本的权重等标准来进行版本选择。

Istio 还为同一服务版本的多个实例提供流量负载均衡。可以在服务发现和负载均衡中找到更多信息。

Istio 不提供 DNS。应用程序可以尝试使用底层平台(kube-dns、mesos-dns 等)中存在的 DNS 服务来解析 FQDN。

Ingress 和 Egress

Istio 假定进入和离开服务网络的所有流量都会通过 Envoy 代理进行传输。通过将 Envoy 代理部署在服务之前,运维人员可以针对面向用户的服务进行 A/B 测试、部署金丝雀服务等。类似地,通过使用 Envoy 将流量路由到外部 Web 服务(例如,访问 Maps API 或视频服务 API)的方式,运维人员可以为这些服务添加超时控制、重试、断路器等功能,同时还能从服务连接中获取各种细节指标。

示例参考

将所有流量导向一个版本
代码语言:javascript
复制
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nginx-server
spec:
  hosts:
  - "nginx.yscloud.com"
  gateways:
  - nginx-server-gateway
  http:
  - route:
    - destination:
        host: nginx-server
        subset: v2
        port:
          number: 80
将流量进行拆分

1、按照权重进行拆分

代码语言:javascript
复制
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nginx-server
spec:
  hosts:
  - "nginx.yscloud.com"
  gateways:
  - nginx-server-gateway
  http:
  - route:
    - destination:
        host: nginx-server
        subset: v1
        port:
          number: 80
      weight: 90
    - destination:
        host: nginx-server
        subset: v2
        port:
          number: 80
      weight: 10

2、按照header进行拆分

代码语言:javascript
复制
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nginx-server
spec:
  hosts:
  - "nginx.yscloud.com"
  gateways:
  - nginx-server-gateway
  http:
   - match:
    - headers:
        test:
          exact: header
    route:
    - destination:
        host: nginx-server
        subset: v1
        port:
          number: 80 

3、按照浏览器进行拆分

代码语言:javascript
复制
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nginx-server
spec:
  hosts:
  - "nginx.yscloud.com"
  gateways:
  - nginx-server-gateway
  http:
  - match:
    - headers:
        User-Agent:
          regex: ".*Firefox/.*"
    route:
    - destination:
        host: nginx-server
        subset: v2
        port:
          number: 80  

其实也是按照header来进行区分 4、按照请求地址进行拆分

代码语言:javascript
复制
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nginx-server
spec:
  hosts:
  - "nginx.yscloud.com"
  gateways:
  - nginx-server-gateway
  http:
  - match:
    - uri:
        prefix: "/v2"
    rewrite:
      uri: /
    route:
    - destination:
        host: nginx-server
        subset: v2
        port:
          number: 80  

5、按照用户源IP进行流量拆分

代码语言:javascript
复制
......
.....
.....
  - match:
    - headers:
        X-Real-IP:
          regex: ".*192.168.3.148.*"
    route:
    - destination:
        host: nginx-server
        subset: v2
        port:
          number: 80
  - match:
    - headers:
        X-Real-IP:
          regex: ".*192.168.2.117.*"
    route:
    - destination:
        host: nginx-server
        subset: v1
        port:
          number: 80

6、根据网络模式,例如手机4G,wifi等 其实我也没找到具体的参数可以控制,但是我们可以间接的进行控制,例如,每一个运营商的IP段是固定的,我们可以利用根据用户源IP的策略进行控制,只不过IP地址变成了各大运营商的地址即可,下面是各大运营商的地址段: https://ispip.clang.cn/

多个条件同时满足时,进行流量拆分
代码语言:javascript
复制
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nginx-server
spec:
  hosts:
  - "nginx.yscloud.com"
  gateways:
  - nginx-server-gateway
  http:
  - match:
    - headers:
        test:
          exact: header
        User-Agent:
          regex: ".*Chrome/.*"
    route:
    - destination:
        host: nginx-server
        subset: v1
        port:
          number: 80   
满足其中一个条件
代码语言:javascript
复制
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nginx-server
spec:
  hosts:
  - "nginx.yscloud.com"
  gateways:
  - nginx-server-gateway
  http:
  - match:
    - headers:
        test:
          exact: header
    - headers:   
        User-Agent:
          regex: ".*Chrome/.*"
    route:
    - destination:
        host: nginx-server
        subset: v1
        port:
          number: 80   
超时和重试
代码语言:javascript
复制
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
    - ratings
  http:
  - route:
    - destination:
        host: ratings
        subset: v1
    timeout: 10s    #超时时间为10秒

还可以设置重试次数

代码语言:javascript
复制
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
    - ratings
  http:
  - route:
    - destination:
        host: ratings
        subset: v1
    retries:
      attempts: 3
      perTryTimeout: 2s

优先级

当对同一目标有多个规则时,会按照在 VirtualService 中的顺序进行应用,换句话说,列表中的第一条规则具有最高优先级。

为什么优先级很重要:当对某个服务的路由是完全基于权重的时候,就可以在单一规则中完成。另一方面,如果有多重条件(例如来自特定用户的请求)用来进行路由,就会需要不止一条规则。这样就出现了优先级问题,需要通过优先级来保证根据正确的顺序来执行规则。

常见的路由模式是提供一或多个高优先级规则,这些优先规则使用源服务以及 Header 来进行路由判断,然后才提供一条单独的基于权重的规则,这些低优先级规则不设置匹配规则,仅根据权重对所有剩余流量进行分流。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-11-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • istio流量管理
  • Pilot 和 Envoy
  • 请求路由
    • 服务之间的通讯
      • Ingress 和 Egress
      • 示例参考
        • 将所有流量导向一个版本
          • 将流量进行拆分
            • 多个条件同时满足时,进行流量拆分
              • 满足其中一个条件
                • 超时和重试
                • 优先级
                相关产品与服务
                负载均衡
                负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档