K8s+istio通过虚拟服务实现路由的一些心得
在istio里,通过虚拟服务(vs)与gateway的绑定,结合目标策略(distinationrule,DR)定义的规则,提供了从服务暴露到流量分配的实现,gateway比较简单,主要用于声明istio的ingress控制器,需要重点关注的是vs与dr进行流量的,而dr通常仅作负载均衡方式、连接池、tls、端口流量等等的规则性说明,与实际路由指向关系不大。and 和or语义。。。
在istio里,通过虚拟服务(vs)与gateway的绑定,结合目标策略(distinationrule,DR)定义的规则,提供了从服务暴露到流量分配的实现,gateway比较简单,主要用于声明istio的ingress控制器,需要重点关注的是vs与dr进行流量的,而dr通常仅作负载均衡方式、连接池、tls、端口流量等等的规则性说明,与实际路由指向关系不大。所以个人认为,搞定了vs配置,基本上就可以满足大部分的路由需求。下面是关于vs的一些简单实践。供分享或指正。
vs可定义精确的匹配规则,目前有5类,包括http头(header),schema(http、https、ftp等),authority(匹配authority头),method(方法, 如get、post等),uri(匹配的url)。下面我们主要以header为案例展开讨论。
针对header,除了常规使用的destination外,vs还可以将请求进行header重写或重定向,例如我们希望把/v1改为/v2,可以采用rewrite字段,定义到/v2;或者利用redirect直接重定向到另外一个完全不同的服务,例如v1是customer服务,但可以在redirect指定hearer为hello的服务,重定向到uri为/hello的服务。留意,vs配置中,destination与redirect字段是相斥的,如果某个服务使用了redirect,就不需要设置destination。
vs配置中,在匹配时,可以使用and和or语义,这个在精确路由时非常有用,参考如下:
使用and语义:
http:
- match:
- uri:
prefix: /v1
headers:
myheaders:
extract: httpdemo
上面定义了前缀为v1,同时(and)http头为精确的值httpdemo。
使用or语义
http:
- match:
- uri:
prefix: /v1
.....
- match:
- headers:
myheaders:
extract: httpdemo
这里定义了or,系统首先匹配uri前缀是否/v1,如果是,直接路由到v1,如果不是,匹配header是否httpdemo。(留意,在vs中设置显式权重比较有助于控制你的流量。假设你有两个服务,不声明权重的话,它就按照大概5:5这样的比例分发,就像没有配置vs一样,但我不是很确定是否必然按这个比例。所以,保险起见,建议有需要的话最好还是指定权重。)
以下是我做的一个测试。创建两个pod,建立服务,创建一个vs配置,加上header的定义,如下:
http:
- match:
- headers:
user:
exact: batman
route:
- destination:
host: customers.istio-test.svc.cluster.local
port:
number: 80
subset: v2
- route:
- destination:
host: customers.istio-test.svc.cluster.local
port:
number: 80
subset: v1
以上定义了一个headr规则,user: batman,如果匹配,流量走向服务v2,kubectl apply后进行测试。
curl -H "user: batman" http://你的域名:端口
或者浏览器装一个插件(我用modhearder,还可以的一个插件)。
最后通过kiali观察流量走向,可以发现,所有hearder添加了user: batman的请求,都会跑到v2上。上面提到的customers镜像,由于被墙的关系,官方提供的路径下载不了,可以用docker.io/pj3677的版本。
更多推荐
所有评论(0)