According to the Istio documentation, VirtualServices should be able to route requests to "a completely different service than was requested". I would like to use this feature give services different aliases in different applications.
I'm starting with a VirtualService definition like this:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-vs
spec:
hosts:
- my-alias
http:
- route:
- destination:
host: my-service
The intention is that a client pod in the mesh should be able to send requests to http://my-alias and have them routed to my-service. In the future I'll expand this with match rules to make the alias behave differently for different clients, but even the simple version isn't working.
With no other setup, the client fails to resolve my-alias via DNS. I can solve this by adding a selectorless k8s service named my-alias so its DNS resolves, but then the VirtualService doesn't seem to do the redirect. If I add an external host like google.com to the VirtualService, then it does successfully redirect any requests to google.com over to my-service. Using the full hostname (my-alias.default.svc.cluster.local) doesn't help.
So it seems like the VirtualService is not allowing me to redirect traffic bound for another service in the mesh. Is this expected, and is there a way I can work around it?
You have to rewrite authority
(the HOST header) of your request, since the HTTP routing in Istio is performed by the HOST header.
Add an HTTPRewrite clause to the http
clause:
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: my-vs spec: hosts: - my-alias http: - route: - destination: host: my-service rewrite: authority: my-service
The problem ended up being that I was using unnamed ports for my services, so traffic never made it into the mesh. According to https://istio.io/docs/setup/kubernetes/spec-requirements/, the HTTP port must be named http
.