Routing by hostname instead of wildcard

[I’m currently using istio 1.3.1]
I have what I would think is a really simple situation. I want to forward HTTP requests using a hostname, but it doesn’t work.

If I use a wildcard for host, it works. If I use the hostname I want to use, it does not. I get no errors, just no routing. I am just trying to connect to an instance of Grafana for testing purposes. Here are my gw & vs yamls:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: grafana-gw
spec:
  selector:
    istio: ingressgateway # use istio default ingress gateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "grafana.localdomain"
#    - "*"

---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: grafana-vs
spec:
  hosts:
  #- "*"
  - grafana.default.svc.cluster.local
# - "grafana.localdomain"
  gateways:
  - grafana-gw
  http:
  - match:
    - uri:
        prefix: /
    route:
    - destination:
        port:
          number: 8080
        host: grafana-svc

As configured above, this does not work. If I change the two host specs to “*” it does, but now of course all HTTP requests are going to this service regardless of host, which I do not want.

What am I missing here? Oh, second question - sometimes in examples I see the URL hostname (grafana.localdomain) and sometimes it’s the service name within the cluster. Are both forms always usable? Is it one or the other? I haven’t been able to find any docs on the specifics of the host parameter.

Replying to myself as an update:
I’ve discovered the problem, or at least I think I have, but I’m not certain what the answer is.

The istio gateway is listening on ports 31380 for http and 31390 for https. When I use curl to access my gateway like this, it works:

$ curl -I -H "Host: grafana.localdomain" http://grafana.localdomain:31380/login
HTTP/1.1 200 OK
content-type: text/html; charset=UTF-8
date: Wed, 23 Oct 2019 09:02:24 GMT
x-envoy-upstream-service-time: 3
server: istio-envoy
transfer-encoding: chunked

But if I curl it directly, it does not work:

$ curl -I http://grafana.localdomain:31380/login
HTTP/1.1 404 Not Found
date: Wed, 23 Oct 2019 09:02:37 GMT
server: istio-envoy
transfer-encoding: chunked

The difference being the Host header when curled directly includes the port, which seems to be throwing it off.

Is there something I’m missing here, or is it simply impossible to do vs/gw forwarding with http hosts specifically named? Do we have to use wildcards?

Oh and to throw one more wrench in the works, I have another application I am exposing as a passthrough HTTPS app, and that works, even though the host is “whatever.localdomain” but when I hit it with a browser I go to “https://whatever.localdomain:31390” - why does including the port seem to break http but works with https?

Colin,
The http setup with host appears correct and your curl’s prove it.
You have to send the host to get the host paramater to work.
The browser will do this when you surf to it and its the same as -H “Host…” when you curl.
That shows a 200 OK response and your browser surf should work as well.

If you are using a wildcard elsewhere or have conflicting gw or vs that could be the issue when you are configured without the port.

But that’s just it - I don’t WANT to send the host, because I WANT to be able to test my pages/sites/apps with a browser, which obviously doesn’t work if you have to inject the host header.

The gateway is able to forward HTTPS/TLS connections (at least passthroughs) that are specified without the port but do include the port as part of the URL. If it can work with TLS, why can’t it work with plain HTTP?

Using a wildcard means you can only test one site/app/whatever per cluster, which is an absurd waste of resources.