使用外部 HTTPS 代理
「設定出口閘道」範例示範如何透過名為「出口閘道」的 Istio 邊緣元件將流量從網格導向外部服務。然而,在某些情況下,需要外部、舊有 (非 Istio) HTTPS 代理才能存取外部服務。例如,您的公司可能已經有這樣一個代理,並且組織內的所有應用程式可能都需要將其流量導向該代理。
這個範例展示如何啟用對外部 HTTPS 代理的存取。由於應用程式使用 HTTP CONNECT 方法來建立與 HTTPS 代理的連線,因此設定導向外部 HTTPS 代理的流量與設定導向外部 HTTP 和 HTTPS 服務的流量不同。
開始之前
請按照安裝指南中的說明設定 Istio。
部署 curl 範例應用程式,作為傳送請求的測試來源。如果您已啟用自動 Sidecar 注入,請執行以下命令來部署範例應用程式
$ kubectl apply -f @samples/curl/curl.yaml@
否則,請在部署
curl
應用程式之前,使用以下命令手動注入 Sidecar$ kubectl apply -f <(istioctl kube-inject -f @samples/curl/curl.yaml@)
將
SOURCE_POD
環境變數設定為您的來源 Pod 的名稱$ export SOURCE_POD=$(kubectl get pod -l app=curl -o jsonpath={.items..metadata.name})
部署 HTTPS 代理
為了模擬舊式代理,並且僅限於此範例,您會在叢集內部部署一個 HTTPS 代理。此外,為了模擬在叢集外部執行的更真實的代理,您將使用代理 Pod 的 IP 位址,而不是 Kubernetes 服務的網域名稱來存取代理 Pod。此範例使用 Squid,但您可以使用任何支援 HTTP CONNECT 的 HTTPS 代理。
為 HTTPS 代理建立一個命名空間,而不要標記它以進行 Sidecar 注入。沒有標籤,Sidecar 注入在新命名空間中會被停用,因此 Istio 將不會控制該處的流量。您需要此行為來模擬代理位於叢集外部的情況。
$ kubectl create namespace external
為 Squid 代理建立一個設定檔。
$ cat <<EOF > ./proxy.conf http_port 3128 acl SSL_ports port 443 acl CONNECT method CONNECT http_access deny CONNECT !SSL_ports http_access allow localhost manager http_access deny manager http_access allow all coredump_dir /var/spool/squid EOF
建立一個 Kubernetes ConfigMap 來保存代理的設定
$ kubectl create configmap proxy-configmap -n external --from-file=squid.conf=./proxy.conf
部署一個包含 Squid 的容器
$ kubectl apply -f - <<EOF apiVersion: apps/v1 kind: Deployment metadata: name: squid namespace: external spec: replicas: 1 selector: matchLabels: app: squid template: metadata: labels: app: squid spec: volumes: - name: proxy-config configMap: name: proxy-configmap containers: - name: squid image: sameersbn/squid:3.5.27 imagePullPolicy: IfNotPresent volumeMounts: - name: proxy-config mountPath: /etc/squid readOnly: true EOF
在
external
命名空間中部署 curl 範例,以測試在沒有 Istio 流量控制的情況下,導向代理的流量。$ kubectl apply -n external -f @samples/curl/curl.yaml@
取得代理 Pod 的 IP 位址,並定義
PROXY_IP
環境變數來儲存它$ export PROXY_IP="$(kubectl get pod -n external -l app=squid -o jsonpath={.items..podIP})"
定義
PROXY_PORT
環境變數以儲存您的代理的埠。在此範例中,Squid 使用埠 3128。$ export PROXY_PORT=3128
從
external
命名空間中的curl
Pod 透過代理向外部服務傳送請求$ kubectl exec "$(kubectl get pod -n external -l app=curl -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>" <title>Wikipedia, the free encyclopedia</title>
檢查代理的存取記錄,查看您的請求
$ kubectl exec "$(kubectl get pod -n external -l app=squid -o jsonpath={.items..metadata.name})" -n external -- tail /var/log/squid/access.log 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 代理。
設定流量到外部 HTTPS 代理
為 HTTPS 代理定義一個 TCP(而不是 HTTP!)服務條目。儘管應用程式使用 HTTP CONNECT 方法來建立與 HTTPS 代理的連線,但您必須為 TCP 流量設定代理,而不是 HTTP。連線建立後,代理僅充當 TCP 通道。
$ kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1 kind: ServiceEntry metadata: name: proxy spec: hosts: - my-company-proxy.com # ignored addresses: - $PROXY_IP/32 ports: - number: $PROXY_PORT name: tcp protocol: TCP location: MESH_EXTERNAL resolution: NONE EOF
從
default
命名空間中的curl
Pod 發送請求。由於curl
Pod 有一個 Sidecar,因此 Istio 控制其流量。$ kubectl exec "$SOURCE_POD" -c curl -- sh -c "HTTPS_PROXY=$PROXY_IP:$PROXY_PORT curl https://en.wikipedia.org/wiki/Main_Page" | grep -o "<title>.*</title>" <title>Wikipedia, the free encyclopedia</title>
檢查 Istio Sidecar 代理的日誌,查看您的請求
$ kubectl logs "$SOURCE_POD" -c istio-proxy [2018-12-07T10:38:02.841Z] "- - -" 0 - 702 87599 92 - "-" "-" "-" "-" "172.30.109.95:3128" outbound|3128||my-company-proxy.com 172.30.230.52:44478 172.30.109.95:3128 172.30.230.52:44476 -
檢查代理的存取記錄,查看您的請求
$ kubectl exec "$(kubectl get pod -n external -l app=squid -o jsonpath={.items..metadata.name})" -n external -- tail /var/log/squid/access.log 1544160065.248 228 172.30.109.89 TCP_TUNNEL/200 87633 CONNECT en.wikipedia.org:443 - HIER_DIRECT/91.198.174.192 -
了解發生了什麼
在此範例中,您執行了以下步驟
- 部署了一個 HTTPS 代理來模擬外部代理。
- 建立一個 TCP 服務條目,以啟用由 Istio 控制的導向外部代理的流量。
請注意,您不必為透過外部代理存取的外部服務(例如 wikipedia.org
)建立服務條目。這是因為從 Istio 的角度來看,請求僅發送到外部代理;Istio 並不知道外部代理會將請求進一步轉發。
清理
關閉 curl 服務
$ kubectl delete -f @samples/curl/curl.yaml@
關閉
external
命名空間中的 curl 服務$ kubectl delete -f @samples/curl/curl.yaml@ -n external
關閉 Squid 代理,移除
ConfigMap
和設定檔$ kubectl delete -n external deployment squid $ kubectl delete -n external configmap proxy-configmap $ rm ./proxy.conf
刪除
external
命名空間$ kubectl delete namespace external
刪除服務條目
$ kubectl delete serviceentry proxy