kubernetes中如何实现Istio流量管理
更新:HHH   时间:2023-1-7


这篇文章主要为大家展示了“kubernetes中如何实现Istio流量管理”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“kubernetes中如何实现Istio流量管理”这篇文章吧。

一:简介

Istio 提供了一个简单的配置模型,用来控制 API 调用以及应用部署内多个服务之间的四层通信。运维人员可以使用这个模型来配置服务级别的属性,这些属性可以是断路器、超时、重试,以及一些普通的持续发布任务,例如金丝雀发布、A/B 测试、使用百分比对流量进行控制,从而完成应用的逐步发布等。

例如,将 reviews 服务 100% 的传入流量发送到 v1 版本,这一需求可以用下面的规则来实现:

apiVersion: networking.istio.io/v1alpha3
    kind: VirtualServicemetadata:
  name: reviewsspec:
  hosts:
  - reviews  http:
  - route:
    - destination:
        host: reviews        
        subset: v1

这个配置的用意是,发送到 reviews 服务(在 host 字段中标识)的流量应该被路由到 reviews 服务实例的 v1 子集中。路由中的 subset 制定了一个预定义的子集名称,子集的定义来自于目标规则配置

apiVersion: networking.istio.io/v1alpha3
      kind: DestinationRulemetadata:
      name: reviewsspec:
      host: reviews  
      subsets:
      - name: v1    
      labels:
      version: v1  
      - name: v2    
      labels:
      version: v2

子集中会指定一或多个标签,用这些标签来区分不同版本的实例。假设在 Kubernetes 上的 Istio 服务网格之中有一个服务,version: v1 代表只有标签中包含 “version:v1” 的 Pod 才会收到流量。

规则可以使用 istioctl 客户端工具 进行配置,如果是 Kubernetes 部署,还可以使用 kubectl 命令完成同样任务,但是只有 istioctl 会在这个过程中对模型进行检查,所以我们推荐使用 istioctl。在配置请求路由任务中包含有配置示例。

Istio 中包含有四种流量管理配置资源,分别是 VirtualService、DestinationRule、ServiceEntry、以及 Gateway。下面会讲一下这几个资源的一些重点。在网络参考中可以获得更多这方面的信息。

二:Virtual Services

Virtual Services在Istio服务网格中定义了对服务的请求如何进行路由控制。例如一个 Virtual Service 可以把请求路由到不同版本,甚至是可以路由到一个完全不同于请求要求的服务上去。路由可以用很多条件进行判断,例如请求的源和目的、HTTP 路径和 Header 以及各个服务版本的权重等。

  1. 路由规则定义

    路由规则对应着一或多个用 VirtualService 配置指定的请求目的主机。这些主机可以是、也可以不是实际的目标负载,甚至可以不是一个网格内可路由的服务。例如要给到 reviews 服务的请求定义路由规则,可以使用内部的名称 reviews,也可以用域名 bookinfo.com,VirtualService 可以这样使用 host 字段:

    hosts:

     - reviews

      - bookinfo.com

    host 字段用显示或者隐式的方式定义了一或多个完全限定名(FQDN)。上面的 reviews,会隐式的扩展成为特定的 FQDN,例如在 Kubernetes 环境中,全名会从 VirtualService 所在的集群和命名空间中继承而来(比如说 reviews.default.svc.cluster.local)

 2.根据来源或 Header 制定规则

a.根据特定用户进行限定。例如,可以制定一个规则,只对来自 reviews 服务的 Pod 生效

apiVersion: networking.istio.io/v1alpha3
  kind: VirtualServicemetadata:
  name: ratingsspec:
  hosts:
  - ratings  
  http:
  - match:
      sourceLabels:
        app: reviews    ...

sourceLabels 的值依赖于服务的实现。比如说在 Kubernetes 中,跟服务的 Pod 选择标签一致。

b.根据调用方的特定版本进行限定。例如下面的规则对前一个例子进行修改,reviews 服务的 v2 版本发出的请求才会生效:

apiVersion: networking.istio.io/v1alpha3
  kind: VirtualServicemetadata:
  name: ratingsspec:
  hosts:
  - ratings  
  http:
  - match:
    - sourceLabels:
        app: reviews        
        version: v2    ...

c.根据 HTTP Header 选择规则。下面的规则只会对包含了 end-user 头,且值为 jason 的请求生效:

apiVersion: networking.istio.io/v1alpha3
  kind: VirtualServicemetadata:
  name: reviewsspec:
  hosts:
    - reviews  
  http:
  - match:
    - headers:
        end-user:
          exact: jason    ...

3.在服务之间分拆流量

每个路由规则都需要对一或多个有权重的后端进行甄别并调用合适的后端。每个后端都对应一个特定版本的目标服务,服务的版本是依靠标签来区分的。如果一个服务版本包含多个注册实例,那么会根据为该服务定义的负载均衡策略进行路由,缺省策略是 round-robin。

例如下面的规则会把 25% 的 reviews 服务流量分配给 v2 标签;其余的 75% 流量分配给 v1:

apiVersion: networking.istio.io/v1alpha3
  kind: VirtualServicemetadata:
  name: reviewsspec:
  hosts:
    - reviews  
  http:
  - route:
    - destination:
        host: reviews        
        subset: v1      
        weight: 75
    - destination:
        host: reviews        
        subset: v2      
        weight: 25

4.超时和重试

缺省情况下,HTTP 请求的超时设置为 15 秒,可以使用路由规则来覆盖这个限制:

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

5.在请求中进行错误注入

在根据路由规则向选中目标转发 http 请求的时候,可以向其中注入一或多个错误。错误可以是延迟,也可以是退出。

下面的例子在目标为 ratings:v1 服务的流量中,对其中的 10% 注入 5 秒钟的延迟。

apiVersion: networking.istio.io/v1alpha3
  kind: VirtualServicemetadata:
  name: ratingsspec:
  hosts:
  - ratings  
  http:
  - fault:
      delay:
        percent: 10
        fixedDelay: 5s    
  route:
    - destination:
        host: ratings        
        subset: v1

三:DestinationRule

1.目标规则

在请求被 VirtualService 路由之后,DestinationRule 配置的一系列策略就生效了。这些策略包含断路器、负载均衡以及 TLS 等的配置内容。DestinationRule 还定义了对应目标主机的可路由 subset(例如有命名的版本)。VirtualService 在向特定服务版本发送请求时会用到这些子集。

apiVersion: networking.istio.io/v1alpha3
  kind: DestinationRulemetadata:
  name: reviewsspec:
  host: reviews  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

2.断路器

可以用一系列的标准,例如连接数和请求数限制来定义简单的断路器。

例如下面的 DestinationRule 给 reviews 服务的 v1 版本设置了 100 连接的限制:

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

3.目标规则的评估

和路由规则类似,这些策略也是和特定的 host 相关联的,如果指定了 subset,那么具体生效的 subset 的决策是由路由规则来决定的。

规则评估的第一步,是确认 VirtualService 中所请求的主机相对应的路由规则(如果有的话),这一步骤决定了将请求发往目标服务的哪一个 subset(就是特定版本)。下一步,被选中的 subset 如果定义了策略,就会开始是否生效的评估。

这一算法需要留心是,为特定 subset 定义的策略,只有在该 subset 被显式的路由时候才能生效。例如下面的配置,只为 review 服务定义了规则(没有对应的 VirtualService 路由规则)。

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

既然没有为 reviews 服务定义路由规则,那么就会使用缺省的 round-robin 策略,偶尔会请求到 v1 实例,如果只有一个 v1 实例,那么所有请求都会发送给它。然而上面的策略是永远不会生效的,这是因为,缺省路由是在更底层完成的任务,策略引擎无法获知最终目的,也无法为请求选择匹配的 subset 策略。

有两种方法来解决这个问题。可以把路由策略提高一级,要求他对所有版本生效:

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

还有一个更好的方法,就是为服务定义路由规则,例如给 reviews:v1 加入一个简单的路由规则:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualServicemetadata:
  name: reviewsspec:
  hosts:
  - reviews  
http:
  - route:
    - destination:
        host: reviews        
        subset: v1

虽然 Istio 在没有定义任何规则的情况下,能将所有来源的流量发送给所有版本的目标服务。然而一旦需要对版本有所区别,就需要制定规则了。从一开始就给每个服务设置缺省规则,是 Istio 世界里推荐的最佳实践。

四:Service Entries

Istio 内部会维护一个服务注册表,可以用 ServiceEntry 向其中加入额外的条目。通常这个对象用来启用对 Istio 服务网格之外的服务发出请求。例如下面的 ServiceEntry 可以用来允许外部对 *.foo.com 域名上的服务主机的调用。

apiVersion: networking.istio.io/v1alpha3
  kind: ServiceEntrymetadata:
  name: foo-ext-svcspec:
  hosts:
  - *.foo.com  
    ports:
  - number: 80
    name: http    
    protocol: HTTP  
    - number: 443
    name: https    
    protocol: HTTPS

五:Gateway

Gateway 为 HTTP/TCP 流量配置了一个负载均衡,多数情况下在网格边缘进行操作,用于启用一个服务的 Ingress 流量。

和 Kubernetes Ingress 不同,Istio Gateway 只配置四层到六层的功能(例如开放端口或者 TLS 配置)。绑定一个 VirtualService 到 Gateway 上,用户就可以使用标准的 Istio 规则来控制进入的 HTTP 和 TCP 流量。

例如下面提供一个简单的 Gateway 代码,配合一个负载均衡,允许外部针对主机 bookinfo.com 的 https 流量:

apiVersion: networking.istio.io/v1alpha3
kind: Gatewaymetadata:
  name: bookinfo-gatewayspec:
  servers:
  - port:
      number: 443
      name: https      
protocol: HTTPS    
hosts:
    - bookinfo.com    
tls:
      mode: SIMPLE      
serverCertificate: /tmp/tls.crt      
privateKey: /tmp/tls.key

要为 Gateway 配置对应的路由,必须为定义一个同样 host 定义的 VirtualService,其中用 gateways 字段来绑定到定义好的 Gateway 上:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualServicemetadata:
  name: bookinfospec:
  hosts:
    - bookinfo.com  gateways:
  - bookinfo-gateway # <---- 绑定到 Gateway
  http:
  - match:
    - uri:
        prefix: /reviews    
route:
    ...

虽然主要用于管理 Ingress 流量,Gateway 还可以用在纯粹的内部服务之间或者 egress 场景下使用。不管处于什么位置,所有的网关都可以以同样的方式进行配置和控制。

以上是“kubernetes中如何实现Istio流量管理”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注天达云行业资讯频道!

返回云计算教程...