Header rule does not work internally

Hi folks,

I have two VirtualService objects… one that does a 20-80 traffic split and another that looks for a header.

They work when accessing my service through the Ingress gateway. When I add the header, I can see it going to the correct subset all the time. And when I don’t have it, I can see the 20-80 traffic split happening. All good there.

However, when I access the service internally (e.g. from inside another service’s container: curl helloworld:5000/hello), while the traffic split is still happening from what I can tell, the header rule is not taking effect. When I add the header, I can see it in the curl verbose output, but it does not affect the routing. It just goes and applies the 20-80 traffic split.

Could there be a bug with internal calls when there’s more than one virtual service involved?

Thanks,
jaid

I’ve confirmed that the header rule works if one VirtualService object has both the header rule and the traffic split.

Is this a known issue with multiple VirtualService objects?

This page: https://istio.io/docs/ops/best-practices/traffic-management/#split-virtual-services does have this:

A VirtualService can only be fragmented this way if it is bound to a gateway. Host merging is not supported in sidecars.

I think that addresses what I’m seeing. Is there a plan to make multiple VirtualServices work for sidecars, too?

Any workaround besides merging them into one?

You need to specify mesh as the gateway in your virtual service, this is the default gateway for mesh unter traffic.

Thanks. It still doesn’t work though when I have two separate VirtualService objects. See below. The second one looks for a header. It does not take effect when I hit the service from another pod in the cluster (it just does the traffic split). But it works great if I hit it from the outside (it always goes to v2). Both of them have “mesh” as one of their gateways. When I combine them into one VirtualService, the header rule works in both scenarios.

apiVersion: v1
items:
- apiVersion: networking.istio.io/v1beta1
  kind: VirtualService
  metadata:
    name: helloworld
    namespace: hw
        spec:
    gateways:
    - my-shared-gateway
    - mesh
    hosts:
    - myhost.mycompany.com
    - helloworld.hw.svc.cluster.local
    http:
    - route:
      - destination:
          host: helloworld
          port:
            number: 5000
          subset: v1
        weight: 80
      - destination:
          host: helloworld
          port:
            number: 5000
          subset: v2
        weight: 20

2nd VirtualService with Header Rule

- apiVersion: networking.istio.io/v1beta1
  kind: VirtualService
  metadata:
    name: helloworld-test
    namespace: hw
  spec:
    gateways:
    - my-shared-gateway
    - mesh
    hosts:
    - myhost.mycompany.com
    - helloworld.hw.svc.cluster.local
    http:
    - match:
      - headers:
          Target-Version:
            exact: target
      route:
      - destination:
          host: helloworld
          port:
            number: 5000
          subset: v2

Hi try this may be this will help you. or also see this https://istio.io/docs/ops/common-problems/network-issues/#route-rules-have-no-effect-on-ingress-gateway-requests

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: helloworld
  namespace: hw
spec:
  hosts:
  - myhost.mycompany.com
 - helloworld.hw.svc.cluster.local
  gateways:
  - mesh # applies internally as well as externally
  - myapp-gateway
  http:
  - match:
    -  gateways:
          - myapp-gateway #restricts this rule to apply only to ingress gateway
    route:
    - destination:
        host: helloworld
          port:
            number: 5000
          subset: v1
        weight: 80
      - destination:
          host: helloworld
          port:
            number: 5000
          subset: v2
        weight: 20
    http:
    - match:
      - headers:
          Target-Version:
            exact: target
        gateways:
          - mesh 
      route:
      - destination:
          host: helloworld
          port:
            number: 5000
          subset: v2

Thanks. But I have no problem with a single VirtualService object. My challenge is with more than one. For now, I’ve come to terms with that limitation when making intra-cluster calls. But I’m hoping that the Istio developers here can chime in re the plan (or the lack thereof) for fixing it.

Thanks again,
jaid