Configure an Egress Gateway 案例演示了如何通过istio edge 组件的Egress Gateway导向流量到外部的服务。 然而,一些案例请求一个外部的,传统的HTTPS代理到外部的服务进行访问。 比如,你公司可能有一个代理,公司所有到外部的请求都要经过它。

本案例演示了如何开启访问到外部的HTTPS proxy. 由于应用使用HTTP 连接方法到HTTPS 代理建立连接,配置流量到外部的HTTPS proxy到到外部HTTP和HTTPS服务是不同的。

1. 准备工作

  1. 部署sleep应用,如果开启了自动sidecar注入。运行以下命令
  1. $ kubectl apply -f samples/sleep/sleep.yaml
  • 手工注入执行以下命令
  1. $ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml)
  1. 设置SOURCE_POD变量获取你source pod的名称
  1. $ export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
  1. 开启Envoy的访问日志
  1. $ istioctl manifest apply --set profile=demo --set meshConfig.accessLogFile="/dev/stdout"

2. 部署HTTPS 代理

使用squid去模拟传统的代理

  1. 针对HTTPS代理创建名称空间, 不要针对它开启sidecar 注入。
  1. $ kubectl create namespace external
  1. 创建针对Squid proxy的配置文件
  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
  1. 创建一个拥有proxy配置的ConfigMap
  1. $ kubectl create configmap proxy-configmap -n external --from-file=squid.conf=./proxy.conf
  1. 部署含有Squid的容器
  1. $ kubectl apply -f - <<EOF
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. name: squid
  6. namespace: external
  7. spec:
  8. selector:
  9. matchLabels:
  10. app: squid
  11. replicas: 1
  12. template:
  13. metadata:
  14. labels:
  15. app: squid
  16. spec:
  17. volumes:
  18. - name: proxy-config
  19. configMap:
  20. name: proxy-configmap
  21. containers:
  22. - name: squid
  23. image: sameersbn/squid:3.5.27
  24. imagePullPolicy: IfNotPresent
  25. volumeMounts:
  26. - name: proxy-config
  27. mountPath: /etc/squid
  28. readOnly: true
  29. EOF
  1. 在external的名称空间中部署sleep的应用到代理间的流量(没有Istio traffic的控制)
  1. $ kubectl apply -n external -f samples/sleep/sleep.yaml
  1. 获得proxy pod的IP地址,并把它存储到PROXY_IP的变量中。
  1. $ export PROXY_IP=$(kubectl get pod -n external -l app=squid -o jsonpath={.items..podIP})
  1. 获得proxy pod的端口,并把它存储到PROXY_PORT变量中。
  1. $ export PROXY_PORT=3128
  1. 在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>"
  1. 检查代理的访问日志
  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

[info]到目前为上,没有istio的情况下完成了以下任务:

  • 部署HTTPS proxy.
  • 使用curl通过代理访问外部的wikipedia的服务

3. 配置流量到外部的HTTPS proxy

  1. 针对HTTPS proxy定义TCP的服务条目。 尽管应用使用HTTP 连接方法去和HTTPS proxy建立连接。 你必须配置针对TCP流量的代理,代替HTTP。 一旦连接建立, 这个代理简单的扮演着TCP tunnel.
  1. $ kubectl apply -f - <<EOF
  2. apiVersion: networking.istio.io/v1alpha3
  3. kind: ServiceEntry
  4. metadata:
  5. name: proxy
  6. spec:
  7. hosts:
  8. - my-company-proxy.com # ignored
  9. addresses:
  10. - $PROXY_IP/32
  11. ports:
  12. - number: $PROXY_PORT
  13. name: tcp
  14. protocol: TCP
  15. location: MESH_EXTERNAL
  16. EOF
  1. 从默认的名称空间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>"
  1. 针对你的请求,检查Istio sidecar 代理的日志
  1. $ kubectl logs $SOURCE_POD -c istio-proxy
  1. 检查你请求的代理访问日志
  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

4. 清空本实验

  1. 关闭sleep服务
  1. $ kubectl delete -f samples/sleep/sleep.yaml
  1. 关闭在external名称空间中的sleep服务
  1. $ kubectl delete -f samples/sleep/sleep.yaml -n external
  1. 关闭squid proxy, 移除ConfigMap和配置文件
  1. $ kubectl delete -n external deployment squid
  2. $ kubectl delete -n external configmap proxy-configmap
  3. $ rm ./proxy.conf
  1. 删除external的名称空间
  1. $ kubectl delete namespace external
  1. 删除服务条目
  1. $ kubectl delete serviceentry proxy