tmp dev
tmp dev

Reputation: 9193

istio virtualservice vs gateway

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

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:
    - "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: istio-test
spec:
  hosts:
  - istio-service-test.default.svc.cluster.local
  # - "*"
  gateways:
  - istio-test-gateway
  http:
  - name: "pingpongservice"
    route:
    - destination:
        host: istio-service-test.default.svc.cluster.local

Under the VirtualService hosts 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

export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
export INGRESS_HOST=$(minikube ip)
export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT

Once I deploy this and try a curl with something like curl "http://${GATEWAY_URL}/ping I get nothing. Under the VirtualService hosts section if I uncomment * and comment out istio-service-test.default.svc.cluster.local 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 http://istio-service-test/ping

Upvotes: 0

Views: 1815

Answers (1)

David Maze
David Maze

Reputation: 158908

The VirtualService hosts: line needs to match the HTTP Host: header. HTTP clients will usually pass on the host name from the URL here, though you can override it sometimes

curl -H 'Host: istio-service-test.default.svc.cluster.local' \
  "http://${GATEWAY_URL}/ping"

If you're binding the VirtualService to an ingress Gateway, hosts: needs to match an external DNS name that routes to the cluster, or be *. You can use this if your cluster is running multiple applications for host-based routing.

If the VirtualService isn't specifically bound to a Gateway (or is explicitly bound to mesh) then hosts: 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.

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, hosts: [*] is probably the right setting.

Upvotes: 1

Related Questions