服务网格(istio)istio流量管理

举报
xcc-2022 发表于 2022/08/07 19:54:08 2022/08/07
【摘要】 流量管理用于控制服务之间的流量和接口调用。使用istio可以轻松配置服务级别的属性,比如断路器、超时时间和重试策略。并且可以轻松的执行A/B测试、金丝雀发布以及按百分比流量分割的策略发布等任务。istio的流量管理模型基于Enovy,和每个服务一起部署。所有网格服务发送和接收的流量(即数据面板中的流量)都会通过Envoy代理,有助于在服务变动时定向或管理网格间的流量。概述为了在网格间定向流量...

流量管理用于控制服务之间的流量和接口调用。使用istio可以轻松配置服务级别的属性,比如断路器、超时时间和重试策略。并且可以轻松的执行A/B测试、金丝雀发布以及按百分比流量分割的策略发布等任务。
istio的流量管理模型基于Enovy,和每个服务一起部署。所有网格服务发送和接收的流量(即数据面板中的流量)都会通过Envoy代理,有助于在服务变动时定向或管理网格间的流量。

概述

为了在网格间定向流量,Istio需要知道系统中的endponit(在k8s中,endpoint记录服务对应的pod的访问地址,存储在etcd中)的位置,以及它们属于哪些服务。比如,如果在k8s中安装Istio,那么Istio会自动检测集群中的服务和endpoint。
通过使用服务注册,Envoy可以把流量导向相应的服务。大部分基于微服务的应用中,每个服务的工作负载都有多个实例处理流量,有时还作为负载均衡池。Envoy默认用轮询的方式把流量代理到每个实例。
Istio允许细粒度地控制服务网格间的流量。比如A/B测试的时候,会希望把一定百分比的流量定向到新版本的服务,或者对服务实例的子集实施不同的负载均衡策略。您可能还希望对进出网格的流量应用特殊规则,或者将网格的外部依赖项添加到服务注册表中。这些通过Istio的流量管理API都可以做到。
API是用K8S的自定义资源调用的,可以通过YAML文件配置。这些资源包括:

  • Virtual services
  • Destination rules
  • Gateways
  • Service entries
  • Sidecars

Virtual services

virtual service/虚拟服务和destination rules/目标规则是IStio中构建流量路由功能的关键组件。虚拟服务提供配置请求在服务网格内如何路由给特定的服务,构建基本的连接和发现的功能。每个虚拟服务都由一系列路由规则组成,Istio会按顺序把请求和这些规则比对,判断要把请求路由到的真正地址。

使用虚拟服务的理由

虚拟服务把客户端发送的请求和接受请求的目标工作负载解耦。默认情况下Envoy会用轮询的方式把请求均匀地发给服务的每个工作负载,但是虚拟服务可以接管一个或多个域名的流量,再根据路由规则,告知Envoy把虚拟服务收到的流量发送给合适的示例,比如同一个服务的不同版本,或者干脆发给不同的服务。
比如A/B测试,客户端的请求都发向同一个虚拟服务的地址,虚拟服务再配置20%的流量发给新版本或某些用户的流量发给新版本。再比如金丝雀升级,可以把分配给新版本示例的流量百分比逐渐增加。
这样流量的路由和实例的部署之间就完全解耦了,实例的数量可以根据流量的大小而增减。
可以用一个虚拟服务处理多个应用服务的流量。比如,可以在k8s中用一个虚拟服务处理同一个命名空间下的所有服务。这种把一个虚拟服务映射多个真实服务的做法在把一个单体应用拆分成多个微服务的时候很有用。
也可以和gateway一起配置路由规则,控制入口和出口流量。

虚拟服务示例

下例根据用户名把请求路由给服务的不同版本:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v3

hosts字段

hosts字段列出虚拟服务的地址。当客户端需要发送请求给服务时,就是用这里列出的地址。
可以时IP地址,DNS名称或者平台支持的缩写名称,这种缩写名称可以解析成全限定域名。也可以使用通配符(’*’)把一组路由规则应用在所有匹配的服务上。虚拟服务的hosts不一定非要是Istio服务注册表中的一部分。

路由规则

http部分包含了虚拟服务的路由规则,描述了匹配条件的路由的行为,用于发送给hosts字段中地址的HTTP/1.1,HTTP2和gRPC流量。也可以使用tcp和tls字段。路由规则中要包含流量的最终地址以及零到多个匹配条件。

匹配条件

示例中的第一条匹配规则是有条件的,用match字段开头,匹配所有由用户jason发出的流量。

- match:
   - headers:
       end-user:
         exact: jason

destination/目的地

destination字段指明符合条件的流量的最终地址。destination中的地址必须时Istio服务注册表中真实存在的,可以是服务网格中的服务也可以是通过服务入口添加进来的网格外的服务。示例中的是K8S服务名。

route:
- destination:
    host: reviews
    subset: v2

路由规则的应用次序

路由规则从上到下依次评估,首条匹配的规则最优先应用。推荐配置的时候写一条没有匹配规则的默认情况。

路由规则的其他事项

上面展示了,当需要把符合匹配条件的流量子集定向到特定目标地址时,路由规则是非常有效的工具。匹配条件可以是流量端口、头字段、URI等。比如下例,把流量分发给两个独立的服务:ratings和reviews,尽管看起来,他们属于一个大型服务http://bookinfo.com/的不同部分。路由规则通过URI定向请求。这种方法再把单体应用拆分成微服务的过渡阶段很有用。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo
spec:
  hosts:
    - bookinfo.com
  http:
  - match:
    - uri:
        prefix: /reviews
    route:
    - destination:
        host: reviews
  - match:
    - uri:
        prefix: /ratings
    route:
    - destination:
        host: ratings

在同一个match字段中添加多个条件,表AND逻辑;多个match字段指向同一个规则表示OR逻辑。
使用权重百分比分配流量可以实现A/B测试:

spec:
  hosts:
  - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
      weight: 75
    - destination:
        host: reviews
        subset: v2
      weight: 25

Destination rules。

虚拟服务把流量路由到目标地址,destination rules配置在目标地址对流量的操作。
特别是,可以使用目标规则来指定命名服务子集,例如按版本对给定服务的所有实例进行分组。然后,可以在虚拟服务的路由规则中使用这些服务子集来控制到不同服务实例的流量。也可以配置负载均衡策略,TLS安全模型以及断路器设置。

负载均衡

除了默认的轮询策略,还可以指定一下策略:

  • Random:随机路由到负载均衡池中的实例
  • Weighted:根据百分比路由到不同的实例
  • Least Request:请求被转发到请求数最少的实例

Destination rule的示例

下例给my-svc的三个不同子集配置了不同的负载均衡策略:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: my-destination-rule
spec:
  host: my-svc
  trafficPolicy:
    loadBalancer:
      simple: RANDOM
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
    trafficPolicy:
      loadBalancer:
        simple: ROUND_ROBIN
  - name: v3
    labels:
      version: v3

通过labels定义子集,label在k8s中以键值对的形式附着给pod等对象,这些label会添加到到service的deployment的metadata中,标志身份。

Gateway

网关用于管理服务网格的进出流量。网关是一个独立的Envoy实例,这个实例运行在网格边缘。
除了网关常见的应用层流量配置,Istio网关资源可以配置4-6层的负载均衡属性,比如暴露的端口、TLS设置等。
出口网关可以为离开网格的流量配置专用出口节点,限制哪些服务可以或应该访问外部网络,或者启用出口流量的安全控制来为网格添加安全性。您还可以使用网关来配置纯内部代理。
Istio预置的demo安装,实现了入口网关和出口网关,default配置只实现了入口网关。

网关的示例

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: ext-host-gwy
spec:
  selector:
    app: my-gateway-controller
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    hosts:
    - ext-host.example.com
    tls:
      mode: SIMPLE
      credentialName: ext-host-cert

上例允许来自ext-host.example.com的HTTPS流量通过443端口进入网格,但没有指定路由。
如果要指定路由,则要把网关绑定一个虚拟服务。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: virtual-svc
spec:
  hosts:
  - ext-host.example.com
  gateways:
  - ext-host-gwy

再通过virtual service配置路由规则。

Service entries

Service entry可以在Istio内部管理的服务注册表中添加新的条目。添加Service entry后,Envoy可以向服务发送流量,就像服务在网格内一样。使用service entry可以代理流量到外部服务。service entry主要用于一下任务。

  • 把流量定向到外部地址,比如网络接口
  • 定义重试、超时以及错误注入等策略
  • 在虚拟机中运行网格
  • 从不同的集群中逻辑添加服务到网格中以在k8s中配置多Istio网格

Service entry的示例

下例把外部依赖ext-svc.example.com添加到Istio服务注册表中。

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: svc-entry
spec:
  hosts:
  - ext-svc.example.com
  ports:
  - number: 443
    name: https
    protocol: HTTPS
  location: MESH_EXTERNAL
  resolution: DNS

Sidecars

Istio默认每个Envoy代理会接受其关联服务的所有端口的流量,并会通过服务发出的所有流量。但是通过sidecar可以:

  • 调整接受的端口和协议
  • 限制可以访问的服务
    下例配置bookinfo命名空间中的服务只能访问相同命名空间的服务和Istio控制面板服务。
apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
  name: default
  namespace: bookinfo
spec:
  egress:
  - hosts:
    - "./*"
    - "istio-system/*"

网络弹性与测试

Istio提供了可选的故障恢复和故障注入功能,可以在运行时动态配置这些功能。使用这些功能可以帮助应用程序可靠地运行,确保服务网格能够容忍失败的节点,并防止局部故障级联到其他节点。

超时

指Envoy等待响应的时间,避免服务阻塞。在每个虚拟服务中单独配置。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - route:
    - destination:
        host: ratings
        subset: v1
    timeout: 10s

重试

指Envoy对某一服务首次访问失败后,最大重试次数。用以避免因为服务或网络的暂时性问题导致访问失败。重试间隔时间由Istio自动决定,避免服务被请求淹没。
重试次数和每次重试的等待时间都可以在虚拟服务中配置。

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

断路器

可以提高微服务的弹性。在circuit breaker中定义对某一地址的访问次数限制,比如并发连接数或失败连接数,一旦达到该数量,断路器会断开,阻止新的连接。
在destination rules中设置阈值,会对服务的每一个地址单独生效。下例设置并发数量是100。

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
spec:
  host: reviews
  subsets:
  - name: v1
    labels:
      version: v1
    trafficPolicy:
      connectionPool:
        tcp:
          maxConnections: 100

失败注入

失败注入是一种测试方法,通过在系统中引入错误,已测试错误可以被拦截,并可以从错误中恢复。
两类可出入的错误类型,都通过虚拟服务配置。

  • Delays:时间性错误。模拟网络延迟或上游服务过载
  • Aborts:毁灭性错误。模拟上游服务异常。通常是HTTP错误码或TCP连接异常。
    下例在每1000次请求中引入一次5秒延迟异常。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - fault:
      delay:
        percentage:
          value: 0.1
        fixedDelay: 5s
    route:
    - destination:
        host: ratings
        subset: v1
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。