VirtualService 和 Gateway 中的 "hosts" 属性是否基于 HTTP 的 Host header(第 7 层)?

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

如果我像下面这样编写 Gateway 和 VirtualService 条目,主机属性匹配什么条件来确定是否应将传入请求路由到服务?它是 HTTP 请求中的“主机”header,还是其他?

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

换句话说 - 如果我们忽略 DNS - 什么“主机”header 可用于通过 cluster/load 平衡器 IP 访问 service/deployment?

如果您可以使用任何 dns 或 cluster/load 平衡器 IP 访问集群,您可以将 example.com DNS 更改为 *。或其他方法将所有 DNS 像列表一样放在 hosts 块中。

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

如果你部署多个服务只有一个外部DNS,你需要使用uri块来匹配,例如在你的虚拟服务中你可以放:

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

在上面的示例中,您可以从任何主机访问 header,但是要匹配不同服务的条件是 http 匹配中的 uri 块

希望对你有用。 :)

回答你的问题

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

是的,它基于 http 主机 header。


根据 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.


我用了bookinfo application来测试。

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

将虚拟服务 hosts* 更改为 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

postman测试过,你也可以用上面提到的curl

示例 example.com 主机 header -> 状态 200。

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

示例 example2.com 主机 header -> 状态 404。

curl -v -HHost:example2.com xx.xxx.xx.x/productpage
Host:example2.com
HTTP/1.1 404 Not Found