使用外部 HTTPS 代理

    此示例演示如何启用对外部 HTTPS 代理的访问。由于应用程序使用 HTTP CONNECT 方法与 HTTPS 代理建立连接,因此配置流量到外部 HTTPS 代理不同于将流量配置为外部 HTTP 和 HTTPS 服务。

    • 按照中的说明安装 Istio。

      如果您安装的安装配置,则将启用 Egress Gateway和访问日志。

    • 将 示例应用程序部署为发送请求的测试源。 如果您启用了自动 sidecar 注入,运行以下命令部署示例应用程序:

      否则,在使用以下命令部署 sleep 应用程序之前,手动注入 sidecar:

      Zip

      1. $ kubectl apply -f <(istioctl kube-inject -f @samples/sleep/sleep.yaml@)

      您可以使用任何安装了 curl 的 pod 作为测试源。

    • 为了发送请求,您需要创建 SOURCE_POD 环境变量来存储源 pod 的名称:

      1. $ export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})

    本例中为了模拟传统代理,在集群内部署了一个 HTTPS 代理。此外,为了模拟在集群外运行的更真实的代理,通过代理的 IP 地址而不是 Kubernetes 服务的域名来寻址代理的 pod。本例使用的是 squid,但是您可以使用任何支持 HTTP CONNECT 连接的 HTTPS 代理。

      1. $ kubectl create namespace external
    1. 为 Squid 代理创建配置文件。

      1. $ cat <<EOF > ./proxy.conf
      2. http_port 3128
      3. acl SSL_ports port 443
      4. acl CONNECT method CONNECT
      5. http_access deny CONNECT !SSL_ports
      6. http_access allow localhost manager
      7. http_access deny manager
      8. http_access allow all
      9. coredump_dir /var/spool/squid
      10. EOF
    2. 创建 Kubernetes 以保存代理的配置:

      1. $ kubectl create configmap proxy-configmap -n external --from-file=squid.conf=./proxy.conf
    3. 使用 Squid 部署容器:

      1. $ kubectl apply -f - <<EOF
      2. apiVersion: apps/v1
      3. kind: Deployment
      4. metadata:
      5. name: squid
      6. namespace: external
      7. replicas: 1
      8. selector:
      9. app: squid
      10. template:
      11. metadata:
      12. labels:
      13. app: squid
      14. spec:
      15. volumes:
      16. - name: proxy-config
      17. configMap:
      18. name: proxy-configmap
      19. containers:
      20. - name: squid
      21. image: sameersbn/squid:3.5.27
      22. imagePullPolicy: IfNotPresent
      23. volumeMounts:
      24. - name: proxy-config
      25. mountPath: /etc/squid
      26. readOnly: true
      27. EOF
    4. external 命名空间中部署 sleep 示例,以测试到代理的通信量,而不进行 Istio 流量控制。

    5. 获取代理 pod 的 IP 地址并定义 PROXY_IP 环境变量来存储它:

      1. $ export PROXY_IP=$(kubectl get pod -n external -l app=squid -o jsonpath={.items..podIP})
    6. 定义 PROXY_PORT 环境变量以存储代理的端口。本例子中 Squid 使用 3128 端口。

      1. $ export PROXY_PORT=3128
    7. external 命名空间中的 sleep pod 通过代理向外部服务发送请求:

      1. $ kubectl exec -it $(kubectl get pod -n external -l app=sleep -o jsonpath={.items..metadata.name}) -n external -- sh -c "HTTPS_PROXY=$PROXY_IP:$PROXY_PORT curl https://en.wikipedia.org/wiki/Main_Page" | grep -o "<title>.*</title>"
      2. <title>Wikipedia, the free encyclopedia</title>
    8. 检查您请求的代理的访问日志:

      1. $ kubectl exec -it $(kubectl get pod -n external -l app=squid -o jsonpath={.items..metadata.name}) -n external -- tail -f /var/log/squid/access.log
      2. 1544160065.248 228 172.30.109.89 TCP_TUNNEL/200 87633 CONNECT en.wikipedia.org:443 - HIER_DIRECT/91.198.174.192 -

    现在,您在没有 Istio 的情况下完成了以下任务:

    • 您部署了 HTTPS 代理。
    • 您使用 curl 通过代理访问 wikipedia.org 外部服务。

    下一步,您必须配置 Istio 启用的 pod 的流量到 HTTPS 代理。

      1. apiVersion: networking.istio.io/v1alpha3
      2. kind: ServiceEntry
      3. metadata:
      4. name: proxy
      5. spec:
      6. hosts:
      7. - my-company-proxy.com # ignored
      8. addresses:
      9. - $PROXY_IP/32
      10. ports:
      11. - number: $PROXY_PORT
      12. name: tcp
      13. protocol: TCP
      14. location: MESH_EXTERNAL
      15. EOF
    1. external 命名空间中的 sleep pod 发送请求。因为 sleep pod 有 Sidecar,可以让 Istio 控制其流量。

      1. $ kubectl exec -it $SOURCE_POD -c sleep -- sh -c "HTTPS_PROXY=$PROXY_IP:$PROXY_PORT curl https://en.wikipedia.org/wiki/Main_Page" | grep -o "<title>.*</title>"
      2. <title>Wikipedia, the free encyclopedia</title>
    2. 查看您的请求的 Istio SideCar 代理的日志:

    3. 查看您请求的代理的访问日志:

      1. $ kubectl exec -it $(kubectl get pod -n external -l app=squid -o jsonpath={.items..metadata.name}) -n external -- tail -f /var/log/squid/access.log
      2. 1544160065.248 228 172.30.109.89 TCP_TUNNEL/200 87633 CONNECT en.wikipedia.org:443 - HIER_DIRECT/91.198.174.192 -

    在本例中,您采取了以下步骤:

    1. 部署了一个 HTTPS 代理来模拟外部代理。
    2. 创建了一个 TCP 服务入口,用作引导 Istio 控制的流量 到外部代理。

    请注意,您不能为通过外部代理访问的外部服务创建服务入口,例如 wikipedia.org。这是因为从 Istio 的角度来看,请求只发送到外部代理;Istio 并不知道外部代理会进一步转发请求。

    1. 关闭 sleep 服务:

      1. $ kubectl delete -f @samples/sleep/sleep.yaml@
    2. 关闭 external 命名空间中的 sleep 服务:

      1. $ kubectl delete -f @samples/sleep/sleep.yaml@ -n external
    3. 关闭 Squid 代理,删除 ConfigMap 和配置文件:

      1. $ kubectl delete -n external deployment squid
      2. $ kubectl delete -n external configmap proxy-configmap
      3. $ rm ./proxy.conf
    4. 删除 external 命名空间:

      1. $ kubectl delete namespace external
      1. $ kubectl delete serviceentry proxy