We’re using Istio 1.6.14. I have a microservice that is used for both internal (in-cluster) and external (via an Istio ingress gateway) calls. Let’s say the microservice exposes /operation
so if you call http://mysvc.myns.svc.cluster.local/operation
you’ll get a response.
When accessed from the outside, I need to do some rewriting. It comes in with an extra prefix, like http://api.mydomain.com/api/operation
so the path /api/operation
needs to be rewritten. Internal calls don’t require this rewrite.
I am trying to do canary deployments and allow for VirtualService
routing across three different deployments - a stable
version (the current); a baseline
version (a “control group” version of the stable for statistics comparison); and a canary
version (the new version). I want to be able to change the traffic routing percentages in one place and have it work for both internal and external communications.
I though a VirtualService
delegate
would be the right way to go, so I created this:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: load-balancer
namespace: myns
spec:
http:
- route:
- destination:
host: mysvc-stable
weight: 50
- destination:
host: mysvc-baseline
weight: 25
- destination:
host: mysvc-canary
weight: 25
I then set up my external traffic routing VirtualService
pointing at my gateway. Note the hosts
is the IP address of the inbound request because we’re going through an Apigee mTLS connection so the DNS resolves to Apigee, not to the Istio ingress. But this works just fine.
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: external-traffic
namespace: myns
spec:
gateways:
- istio-system/apigee-mtls
hosts:
- 1.2.3.4
http:
- delegate:
name: load-balancer
namespace: myns
match:
- uri:
prefix: /api/operation
rewrite:
uri: /operation
With just these two VirtualService
in place, I can access my service from the outside and the traffic routing works perfectly. So far, so good.
The problem is that if I access internal to the cluster then I’m not getting traffic routing yet. I need a VirtualService
for the inside, too. But that’s where things fall down. I tried putting this:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: internal-traffic
namespace: myns
spec:
gateways:
- mesh
hosts:
- mysvc
http:
- delegate:
name: load-balancer
namespace: myns
But I got the error Error from server: error when creating "vs.yaml": admission webhook "validation.istio.io" denied the request: configuration is invalid: http delegate only applies to gateway
I did find this issue in the Istio repo where some folks talked about the same error but I wasn’t sure if this is the same situation or something else.
I then tried to change the delegate to have the internal routing…
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: load-balancer
namespace: myns
spec:
gateways:
- mesh
hosts:
- mysvc
http:
- route:
- destination:
host: mysvc-stable
weight: 50
- destination:
host: mysvc-baseline
weight: 25
- destination:
host: mysvc-canary
weight: 25
…but as soon as that gets deployed, internal traffic gets routed right but external traffic no longer comes through at all. I get 404 Not Found.
I can’t delegate something on the mesh
gateway, but I also can’t delegate something from an ingress gateway to a VirtualService
with a named host.
Am I missing something?