我需要为同一主机定义两个VirtualService,.i.e。
主持人:http://customerA.test.example.com,将用于服务两个服务,即“srv”和“srvui”
为了实现这一点,我将虚拟服务定义为:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: srv
namespace: srv-test01
spec:
gateways:
- http-gateway
hosts:
- customerA.test.example.com
http:
- match:
- uri:
prefix: /srv
route:
- destination:
host: srv.srv-test01.svc.cluster.local
port:
number: 8080
和
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: srvui
namespace: srv-test01
spec:
gateways:
- http-gateway
hosts:
- customerA.test.example.com
http:
- match:
- uri:
prefix: /srvui
route:
- destination:
host: srvui.srv-test01.svc.cluster.local
port:
number: 8080
这导致了istio-ingress-gateway的特使conf(两个virtualService都在同一名称空间中)
"name": "customerA.test.example.com:80",
"domains": [
"customerA.test.example.com",
"customerA.test.example.com:80"
],
"routes": [
{
"match": {
"prefix": "/srv"
},
"route": {
"cluster": "outbound|8080||srv.srv-test01.svc.cluster.local",
"timeout": "0s",
"max_grpc_timeout": "0s"
},
"decorator": {
"operation": "srv.srv-test01.svc.cluster.local:8080/srv*"
},
"per_filter_config": {
"mixer": {
"forward_attributes": {
"attributes": {
"destination.service.host": {
"string_value": "srv.srv-test01.svc.cluster.local"
},
"destination.service.uid": {
"string_value": "istio://srv-test01/services/srv"
},
"destination.service.namespace": {
"string_value": "srv-test01"
},
"destination.service.name": {
"string_value": "srv"
},
"destination.service": {
"string_value": "srv.srv-test01.svc.cluster.local"
}
}
},
"mixer_attributes": {
"attributes": {
"destination.service.host": {
"string_value": "srv.srv-test01.svc.cluster.local"
},
"destination.service.uid": {
"string_value": "istio://srv-test01/services/srv"
},
"destination.service.name": {
"string_value": "srv"
},
"destination.service.namespace": {
"string_value": "srv-test01"
},
"destination.service": {
"string_value": "srv.srv-test01.svc.cluster.local"
}
}
}
}
}
},
{
"match": {
"prefix": "/srvui"
},
"route": {
"cluster": "outbound|8080||srvui.srv-test01.svc.cluster.local",
"timeout": "0s",
"max_grpc_timeout": "0s"
},
"decorator": {
"operation": "srvui.srv-test01.svc.cluster.local:8080/srvui*"
},
"per_filter_config": {
"mixer": {
"forward_attributes": {
"attributes": {
"destination.service.namespace": {
"string_value": "srv-test01"
},
"destination.service.name": {
"string_value": "srvui"
},
"destination.service": {
"string_value": "srvui.srv-test01.svc.cluster.local"
},
"destination.service.host": {
"string_value": "srvui.srv-test01.svc.cluster.local"
},
"destination.service.uid": {
"string_value": "istio://srv-test01/services/srv"
}
}
},
"mixer_attributes": {
"attributes": {
"destination.service.host": {
"string_value": "srvui.srv-test01.svc.cluster.local"
},
"destination.service.uid": {
"string_value": "istio://srv-test01/services/srv"
},
"destination.service.name": {
"string_value": "srvui"
},
"destination.service.namespace": {
"string_value": "srv-test01"
},
"destination.service": {
"string_value": "srvui.srv-test01.svc.cluster.local"
}
}
}
}
}
}
]
},
然而,这里的问题是即使是/ srvui的请求最终都在/ srv虚拟服务上,登录istio-ingress-gateway
[2019-02-04T05:46:20.822Z] "**GET /srvHTTP/1.1**" 404 - 0 1077 3 2 "xx.xx.xx.xx, xx.xx.xx.xx" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36" "5fa6611c-07ab-954c-b871-09398bd6c2e4" "customerA.test.example.com" "10.192.21.210:8080" outbound|8080||srv.srv-test01.svc.cluster.local - 10.192.11.185:80 10.192.20.101:36536 ---> **end up on correct service on backend as per virtualService defination**
[2019-02-04T05:46:40.864Z] "**GET /srvuiHTTP/1.1**" 404 - 0 1079 3 1 "xx.xx.xx.xx, 10.192.10.101" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36" "58e17520-a5df-9c90-9ec4-62dbc2bc1307" "customerA.test.example.com" "10.192.21.210:8080" outbound|8080||srv.srv-test01.svc.cluster.local - 10.192.11.185:80 10.192.10.101:54352 ---> Even the context is srvui it is ending up on srv backend.
看起来它取决于其conf中的VirtualService的编号,以使路由生效,
如果我们首先配置srvui virtualService然后srv路由正确发生。
但是问题是,我们需要按编号顺序维护这些服务的部署,我想避免
我不能用“exact”代替“prefix”,因为那时我需要定义100多个精确的URI路径
其他解决方案是更改服务上下文的名称,使它们看起来不像是srv和srvui这样的彼此的子集,因此istio-ingress-gateway可以正确地路由它,但是这也需要更改应用程序。
如果有任何其他解决方案,请告诉我,我可以在这里实施。
这并不奇怪,因为srv
是srvui
的一个子集。
你应该能够使用regex
匹配而不是exact
或prefix
。有关更多完整文档,请参阅https://istio.io/docs/reference/config/istio.networking.v1alpha3/#HTTPMatchRequest。
匹配值的URI区分大小写,格式如下:
- exact:精确字符串匹配的“value”
- prefix:基于前缀的匹配的“value”
- 正则表达式:ECMAscript样式基于正则表达式匹配的“值”