I need to define two VirtualService for same host, .i.e.
host: http://customerA.test.example.com, would be used to serve two service namely "srv" and "srvui"
To Achieve this I respectively, defined Virtual Service as:
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
and
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
This has resulted in envoy conf on istio-ingress-gateway as (both virtualService are in same namespace)
"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"
}
}
}
}
}
}
]
},
However the problem here is that even the request coming for /srvui are ending up on /srv virtual-service, logs on 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.
it looks like it depends on the numbering of VirtualService in its conf for the routing to take effect,
if we configure srvui virtualService first and then srv routing happens correctly.
however the problem with it, we need to maintain the deployment of these service in numbered order, which I would like to avoid
I cannot use "exact" in place of "prefix", because then I would need to defined more than 100 exact URI path
Other solution is to change the name of the service context so that they do not look like subset of each other like here srv and srvui and thus istio-ingress-gateway can route it properly ,however this also require application change.
kindly let me know if there is any other solution, I could implement here.