在VirtualService中,tls是一种TLSRoute类型的路由集合,用于处理非终结的TLS和HTTPS的流量,使用SNI(Server Name Indication,客户端在TLS握手阶段监理连接使用的Hostname)做路由选择。在TLSRoute被应用于以下场景中。
apiVerison: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: total-weather-tls
namespace: weather
spec:
host:
- "*.weather.com"
gateway:
- ingress-gateway
tls:
- meatch:
- port: 443
sniHosts:
- forntend.weather.com
route:
- destination:
host:frontend
- meatch:
- port: 443
sniHosts:
- recommendation.weather.com
route:
- destination:
host: recommendation
在以上示例中,可以通过HTTPS方式从外部访问weather应用内部的两个HTTPS服务frontend和recommendation,访问目标端口是443且SNI是“frontend.weather.com”的请求被转发到frontend服务上,访问目标端口是443并且SNI是“recommendation.weather.com”的请求会被转发到recommendation服务上。
TLSRoute的规则定义比HTTPRoute简单很多,规则逻辑也是将满足一定条件的流量转发到对应后端。在规则定义中,匹配条件是TLSMatchAttributes,路由规则目标是RouteDestination。
在TLSRoute中,match字段是一个TLSMatchAttributes类型的数组,表示TLS的匹配条件。下面来讲解一下TLS服务的请求特征。
可以看到,sniHosts和destinationSubnets属性是TLS特有的,port、sourceLabels和gateways属性同HTTP的条件定义。一般的用法是匹配port和sniHosts。
TLS的路由目标通过RouteDestination来描述转发的目的地址,这是一个四层路由转发地址,包含两个必选属性destination和weight。
RouteDestination上的这两字字段在使用上有较多注意点。用法和约束同HTTPRouteDestination的对应字段。
所有不满足以上HTTP和TLS条件的流量都会应用TCP流量规则。
如下所示,将来自forecast服务23003端口的流量转发到inner-forecast服务的3003端口。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: forecast
namespace: weather
spec:
hosts:
- forecast
tcp:
- match:
- port: 23003
route:
- destination:
host: inne-forecast
port:
number: 3003
与HTTP和TLS类似,TCPRoute的规则描述的也是将满足一定条件的流量转发到对应的目标后端,其目标后端的定义和TLS相同,也是RouteDestination。下文将重点关注TCP特有的四层匹配规则L4MatchAttributes。
在TCPRoute中,match字段也是一个数组,元素类型是L4MatchAttributes,支持一下匹配属性:
这几个参数和TLSMatchAttributes对应字段的意义相同,如下所示为基于端口和源工作负载标签描述TCP流量的典型示例:
tcp:
- match:
- sourceLabels:
group: beta
- port:23003
VirtualService 在http、tls、tcp这三个字段上分别定义了应用于HTTP、TLS和TCP三种协议的路由规则。从规则构成上都是先定义一组匹配条件,然后对满足条件的的流量执行对应的操作。因为协议的内容不同,路由匹配条件不同,所以执行的操作也不同。如下表所示对比了三种路由规则。从各个维度来看,HTTP路由规则的内容最丰富,TCP路由规则的内容最少,这也符合协议分层的设计。
比较内容 | HTTP | TLS | TCP |
---|---|---|---|
路由规则 | HTTPRoute | TLSRoute | TCPRoute |
流量匹配条件 | HTTPMatchRequest | TLSMatchAttributes | L4MatchAttributes |
条件属性 | uri、scheme、method、authority、port、sourceLabels、gateway | sniHosts、destinationSubnets、port、sourceLabels、gateway | destinationSubnets、port、sourceLabels、gateway |
流量操作 | route、redirect、rewrite、retry、timeout、faultInjection、corsPolicy | Route | Route |
目标路由定义 | HTTPRouteDestination | RouteDestination | RouteDestination |
目标路由属性 | destination、weight、headers | destination、weight | destination、weight |
下面结合几个典型的使用场景来看看VirtualService的综合使用。
VirtualService是一个广义的Service,在如下配置中可以将一个weather应用的多个服务组成一个大的虚拟服务。根据访问路径得不同,对weather服务的访问会被转发到不同的内部服务上。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: weather
namespace: weather
spec:
hosts:
- weather.com
http:
- match:
- uri:
prefix: /recommendation
route:
- destination:
host: recommendation
- match:
- uri:
prefix: /forecast
route:
- destination:
host: forecast
- match:
- uri:
prefix: /advertisemment
route:
- destination:
host: advertisemment
假设访问“weather.com”服务,则根据不同的路径,流量会被分发到不同的后端服务上。当然,在内部服务间的访问,更常规的用法是直接使用服务名。
我们可以对VirtualService设置N条规则,在VirtualService中通过路由的顺序即可明确表达规则,哪条规则在前面,谁的优先级就高。在下面的配置中,以“/weather/data”开头的流量被转发到v3版本,以“/weather”开头的其他流量被转发到v2版本,其他流量被转发到v1版本。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: forecast
namespace: weather
spec:
hosts:
- forecast
http:
- match:
- uri:
perfix: "/weather/data"
route:
- destination:
name: forecast
subset: v3
- match:
- uri:
perfix: "/weather"
route:
- destination:
name: forecast
subset: v2
- route:
- destination:
name: forecast
subset: v1
在路由规则执行时,只要有一个匹配,规则执行就会跳出。所有随便调整以上的三条规则,则可能导致另一条规则在理论上将没有流量。
灰度发布分流规则一般有两种方式:一种是基于请求的内容切分流量,另一种是比例切分流量。实际上,根据需要也可以结合使用。如下所示:
apiVersiom: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: forecast
namespace: weather
spec:
hosts:
- forecast
http:
- match:
- headers:
cookie:
regex:"xxxxx"
uri:
prefix: "/weather"
- uri:
prefix: "data"
route:
- destination:
name: forecast
subset: v3
weight: 20
- destination:
name: forecast
subset: v2
weight: 80
- route:
- destination:
name: forecast
subset: v1
对于forecast服务的请求,当请求的cookie满足“xxx”正则表达式,且uri的前缀为“/weather”,或者uri的前缀为“/data”时,流量走forecast的v2、v3版本,其中v2流量占80%,v3占20%。其余的流量都走forcast的v1版本。
现在来看下一个通用字段sourceLabels,该字段可以用来过滤访问源。如下配置所示,只对frontend服务的v2版本到forecast服务的v1版本的请求设置20s的延迟。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
medata:
name: forecast
namespace: weather
spec:
hosts:
- forecast
http:
- match:
- sourceLabels:
app: frontend
version: v2
fault:
delay:
fixeDelay: 20s
route:
- destination:
name: forecast
subset: v1
以上只是典型的应用,掌握了规则的定义和语法,边可以自由配置需要的多业务功能,非常灵活方便。
可能会觉得很复杂,所以要加强练习,后面的一些资源对象规则则没有复杂了。
(如果觉得写得还好,请多多点赞,觉得有用就收藏起来,方便食用)