Istio提供了一个简单的配置模型来控制API调用和第4层流量如何跨应用程序部署中的各种服务流动。配置模型允许操作员配置服务级属性,例如断路器,超时,重试,以及设置常见的连续部署任务,例如金丝雀推出,A / B测试,基于%的流量分割的分阶段推出等。
例如,可以使用如下配置来描述将评论服务的100%传入流量发送到版本“v1” 的简单规则:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
此配置表示发送到评论服务(在hosts
字段中指定)的流量应路由到基础评论服务实例的v1子集。路由subset
指定相应目标规则配置中已定义子集的名称:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
子集指定一个或多个标识特定于版本的实例的标签。例如,在Istio的Kubernetes部署中,“version:v1”表示只有包含标签“version:v1”的pod才会收到流量。
可以使用istioctl CLI配置规则,也可以使用命令在Kubernetes部署中配置规则kubectl
,尽管只会istioctl
执行模型验证并建议使用。有关示例,请参阅配置请求路由任务。
Istio中有四种流量管理配置资源:VirtualService,DestinationRule,ServiceEntry和Gateway。下面描述了这些资源的一些重要方面。有关详细信息,请参阅网络参考
虚拟服务
甲VirtualService定义了控制如何用于服务请求的服务Istio网格内路由的规则。例如,虚拟服务可以将请求路由到不同版本的服务,或者实际上是将请求路由到与请求完全不同的服务。可以根据请求源和目标,HTTP路径和标头字段以及与各个服务版本关联的权重来路由请求。
规则目的地
路由规则对应于VirtualService
配置中指定的一个或多个请求目标主机。这些主机可能与实际目标工作负载相同或不同,甚至可能不对应于网格中的实际可路由服务。例如,要使用其内部网格名称或通过主机为审阅服务定义请求的路由规则,可以使用如下字段:reviews
bookinfo.com
VirtualService
hosts
hosts:
- reviews
- bookinfo.com
该hosts
字段隐式或显式指定一个或多个完全限定的域名(FQDN)。reviews
上面的短名称将隐式扩展为特定于实现的FQDN。例如,在Kubernetes环境中,全名是从VirtualSevice
(例如reviews.default.svc.cluster.local
)的集群和名称空间派生的。
按源/标头限定规则
可以选择将规则限定为仅应用于符合某些特定条件的请求,例如:
1.限制为特定呼叫者。例如,规则可以指示它仅适用于来自实现评论服务的工作负载(pod)的调用。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- match:
sourceLabels:
app: reviews
...
值sourceLabels
取决于服务的实现。例如,在Kubernetes中,它可能与相应Kubernetes服务的pod选择器中使用的标签相同。
2.限制到呼叫者的特定版本。例如,以下规则将前一个示例简化为仅应用于评论服务的版本“v2”的调用。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- match:
- sourceLabels:
app: reviews
version: v2
...
3.根据HTTP标头选择规则。例如,如果传入请求包含包含子字符串“user = jason”的“cookie”标头,则以下规则将仅适用于传入请求。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- match:
- headers:
cookie:
regex: "^(.*?;)?(user=jason)(;.*)?$"
...
如果提供了多个标头,则所有相应的标头必须匹配才能应用规则。
可以同时设置多个标准。在这种情况下,取决于嵌套,应用AND或OR语义。如果多个条件嵌套在单个匹配子句中,则条件为AND。例如,以下规则仅适用于请求的来源是“reviews:v2”并且存在包含“user = jason”的“cookie”标题。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- match:
- sourceLabels:
app: reviews
version: v2
headers:
cookie:
regex: "^(.*?;)?(user=jason)(;.*)?$"
...
相反,如果条件出现在单独的匹配子句中,则只能应用其中一个条件(OR语义):
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- match:
- sourceLabels:
app: reviews
version: v2
- headers:
cookie:
regex: "^(.*?;)?(user=jason)(;.*)?$"
...
在服务版本之间拆分流量
每个路由规则标识在激活规则时要调用的一个或多个加权后端。每个后端对应于目标服务的特定版本,其中版本可以使用标签表示。如果存在多个具有指定标签的已注册实例,则它们将根据为服务配置的负载平衡策略进行路由,或者默认为循环。
例如,以下规则会将评论服务的25%流量路由到具有“v2”标签的实例,将剩余流量(即75%)路由到“v1”。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
weight: 75
- destination:
host: reviews
subset: v2
weight: 25
超时和重试
默认情况下,http请求的超时为15秒,但这可以在路由规则中覆盖,如下所示:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- route:
- destination:
host: ratings
subset: v1
timeout: 10s
也可以在路由规则中指定给定http请求的重试次数。可以按如下方式设置最大尝试次数,或者在默认或覆盖的超时期限内尽可能多的尝试次数:
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
请注意,还可以基于每个请求覆盖请求超时和重试。
有关超时控制的演示,请参阅请求超时任务。
在请求路径中注入错误
路由规则可以指定在将http请求转发到规则的相应请求目的地时要注入的一个或多个故障。故障可以是延迟或中止。
以下示例将向评级微服务的“v1”版本的10%请求中引入5秒延迟。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- fault:
delay:
percent: 10
fixedDelay: 5s
route:
- destination:
host: ratings
subset: v1
另一种故障中止可用于过早终止请求,例如,模拟故障。
以下示例将向评级服务“v1” 返回10%请求的HTTP 400错误代码。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- fault:
abort:
percent: 10
httpStatus: 400
route:
- destination:
host: ratings
subset: v1
有时延迟和中止故障一起使用。例如,以下规则将审核服务“v2”的所有请求延迟5秒到评级服务“v1”,然后中止10%:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- match:
- sourceLabels:
app: reviews
version: v2
fault:
delay:
fixedDelay: 5s
abort:
percent: 10
httpStatus: 400
route:
- destination:
host: ratings
subset: v1
要查看故障注入操作,请参阅故障注入任务。
HTTP路由规则优先
当给定目的地有多个规则时,它们按照它们出现的顺序进行评估VirtualService
,即列表中的第一个规则具有最高优先级。
为什么优先重要?每当特定服务的路由故事纯粹基于权重时,就可以在单个规则中指定。另一方面,当使用其他标准(例如,来自特定用户的请求)来路由流量时,将需要不止一个规则来指定路由。这是必须仔细考虑规则优先级的地方,以确保以正确的顺序评估规则。
广义路由规范的一种常见模式是提供一个或多个更高优先级的规则,这些规则通过源/头限定规则,然后提供单个基于权重的规则,最后没有匹配条件,以提供所有其他情况的流量的加权分布。
例如,以下VirtualService
包含2个规则,它们一起指定对包含名为“Foo”且值为“bar”的标题的评论服务的所有请求将被发送到“v2”实例。所有剩余的请求将被发送到“v1”。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- match:
- headers:
Foo:
exact: bar
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v1
请注意,基于标头的规则具有更高的优先级。如果它较低,这些规则将无法按预期工作,因为基于权重的规则(没有特定的匹配标准)将首先进行评估,然后将所有流量简单地路由到“v1”,甚至包括匹配“Foo”的请求“头。一旦找到适用于传入请求的规则,它将被执行并且规则评估过程将终止。这就是为什么在存在多个规则时仔细考虑每个规则的优先级非常重要的原因。
目标规则
一个DestinationRule配置组策略后应用的请求VirtualService
已经发生路由。它们旨在由服务所有者编写,描述断路器,负载平衡器设置,TLS设置等。
A DestinationRule
还定义subsets
了相应目标主机的可寻址(即,命名版本)。VirtualService
在将流量发送到特定版本的服务时,这些子集用于路由规范。
以下DestinationRule
配置评论服务的策略和子集:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
spec:
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
请注意,可以在单个DestinationRule
配置中指定多个策略(例如,默认和特定于v2)。
断路器
可以根据许多标准(例如连接和请求限制)设置简单的断路器。
例如,以下DestinationRule
设置对评论服务版本“v1”后端的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
有关断路器控制的演示,请参阅断路任务。
DestinationRule评估
与路由规则类似,策略与特定主机相关联,但如果它们是特定于子集,则激活取决于路由规则评估结果。
规则评估过程中的第一步评估VirtualService
对应于所请求主机的路由规则(如果有任何已定义的),以确定当前请求将被路由到的目标服务的子集(即,特定版本)。接下来,评估与所选子集相对应的策略集(如果有的话)以确定它们是否适用。
注意:要记住的算法的一个细微之处在于,只有在明确路由到相应的子集时,才会应用为特定子集定义的策略。例如,考虑以下配置,作为为评论服务定义的唯一规则(即,相应的路由规则中没有路由规则)VirtualService
。
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
subsets:
- name: v1
labels:
version: v1
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
由于没有为评论服务定义特定的路由规则,因此将应用默认的循环路由行为,有时可能会调用“v1”实例,如果“v1”是唯一运行的版本,甚至可能总是如此。然而,由于默认路由是在较低级别完成的,因此永远不会调用上述策略。规则评估引擎将不知道最终目标,因此无法将子集策略与请求匹配。
您可以通过以下两种方式之一修复上述示例。您可以将流量策略上移一级以使其适用于任何版本:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
subsets:
- name: v1
labels:
version: v1
或者,更好的是,为服务定义正确的路由规则。例如,您可以为“reviews:v1”添加简单的路由规则。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
虽然默认的Istio行为可以方便地将流量从任何源发送到目标服务的所有版本而不设置任何规则,但只要需要版本区分,就需要规则。因此,从一开始就为每个服务设置默认规则通常被认为是Istio中的最佳实践。
服务条目
一个ServiceEntry用于添加额外的条目成Istio内部维护的服务注册。它最常用于启用对Istio服务网格之外的服务的请求。例如,以下内容ServiceEntry
可用于允许外部调用*.foo.com
域下托管的服务。
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: foo-ext-svc
spec:
hosts:
- *.foo.com
ports:
- number: 80
name: http
protocol: HTTP
- number: 443
name: https
protocol: HTTPS
ServiceEntry
使用该hosts
字段指定a的目标,该字段可以是完全限定域名或通配符域名。它表示允许访问网格中的服务的一个或多个服务的白名单集。
A ServiceEntry
不限于外部服务配置,它可以有两种类型:网状内部或网状外部。网状内部条目与所有其他内部服务类似,但用于向网格显式添加服务。它们可用于添加服务,作为扩展服务网格的一部分,以包括非托管基础架构(例如,添加到基于Kubernetes的服务网格的VM)。网格外部条目表示网格外部的服务。对于他们来说,mTLS身份验证被禁用,并且在客户端执行策略实施,而不是在通常的服务器端执行内部服务请求。
只要服务条目使用匹配引用服务,服务条目就可以与虚拟服务和目标规则结合使用hosts
。例如,以下规则可与上述ServiceEntry
规则结合使用,为外部服务的调用设置10秒超时bar.foo.com
。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bar-foo-ext-svc
spec:
hosts:
- bar.foo.com
http:
- route:
- destination:
host: bar.foo.com
timeout: 10s
外部目的地支持重定向和转发流量,定义重试,超时和故障注入策略的规则。然而,加权(基于版本)路由是不可能的,因为没有外部服务的多个版本的概念。
有关访问外部服务的更多信息,请参阅出口任务。
网关
甲网关配置HTTP / TCP流量负载平衡器,在网格的边缘最常用操作,以实现入口流量为应用程序。
与Kubernetes Ingress不同,Istio Gateway
仅配置L4-L6功能(例如,要暴露的端口,TLS配置)。然后,用户可以使用标准的Istio规则来控制HTTP请求以及Gateway
通过绑定VirtualService
到它来进入的TCP流量。
例如,以下简单Gateway
配置负载均衡器以允许主机的外部https流量bookinfo.com
进入网格:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
servers:
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- bookinfo.com
tls:
mode: SIMPLE
serverCertificate: /tmp/tls.crt
privateKey: /tmp/tls.key
要配置相应的路由,VirtualService
必须为同一主机定义a 并绑定到Gateway
使用gateways
配置中的字段:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- bookinfo.com
gateways:
- bookinfo-gateway # <---- bind to gateway
http:
- match:
- uri:
prefix: /reviews
route:
...
有关完整的入口网关示例,请参阅入口任务。
虽然主要用于管理入口流量,Gateway
但也可用于模拟纯内部或出口代理。无论位置如何,所有网关都可以以相同的方式进行配置和控制。有关详细信息,请参阅网关参考。
https://istio.io/docs/concepts/traffic-management/rules-configuration/
总结:
Istio中有四种流量管理配置资源:VirtualService,DestinationRule,ServiceEntry和Gateway
VirtualService:
VirtualService定义了控制如何用于服务请求的服务Istio网格内路由的规则。例如,虚拟服务可以将请求路由到不同版本的服务,或者实际上是将请求路由到与请求完全不同的服务。可以根据请求源和目标,HTTP路径和标头字段以及与各个服务版本关联的权重来路由请求。
1、按源/标头限定规则
2、在服务版本之间拆分流量
3、超时和重试
4、在请求路径中注入错误
5、HTTP路由规则优先
DestinationRule:
DestinationRule配置组策略后应用的请求VirtualService
已经发生路由。它们旨在由服务所有者编写,描述断路器,负载平衡器设置,TLS设置等。
1、destinationRule
还定义subsets
2、
断路器
ServiceEntry: 访问外部请求
用于添加额外的条目成Istio内部维护的服务注册。它最常用于启用对Istio服务网格之外的服务的请求。例如,以下内容ServiceEntry
可用于允许外部调用*.foo.com
域下托管的服务。
Gateway:与Kubernetes Ingress不同,Istio Gateway
仅配置L4-L6功能(例如,要暴露的端口,TLS配置)。然后,用户可以使用标准的Istio规则来控制HTTP请求以及Gateway
通过绑定VirtualService
到它来进入的TCP流量。
简而言之:
流程
Gateway (路径匹配) > VirtualService(规则,权重匹配) > DestinationRule(目标服务,断路器) > 具体服务
ServiceEntry: 访问外部请求