Virtual Service's host doesn't resolve with HTTP

Using the bookinfo example on OpenShift 4.6.
When I create a virtual service with a host that’s not the same name as the K8s service the hostname cannot be resolved.

Have I made a basic error of some kind ?

For example:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: productpage
spec:
  hosts:
  - productpage
  - productpages
  http:
  - route:
    - destination:
        host: productpage
        subset: v1

From another pod that’s part of the mesh:

$ curl -sv http://productpage:9080
*   Trying 172.30.149.238:9080...
* Connected to productpage (172.30.149.238) port 9080 (#0)
...
$ curl -sv http://productpages:9080
* Could not resolve host: productpages
* Closing connection 0

So what happens is when you run curl http://productpage:9080, assuming you’re running it inside de pod/vm in the mesh, it gets expanded to productpage.namespace.svc.cluster.local (cluster.local is the default service address, my be different in your case). The same happens for productpages, but this time there’s no productpages.namespace.svc.cluster.local address since from what you mentioned, that address is not defined.

As far as I understand, your hosts entry needs to be DNS resolvable.

Hope this helps!

When I create a virtual service with a host that’s not the same name as the K8s service the hostname cannot be resolved.

Just to be sure I understood your question: you have a service, let’s name it productpages, in your cluster. The you create a virtualservice that matches the host productpage and you would like to be able to call http://productpage and be re-routed to productpages, right?

If this is the case, note that Istio does not act as a DNS service. Your application (or curl) will resolve productpage and establish a connection with the resulting IP address. Istio just intercepts that connection and check the HTTP Host header to see if there is any VirtualService with a host that matches it. But if your are not able to establish a TCP connection in first place, Istio will never get the opportunity to apply this VirtualService.

In Kubernetes, there is a registry with all Service names and respective IP addresses, which are used for DNS resolution. The service, then, act as a load balancer to your PODS. For being able to call your service implementation (POD) with a another name, you can create a Service in kubernetes that matches your POD labels with that name. Then, you’ll have 2 services that targets the sames POD and you’ll be able to use the virtuaservice you provided to apply additional routing rules.

Hope this helps!

Thanks !

The bit I hadn’t realised was that creating an ISTIO VirtualService does not create an entry in the Kubernetes DNS. Given it doesn’t my problem makes complete sense to me now.