Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the "hosts" attribute in VirtualService and Gateway based on HTTP's Host header (layer 7)?

If I write Gateway and VirtualService entries like below, what criteria do the hosts attributes match to determine whether an incoming request should be routed to the service? Is it the "Host" header in the HTTP request, or something else?

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: default-gateway
  namespace: web
spec:
  selector:
    istio: ingressgateway
  servers:
  - hosts:
    - example.com
    port:
      name: www
      number: 80
      protocol: HTTP
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: web
  namespace: web
spec:
  gateways:
  - default-gateway
  hosts:
  - example.com
  http:
  - route:
    - destination:
        host: webserver # assume this is the name of the Service for our deployed container
---
# Assume a Service and Deployment exist for the above Service

Said another way - if we ignore DNS - what "Host" headers could be used to access the service/deployment via the cluster/load balancer IP?

like image 747
Johntron Avatar asked Nov 03 '20 00:11

Johntron


2 Answers

if you can access to the cluster using any dns, or cluster/load balancer IP, you can change the example.com DNS to *. or other method is put all DNSs like a list in the hosts block.

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: default-gateway
  namespace: web
spec:
  selector:
    istio: ingressgateway
  servers:
  - hosts:
    - '*'
    port:
      name: www
      number: 80
      protocol: HTTP
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: web
  namespace: web
spec:
  gateways:
  - default-gateway
  hosts:
  - '*'
  http:
  - route:
    - destination:
        host: webserver # assume this is the name of the Service for our deployed container
---
# Assume a Service and Deployment exist for the above Service

In the case that you deploy multiple services with only one external DNS, you need to match using uri block, for example in your virtual service you can put:

apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: web
      namespace: web
    spec:
      gateways:
      - default-gateway
      hosts:
      - '*'
      http:
      - match:
        - uri:
            prefix: /test/service1
        rewrite:
         uri: / 
      - route:
        - destination:
            host: webserver # assume this is the name of the Service for our deployed container

In the example above you can access from any host header, but the criterio to match to diferentes services are the the uri block in the http match

I hope it works for you. :)

like image 88
jitapichab Avatar answered Oct 21 '22 03:10

jitapichab


To answer your question

are you saying "hosts" is or is not based on the HTTP "Host" header?

Yes, it's based on the http host header.


According to istio documentation:

Access the httpbin service using curl:

$ curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST:$INGRESS_PORT/status/200"
HTTP/1.1 200 OK
server: istio-envoy
...

Note that you use the -H flag to set the Host HTTP header to “httpbin.example.com”. This is needed because your ingress Gateway is configured to handle “httpbin.example.com”, but in your test environment you have no DNS binding for that host and are simply sending your request to the ingress IP.


I used bookinfo application for testing.

kubectl label namespace default istio-injection=enabled
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml

Change virtual service hosts from * to example.com.

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: bookinfo-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo
spec:
  hosts:
  - "example.com"
  gateways:
  - bookinfo-gateway
  http:
  - match:
    - uri:
        exact: /productpage
    - uri:
        prefix: /static
    - uri:
        exact: /login
    - uri:
        exact: /logout
    - uri:
        prefix: /api/v1/products
    route:
    - destination:
        host: productpage
        port:
          number: 9080

Tested it with postman, you can also use curl which is mentioned above.

Example with example.com host header -> status 200.

enter image description here

curl -v -HHost:example.com xx.xxx.xx.x/productpage
Host:example.com
HTTP/1.1 200 OK

Example with example2.com host header -> status 404.

enter image description here

curl -v -HHost:example2.com xx.xxx.xx.x/productpage
Host:example2.com
HTTP/1.1 404 Not Found
like image 21
Jakub Avatar answered Oct 21 '22 01:10

Jakub