<p>I'm trying to wrap my head around a virtual service works in istio.  I am running istio on minikube and have the following yamls</p>
<pre><code>apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: istio-test-gateway
spec:
  selector:
    istio: ingressgateway  
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - &quot;*&quot;
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: istio-test
spec:
  hosts:
  - istio-service-test.default.svc.cluster.local
  # - &quot;*&quot;
  gateways:
  - istio-test-gateway
  http:
  - name: &quot;pingpongservice&quot;
    route:
    - destination:
        host: istio-service-test.default.svc.cluster.local
</code></pre>
<p>Under the <code>VirtualService</code> <code>hosts</code> section I have defined an actual host and I'm trying to figure out how this works.  On minikube I run the following to get the urls</p>
<pre><code>export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name==&quot;http2&quot;)].nodePort}')
export INGRESS_HOST=$(minikube ip)
export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
</code></pre>
<p>Once I deploy this and try a curl with something like <code>curl &quot;http://${GATEWAY_URL}/ping</code> I get nothing.  Under the <code>VirtualService</code> <code>hosts</code> section if I uncomment <code>*</code> and comment out <code>istio-service-test.default.svc.cluster.local</code> then it works, I successfully get the response from the server.  I am not sure what is going on here.  Ideally what I'm trying to do is to access the service using something like <code>http://istio-service-test/ping</code></p>

tmp dev
<p>The VirtualService <code>hosts:</code> line needs to match the HTTP <code>Host:</code> header.  HTTP clients will usually pass on the host name from the URL here, though you can override it sometimes</p>
<pre class="lang-sh prettyprint-override"><code>curl -H 'Host: istio-service-test.default.svc.cluster.local' \
  &quot;http://${GATEWAY_URL}/ping&quot;
</code></pre>
<p>If you're binding the VirtualService to an ingress Gateway, <code>hosts:</code> needs to match an <em>external</em> DNS name that routes to the cluster, or be <code>*</code>.  You can use this if your cluster is running multiple applications for host-based routing.</p>
<p>If the VirtualService isn't specifically bound to a Gateway (or is explicitly bound to <code>mesh</code>) then <code>hosts:</code> needs to match a Kubernetes-internal DNS name for a Service, and it provides ingress-type routing functionality around that in-cluster Service.  This would allow you to do path-based or header-based routing for what's otherwise a ClusterIP-type Service, without having to run your own intermediate reverse proxy.</p>
<p>For your use, where you're binding the VirtualService to an ingress Gateway, you're only running one application in the cluster, and the minikube installation doesn't have a persistent DNS name, <code>hosts: [*]</code> is probably the right setting.</p>
