我需要为同一主机定义两个VirtualService,即
主机: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路由。
但是问题出在哪里,我们需要按编号顺序维护这些服务的部署,我想避免
我不能使用“精确”代替“前缀”,因为那样的话我需要定义100个以上的确切URI路径
其他解决方案是更改服务上下文的名称,以使它们看起来不像彼此的子集,如srv和srvui,因此istio-ingress-gateway可以正确路由它,但是这也需要更改应用程序。 / p>
请让我知道是否还有其他解决方案,我可以在这里实现。
答案 0 :(得分:3)
这并不奇怪,因为srv
是srvui
的子集。
您应该能够使用regex
匹配而不是exact
或prefix
。有关更多完整文档,请参见https://istio.io/docs/reference/config/istio.networking.v1alpha3/#HTTPMatchRequest。
匹配值的URI区分大小写,其格式如下:
- 精确:“值”表示完全匹配的字符串
- 前缀:用于基于前缀的匹配的“值”
- regex:ECMAscript样式基于正则表达式的匹配的“值”