VirtualService routing based on uri prefix

I created a VirtualService like this to try to make a route to the Jaeger UI:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: jaeger-vs
spec:
  hosts:
  - "*"
  gateways:
  - my-gateway
  http:
  - match:
    - uri:
        prefix: "/tracing/"
    rewrite:
      uri: "/"
    route:
    - destination:
        port:
          number: 80
        host: tracing.istio-system.svc.cluster.local

It makes a call to http://<my-ip-address>/tracing/ and returns a 200, but then it tries to make calls for some static assets like favicon.ico which is actually to http://<my-ip-address>/favicon.ico and I was expecting it to go to http://<my-ip-address>/tracing/favicon.ico

I might not be understanding the purpose of “rewrite”, but I thought it was so that I could use one VirtualService to route to different services, so /serviceA/ goes to serviceA, but when it gets there, the path would only have “/” because of the rewrite.

Any ideas how I can go about this path-based routing to the Jaeger UI? Thanks!
(this is just to simplify debugging - I’d like to avoid Host-based routing / SNI so I don’t have to change my hosts file, etc)
Edit* Oh, and we’re using Istio 1.0.2 for now - we are lagging a bit behind, since we had some trouble with later versions.

1 Like

I’m starting to think that what I’m trying to do doesn’t make sense… I think I’ll just do Host-header based routing, unless someone can help me figure out how a path-based approach might work.

Change the above block to look like this:

  http:
  - match:
    - uri:
        prefix: /
    rewrite:
      uri: /tracing/

Thanks @Sourabh_Wadhwa - I am not sure if this works with multiple services though, since both would have to match prefix: /

Basically /serviceA/ gets routed to serviceA and /serviceB/ gets routed to service B (and in both services the request comes in as if the path were “/”).

But I’m not sure if that’s possible anymore, since the SPA requesting resources has no way of knowing that requests it makes should include the “/serviceX/” prefix.

Thanks for your help though!

Hello @adinunzio84,

I am still unclear about your requirement a little, For my particular case I had following cases:

/api/browse – should go to browse microservcie
/api/auth – should go to auth microservice
/api – should go to ML service
/ – Should go to UI service

my virtual service looked like:

> kind: VirtualService
> metadata:
>   name: routes
>   namespace: ui-istio
> spec:
>   gateways:
>   - my-gateway
>   hosts:
>   - istio.example.com
>   http:
>   - match:
>     - uri:
>         prefix: /api/browse
>     rewrite:
>       uri: /
>     route:
>     - destination:
>         host: browse.browse-istio.svc.cluster.local
>         port:
>           number: 80
>   - match:
>     - uri:
>         prefix: /api/auth
>     rewrite:
>       uri: /
>     route:
>     - destination:
>         host: auth.auth-istio.svc.cluster.local
>         port:
>           number: 80
>   - match:
>     - uri:
>         prefix: /api/
>     rewrite:
>       uri: /
>     route:
>     - destination:
>         host: ml.ml-istio.svc.cluster.local
>         port:
>           number: 80
>   - match:
>     - uri:
>         prefix: /
>     route:
>     - destination:
>         host: ui.ui-istio.svc.cluster.local
>         port:
>           number: 80

Here Istio will read the config from top to bottom

Thanks for the help @Sourabh_Wadhwa, but I decided to use host-based routing and set my hosts.txt file to point to my ingress for the different hosts.

Your post helped me achieve that though - much appreciated.

The only thing left holding me back is that the Jaeger operator creates headless services, which doesn’t work with Istio VirtualServices.

Hey @adinunzio84, Can you please elaborate on how you did this ? I actually have a requirement where this solution can help me in my setup.

Sorry for the delay @Sourabh_Wadhwa - I just did this for debugging purposes, but I modified my /etc/hosts file to have the IP of my ingress associated with all the different “hosts” for my service (e.g. I used “serviceA.lh” as one), so I then made multiple VirtualServices for the different hosts, and they all shared the same gateway:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-vs
spec:
  hosts:
  - "serviceA.lh"
  gateways:
  - "my-gateway"
  http:
  - route:
    - destination:
        port:
          number: 80
        host: serviceA.svcAnamespace.svc.cluster.local

Then I could access each service in this way in my browser. With that said, it does not work for routing to the Jaeger UI created by the jaeger operator because the query service it makes is headless.