Istio 作为外部服务的代理

配置 Istio 入口网关充当外部服务的代理。

2019 年 10 月 15 日 | 作者:Vadim Eisenberg - IBM

The 控制入口流量无 TLS 终止的入口网关 任务描述了如何配置入口网关以将网格内的服务暴露给外部流量。这些服务可以是 HTTP 或 HTTPS。在 HTTPS 的情况下,网关会将流量传递,而不会终止 TLS。

这篇博文描述了如何使用 Istio 的相同入口网关机制来启用对外部服务的访问,而不是对网格内的应用程序的访问。这样,Istio 作为一个整体就可以充当代理服务器,并提供可观察性、流量管理和策略实施的附加价值。

这篇博文展示了如何配置对 HTTP 和 HTTPS 外部服务的访问,即 httpbin.orgedition.cnn.com

配置入口网关

  1. 使用 servers: 部分定义入口网关,该部分配置了 80443 端口。确保 mode: 设置为 PASSTHROUGH,用于端口 443 中的 tls:,这指示网关按原样传递入口流量,而不会终止 TLS。

    $ kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
      name: proxy
    spec:
      selector:
        istio: ingressgateway # use istio default ingress gateway
      servers:
      - port:
          number: 80
          name: http
          protocol: HTTP
        hosts:
        - httpbin.org
      - port:
          number: 443
          name: tls
          protocol: TLS
        tls:
          mode: PASSTHROUGH
        hosts:
        - edition.cnn.com
    EOF
    
  2. httpbin.orgedition.cnn.com 服务创建服务条目,使其可从入口网关访问

    $ kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1alpha3
    kind: ServiceEntry
    metadata:
      name: httpbin-ext
    spec:
      hosts:
      - httpbin.org
      ports:
      - number: 80
        name: http
        protocol: HTTP
      resolution: DNS
      location: MESH_EXTERNAL
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: ServiceEntry
    metadata:
      name: cnn
    spec:
      hosts:
      - edition.cnn.com
      ports:
      - number: 443
        name: tls
        protocol: TLS
      resolution: DNS
      location: MESH_EXTERNAL
    EOF
    
  3. localhost 服务创建一个服务条目并配置一个目标规则。您需要在下一步中使用此服务条目作为网格内应用程序对外部服务的流量的目的地,以阻止来自网格内的流量。在本例中,您使用 Istio 作为外部应用程序和外部服务之间的代理。

    $ kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1alpha3
    kind: ServiceEntry
    metadata:
      name: localhost
    spec:
      hosts:
      - localhost.local
      location: MESH_EXTERNAL
      ports:
      - number: 80
        name: http
        protocol: HTTP
      - number: 443
        name: tls
        protocol: TLS
      resolution: STATIC
      endpoints:
      - address: 127.0.0.1
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: localhost
    spec:
      host: localhost.local
      trafficPolicy:
        tls:
          mode: DISABLE
          sni: localhost.local
    EOF
    
  4. 为每个外部服务创建一个虚拟服务,以配置路由到它。两个虚拟服务都包含 gateways: 部分中的 proxy 网关,以及 HTTP 和 HTTPS 流量相应的 match: 部分。

    注意 mesh 网关的 route: 部分,该网关代表网格内的应用程序。mesh 网关的 route: 显示了流量如何被定向到 localhost.local 服务,从而有效地阻止了流量。

    $ kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: httpbin
    spec:
      hosts:
      - httpbin.org
      gateways:
      - proxy
      - mesh
      http:
      - match:
        - gateways:
          - proxy
          port: 80
          uri:
            prefix: /status
        route:
        - destination:
            host: httpbin.org
            port:
              number: 80
      - match:
        - gateways:
          - mesh
          port: 80
        route:
        - destination:
            host: localhost.local
            port:
              number: 80
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: cnn
    spec:
      hosts:
      - edition.cnn.com
      gateways:
      - proxy
      - mesh
      tls:
      - match:
        - gateways:
          - proxy
          port: 443
          sni_hosts:
          - edition.cnn.com
        route:
        - destination:
            host: edition.cnn.com
            port:
              number: 443
      - match:
        - gateways:
          - mesh
          port: 443
          sni_hosts:
          - edition.cnn.com
        route:
        - destination:
            host: localhost.local
            port:
              number: 443
    EOF
    
  5. 启用 Envoy 的访问日志记录.

  6. 按照 确定入口 IP 和端口 中的说明定义 SECURE_INGRESS_PORTINGRESS_HOST 环境变量。

  7. 通过您的入口 IP 和端口访问 httpbin.org 服务,您分别在前面的步骤中将这些 IP 和端口存储在 $INGRESS_HOST$INGRESS_PORT 环境变量中。访问 httpbin.org 服务的 /status/418 路径,该路径返回 HTTP 状态 418 我是一个茶壶

    $ curl $INGRESS_HOST:$INGRESS_PORT/status/418 -Hhost:httpbin.org
    
    -=[ teapot ]=-
    
       _...._
     .'  _ _ `.
    | ."` ^ `". _,
    \_;`"---"`|//
      |       ;/
      \_     _/
        `"""`
    
  8. 如果 Istio 入口网关部署在 istio-system 命名空间中,请使用以下命令打印网关的日志

    $ kubectl logs -l istio=ingressgateway -c istio-proxy -n istio-system | grep 'httpbin.org'
    
  9. 在日志中搜索类似于以下内容的条目

    [2019-01-31T14:40:18.645Z] "GET /status/418 HTTP/1.1" 418 - 0 135 187 186 "10.127.220.75" "curl/7.54.0" "28255618-6ca5-9d91-9634-c562694a3625" "httpbin.org" "34.232.181.106:80" outbound|80||httpbin.org - 172.30.230.33:80 10.127.220.75:52077 -
    
  10. 通过您的入口网关访问 edition.cnn.com 服务

    $ curl -s --resolve edition.cnn.com:$SECURE_INGRESS_PORT:$INGRESS_HOST https://edition.cnn.com:$SECURE_INGRESS_PORT | grep -o "<title>.*</title>"
    <title>CNN International - Breaking News, US News, World News and Video</title>
    
  11. 如果 Istio 入口网关部署在 istio-system 命名空间中,请使用以下命令打印网关的日志

    $ kubectl logs -l istio=ingressgateway -c istio-proxy -n istio-system | grep 'edition.cnn.com'
    
  12. 在日志中搜索类似于以下内容的条目

    [2019-01-31T13:40:11.076Z] "- - -" 0 - 589 17798 1644 - "-" "-" "-" "-" "172.217.31.132:443" outbound|443||edition.cnn.com 172.30.230.33:54508 172.30.230.33:443 10.127.220.75:49467 edition.cnn.com
    

清理

删除网关、虚拟服务和服务条目

$ kubectl delete gateway proxy
$ kubectl delete virtualservice cnn httpbin
$ kubectl delete serviceentry cnn httpbin-ext localhost
$ kubectl delete destinationrule localhost
分享此帖子