Istio通过流量管理API进行流量配置。流量管理API使用Kubernetes的CRDs(自定义资源定义)来声明。 本节学习在前面2节配置请求路由中用过的两个API资源:虚拟服务VirtualService和目标路由DestinationRule。
虚拟服务VirtualService使用虚拟服务可以为一个或多个主机名(hostnames)指定流量行为。在虚拟机服务中使用路由规则(route)告诉Envoy如何发送虚拟服务的流量到适当的目标(destination)。 路由(route)的目标(destination)可以是同一服务的不同版本,也可以是完全不同的服务。
下面是一个典型的用例,将流量发送到被指定为服务子集的不同版本。客户端将虚拟服务视为一个单一实体将请求发送到虚拟服务reviews,然后Envoy根据虚拟服务规则将流量路由到不同版本,25%的流量调用转到reviews服务的v2版本。 这是一个金丝雀发布的场景,逐步增加发送到新版本服务的流量百分比。
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
虚拟服务有如下两个使用场景:
通过单个虚拟服务处理多个应用程序服务,例如配置一个虚拟服务处理Kubernetes特定命名空间中的所有服务。映射单一的虚拟服务到多个“真实”服务,可以在不需要客户适应转换的情况下,将单体应用转换为微服务构建的复合应用系统。和网关整合并配置流量规则来控制出入流量再来看一下“基于用户身份进行请求路由”这个例子中创建的虚拟服务VirtualService,将根据请求是否来自特定的用户,把它们路由到服务的不同版本:
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字段指定虚拟服务的主机,是路由规则的应用目标,是客户端向服务发送请求时使用的一个或多个地址,这里只有一个reivews。 虚拟服务的主机名hosts可以是IP地址,DNS名称或者依赖于平台的一个简称(例如Kubernetes服务的短名称),隐式或显式的指向一个完全限定域名(FQDN)。 也可以使用通配符*前缀来创建一组匹配所有服务的路由规则。虚拟服务的hosts字段实际上不必是istio服务注册的一部分,它只是虚拟的目标地址,这样就可以为没有路由到网格内部的虚拟主机建模。
http字段包含了虚拟服务的路由规则,用来描述匹配条件和路由行为。通过路由规则把HTTP1.1, HTTP2和gRPC等流量发送到hosts字段指定的目标。一个路由规则具有0个或多个匹配条件(match),并包含指定的请求要流向哪个目标地址(destination)。 示例中的第一个路由规则就有一个匹配条件,以match字段开始,通过使用headers, end-user, exact等字段匹配请求头end-user=jason的请求。 route部分的destination字段指定了符合此条件的流量的实际目标地址。与虚拟机服务的hosts字段不同,destination的host字段必须是存在于isito服务注册中心的实际目标地址, 否则Envoy不知道将请求发送到哪里。在本例中host为Kubernetes中的reviews服务名(这里使用的Kubernetes服务的短名称设置)。destination片段还指定了reviews这个Kubernetes服务子集subset。
路由规则在匹配时按从上到下的顺序选择。因此一般建议提供一个默认的“无条件”或基于权重的规则作为每个虚拟服务的最后一条路由规则,确保流经虚拟服务的流量至少能够匹配一条路由规则。
路由规则是将特定流量子集路由到指定目标地址的强大工具。可以在流量端口、header 字段、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
...
http:
- match:
sourceLabels:
app: reviews
route:
路由规则的配置十分灵活,除了上面例子中已经展示的,还可以使用路由规则在流量上执行一些操作,例如添加删除header、重写URL、为调用这一目标地址的请求设置重试策略等。 关于VirtualService的更多内容可以查看官方的配置手册https://istio.io/latest/zh/docs/reference/config/networking/virtual-service。
目标规则DestinationRule虚拟服务用来配置如何将流量路由到目标地址,而目标规则就是用来配置流量真实的目标地址上的。可以使用目标规则来指定命名的服务子集,例如按版本为所有给定服务的实例分组,然后可以在虚拟服务的路由规则中使用这些服务子集来控制到服务不同实例的流量。 使用目标规则还可以在调用这个目标服务或特定子集时定制Envoy的流量策略,例如负载均衡策略、TLS安全模式或熔断器设置。
默认情况下,Istio使用轮询(ROUND_ROBIN)的负载均衡策略,实例池中的每个实例依次获取请求。Istio同时支持如下的负载均衡模型,可以在目标规则DestinationRule中为流向某个特定服务或服务子集的流量指定这些模型。
随机(RANDOM):请求以随机的方式转到池中的实例。权重:请求根据指定的百分比转到实例。最少请求(LEAST_CONN):请求被转到最少被访问的实例在下面的示例中,目标规则为my-svc目标服务的3个子集配置了负载均衡策略,v1,v3为RANDOM,v2为ROUND_ROBIN:
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定义的,在Kubernetes中它是附加到像Pod这种对象上的键/值对。这些标签应用于Kubernetes服务的Deployment并作为metadata来识别不同的版本。
总结本节学习了Isito流量管理API的两个资源对象VirtualService和DestinationRule。 虚拟服务用来配置如何将流量路由到目标地址,虚拟服务的路由规则可以在流量端口、header 字段、URI 等内容上设置匹配条件,将流量到路由到适当的目标,同时还可以使用路由规则在流量上执行一些操作,例如添加删除header、重写URL、为调用这一目标地址的请求设置重试策略等。 目标规则是应用在目标地址上的规则,使用目标规则可以在调用这个目标服务或特定子集时定制Envoy的流量策略,例如负载均衡策略、TLS安全模式或熔断器设置。
参考https://istio.io/latest/zh/docs/concepts/traffic-managementhttps://istio.io/latest/zh/docs/reference/config/networking/virtual-servicehttps://istio.io/latest/zh/docs/reference/config/networking/destination-rule/