官方文档介绍:https://istio.io/latest/docs/concepts/traffic-management/
Istio服务网格中的核心资源:
这些核心资源都是用于配置Istio流量管理的资源控制器。
在Istio服务网格中,IngressGateway是集群访问的入口,IngressGateway针对应用程序的流量转发控制进行了解耦,分为了两种资源控制器(Gateway和VirtualService),通过这两种资源控制器相互配合,完成流量的转发管理。
Gateway网关资源主要是为网格内的服务提供一个对外访问的入口,类似于Ingress资源,将网格内的应用程序发布在互联网环境。
Gateway网关资源需要配合VirtualService资源才能完成应用程序对外暴露的规则配置信息,Gateway与VirtualService定义的转发规则最终会配置在Istio的Ingressgateway服务中。
Gateway资源相当于Nginx中的server{}模块,用于接收流量,VirtualService资源相当于Nginx中的location模块,用于处理流量的转发,两个资源之间需要相互配合才能完成流量的管控。
如下图所示:用户的请求首先到达LB负载均衡,然后转发至Istio的IngressGateway,根据Gateway和VirtualService资源生成的程序转发规则,将请求转发至应用程序的Service资源上,最后由具体的Pod资源提供服务。
apiVersion: networking.istio.io/v1alpha3
kind: Gateway #资源类型为Gateway
metadata:
name: knowsystem-gw #资源的名称
spec:
selector: #定义选择器
istio: ingressgateway #关联带有istio=ingressgateway标签的gateway组件,然后会将配置的转发信息写入到该gateway组件中
servers: #定义服务列表
- port: #定义服务使用的端口号
number: 80 #端口号为80
name: http #端口的名称
protocol: HTTP #端口的协议
hosts: #接收那些主机的流量
- "*" #可以是"*"所有主机、"*.jiangxl.com"泛域名、"knowsystem.jiangxl.com"单个域名
VirtualService是Istio流量治理的核心配置资源,所有的流量控制策略都是由VirtualService资源实现的,Gateway资源相当于流量的入口,流量如何管控是由VirtualService资源实现的。
VirtualService资源是虚拟服务,将满足条件的流量转发到对应的服务后端,或者将全部流量安装一定的权重分配到不同的流量规则,由多个版本按照比例处理请求。
VirtualService资源中destination的host字段配置的时候一定要是k8s集群中存在的service资源,否则Envoy不知道该将流量转发给谁,在spec.hosts字段中配置的如果是service资源,无需指定service的完整名称,只需要指定service资源的名称就会自动添加service资源所在的namespace以及k8s地址,例如knowsystem-svc.prod-knowsystem.svc.cluster.local,不过自动添加的namespace是virtualservice所在的namespace,也可以指定完整的名称。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: knowsystem-vs
namespace: prod-knowsystem
spec:
hosts: #定义虚拟主机,这个主机名称是客户端向服务发送请求时使用的一个或多个地址,接收来自这个地址的请求然后进入到此VirtualService,进行流量的管控
- "*" #地址列表可以填写多个,网格内部服务访问通常使用的是Service资源的名称,外部用户要访问网格内的服务时,这里就需要填写与Gateway中hosts字段一致,一般都是域名
gateways: #关联Gateway资源,Gateway是入口,VirtualService处理流量分配
- knowsystem-gw
http: #定义http流量的管理列表
- route: #定义流量转发规则
- destination: #定义匹配的路由规则
host: knowsystem-svc #将流量转发到后端应用程序的Service资源
subset: v1 #引用名称为v1的路由规则
weight: 90 #定义权重值比例,意思就是说将流量请求按90%的权重分配到v1路由规则上,v1路由规则对应的是V1版本的Pod资源。
- destination:
host: knowsystem-svc
subset: v2 #引用名称为v1的路由规则
weight: 10 #权重值为90,意思就是说将流量请求按90%的权重分配到v1路由规则上,v1路由规则对应的是V1版本的Pod资源。
流量比例分配如果先写weight再写destination参数就更容易理解了,如下图所示,接收到的90%的流量转发到V1版本的路由规则,接收到的10%的流量转发到V2版本的路由规则。
VirtualService还可以匹配满足的条件,然后对流量进行控制,相当于优先级模式,当满足条件后匹配v1路由规则,不满足条件时匹配v2路由规则。
可以实现重定向、重写、重试、故障注入、跨站策略等等,不仅可以做路由规则匹配还支持修改请求本身。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- match: #定义规则匹配
- headers: #以HTTP请求头中包含的信息进行匹配
end-user:
exact: jiangxl #匹配请求头中user字段为jiangxl的流量
route: #将满足匹配条件的流量进行流量路由规则
- destination: #将流量路由到reviews的Service资源中v3名称的路由规则上,由v3版本的Pod资源提供服务
host: reviews
subset: v3
- route: #如果不满足匹配的条件,那么就按照下面的路由规则进行匹配
- destination:
host: reviews
subset: v2 #将流量转发到reviews的Service资源中v2名称的路由规则上,有v2版本的Pod资源提供服务
上面的配置清单中,当满足user为jiangxl的流量请求会被match进行匹配,随后路由到V3版本的路由规则上,如果不满足条件则路由到V2版本的路由规则中。
VirtualService虚拟服务资源还可以进行多路由的规则匹配,例如请求不同url时跳转到不同的路由规则进行匹配。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- bookinfo.com
http:
- match: #匹配url为/reviews的流量请求
- uri:
prefix: /reviews
route: #将匹配的流量请求路由到reviews Service资源中
- destination:
host: reviews
- match: #匹配url为/ratings的流量请求
- uri:
prefix: /ratings
route:
- destination:
host: ratings #将匹配的流量请求路由到ratings Service资源中
访问http://bookinfo.com/reviews时会被路由到reviews的Service资源中,由reviews的Pod资源提供服务
访问http://bookinfo.com/reviews时会被路由到ratings的Service资源中,由ratings的Pod资源提供服务
DestinationRule是istio流量路由匹配的重要组成部分,VirtualService用于定义流量分发的目的地,而DestinationRule就是去配置这个目的地,如果没有这个目的地,那么流量也是无法路由匹配的。
DestinationRule主要用于配置流量路由分发的目标,VirtualService路由规则起作用之后,由DestinationRule转发到真实的目的地。
流量基于三种核心资源转发流程:
Gateway—>VirtualService—>Router—>DestinationRole—>Service
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: knowsystem-dr
namespace: prod-knowsystem
spec:
host: knowsystem-svc #针对哪一个Service资源配置路由转发规则
subsets: #定义路由规则子集
- name: v1 #路由规则的名称,会在VirtualService资源中引用,然后将请求路由到定义的规则上
labels: #通过标签进行匹配
version: v1 #匹配version=v1标签的Pod资源,这一组路由规则的意思就是将请求通过这个路由规则转发到含有version=v1标签的Pod资源上
- name: v2
labels:
version: v2 #匹配version=v2标签的Pod资源,这一组路由规则的意思就是将请求通过这个路由规则转发到含有version=v2标签的Pod资源上