istio: Multiple virtualservices on the same host do not merge
Describe the bug I did the similar test with deploying 2 applications as reported in #6046 - bookinfo and httpbin. One of the applications always returns 404 in the following cases:
case 1: single namespace bookinfo app - bookinfo-gateway and bookinfo virtualservice httpbin app - httpbin-gateway and httpbin virtualservice
case 2: single namespace with single gateway bookinfo app - bookinfo-gateway and bookinfo virtualservice httpbin app - httpbin virtualservice (with short name bookinfo-gateway defined in gateways list)
case 3: multiple namespaces with single gateway bookinfo app - bookinfo-gateway and bookinfo virtualservice in namespace1 httpbin app - httpbin virtualservice in namespace2 (with fqdn bookinfo-gateway.namespace1.svc.cluster.local defined in gateways list)
the application returns 200 if I removed the other virtualservice file in above case. here are the yaml files of the gateway and virtualservices for case 2:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"networking.istio.io/v1alpha3","kind":"Gateway","metadata":{"annotations":{},"name":"bookinfo-gateway","namespace":"default"},"spec":{"selector":{"istio":"ingressgateway"},"servers":[{"hosts":["*"],"port":{"name":"http","number":80,"protocol":"HTTP"}}]}}
clusterName: ""
creationTimestamp: 2018-08-03T18:35:36Z
generation: 1
name: bookinfo-gateway
namespace: default
resourceVersion: "10845"
selfLink: /apis/networking.istio.io/v1alpha3/namespaces/default/gateways/bookinfo-gateway
uid: 039d51b8-974c-11e8-a97b-00505680c68c
spec:
selector:
istio: ingressgateway
servers:
- hosts:
- '*'
port:
name: http
number: 80
protocol: HTTP
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"networking.istio.io/v1alpha3","kind":"VirtualService","metadata":{"annotations":{},"name":"bookinfo","namespace":"default"},"spec":{"gateways":["bookinfo-gateway"],"hosts":["*"],"http":[{"match":[{"uri":{"exact":"/productpage"}},{"uri":{"exact":"/login"}},{"uri":{"exact":"/logout"}},{"uri":{"prefix":"/api/v1/products"}}],"route":[{"destination":{"host":"productpage","port":{"number":9080}}}]}]}}
clusterName: ""
creationTimestamp: 2018-08-03T19:10:19Z
generation: 1
name: bookinfo
namespace: default
resourceVersion: "10535"
selfLink: /apis/networking.istio.io/v1alpha3/namespaces/default/virtualservices/bookinfo
uid: dce03829-9750-11e8-a97b-00505680c68c
spec:
gateways:
- bookinfo-gateway
hosts:
- '*'
http:
- match:
- uri:
exact: /productpage
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
host: productpage
port:
number: 9080
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"networking.istio.io/v1alpha3","kind":"VirtualService","metadata":{"annotations":{},"name":"httpbin","namespace":"default"},"spec":{"gateways":["bookinfo-gateway"],"hosts":["*"],"http":[{"match":[{"uri":{"prefix":"/status"}},{"uri":{"prefix":"/delay"}},{"uri":{"prefix":"/headers"}}],"route":[{"destination":{"host":"httpbin","port":{"number":8000}}}]}]}}
clusterName: ""
creationTimestamp: 2018-08-03T18:57:54Z
generation: 1
name: httpbin
namespace: default
resourceVersion: "10157"
selfLink: /apis/networking.istio.io/v1alpha3/namespaces/default/virtualservices/httpbin
uid: 20d0e173-974f-11e8-a97b-00505680c68c
spec:
gateways:
- bookinfo-gateway
hosts:
- '*'
http:
- match:
- uri:
prefix: /status
- uri:
prefix: /delay
- uri:
prefix: /headers
route:
- destination:
host: httpbin
port:
number: 8000
Expected behavior I assume both case 2 and case 3 (#6483 should have fixed the issue) should work in 1.0.
Version Version: 1.0.0 GitRevision: 3a136c90ec5e308f236e0d7ebb5c4c5e405217f4 User: root@71a9470ea93c Hub: gcr.io/istio-release GolangVersion: go1.10.1 BuildStatus: Clean
Client Version: version.Info{Major:“1”, Minor:“10”, GitVersion:“v1.10.2”, GitCommit:“81753b10df112992bf51bbc2c2f85208aad78335”, GitTreeState:“clean”, BuildDate:“2018-04-27T09:22:21Z”, GoVersion:“go1.9.3”, Compiler:“gc”, Platform:“linux/amd64”} Server Version: version.Info{Major:“1”, Minor:“10”, GitVersion:“v1.10.6”, GitCommit:“a21fdbd78dde8f5447f5f6c331f7eb6f80bd684e”, GitTreeState:“clean”, BuildDate:“2018-07-26T10:04:08Z”, GoVersion:“go1.9.3”, Compiler:“gc”, Platform:“linux/amd64”}
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 26 (11 by maintainers)
@louiscryan this is not acceptable, and a clear regression of virtual services from the ingress resources that existed in 0.6. What is the complication of just supporting what was supported in 0.6? Doing this kind of post processing especially in dynamic systems causes a ton of edge cases for the post processor specifically around the removal and updating of routes.
This should be fixed ASAP, to be in parity with the way it worked in 0.6.
@ZackButcher ^^
cc @rshriram @louiscryan This is an issue for a customer. The customer uses helm to manage multiple services. These services share the host but use different URI matches on two virtual services. What should be the advice for people who use helm to manage ingress-type resources?
I understand the concern, but this argument is a clear strawman. The possibility of ambiguities is problematic, I will concede that.
The problem we are facing is not with ambiguous matches. We are currently blocked because Istio does not support merging routes at all. Give us enough rope to hang ourselves. That’s all I’m asking.
@nrjpoddar Well, I do not agree to the path of having to change files as services get installed. if that were the case, would just update the virtual service to include all needed URIs. My opinion is to give more thought and treat multiple files as pure conf files which can be merged.
Really? Does that mean merging the following examples would be nondeterministic?
for host example.com match path /hello and route to X
for host example.com match path /world and route to Y
@rshriram @vadimeisenbergibm Hostname per service seems a lot to ask customers to setup/configure if we have more than say 10 services to be exposed. Here is a scenario where a standard nginx has worked well for me in the past
Wondering how this can be done using Istio ingress-gateway? i.e something like do not treat virtualservice with same host as error but really treat as a merge. This way each service can bring their own match parameters and not need to keep modifying the same Virtual service using something centralized. May be these last few statements are based on me not knowing if there is a way to achieve this already.
@louiscryan thanks for your response! I’ve provided a relatively contrived but as simple example as I can provide to help with context below.
Just a couple of comments before I describe the scenario:
The scenario is you have serviceA and serviceB each belong behind a single subdomain subdomain1 and are routed to unique input channels. The input channels cannot be added to the host because they would violate RFC-1035 size limits as we don’t have control over what they are.
I would constrain scope here, leverage reasonable assumptions to get the job done. We’re/were EEP so I’m happy to come to MV or SF office and work with ya’ll.