mirror of https://github.com/istio/istio.io.git
An example of configuring access to an external legacy HTTPS proxy (#2960)
* initial version * ServiceEntry -> service entry (in text) * config map -> `ConfigMap` * fix a link * task -> example * through such proxy -> through it * elaborate what has been done after the proxy is deployed and tested * split a long line * explain why there is no need to define service entries for external services accessed through the proxy * rewrite the sentence about simulating the proxy outside the cluster * check the log and see your request -> check the log for your request * HTTP CONNECT method -> the HTTP CONNECT method * between the application and the proxies -> between the application and the proxy * add explanation how this example is different from other egress examples
This commit is contained in:
parent
b1a0c38a49
commit
79cd5ced44
|
@ -0,0 +1,244 @@
|
||||||
|
---
|
||||||
|
title: Connect to an external HTTPS proxy
|
||||||
|
description: Describes how to configure Istio to let applications use an external HTTPS proxy.
|
||||||
|
weight: 60
|
||||||
|
keywords: [traffic-management,egress]
|
||||||
|
---
|
||||||
|
The [Configure an Egress Gateway](/docs/examples/advanced-gateways/egress-gateway/) showed how you can direct traffic to
|
||||||
|
external services from your mesh via an Istio edge component called _Egress Gateway_. However, there are cases when you
|
||||||
|
must use an external, legacy (non-Istio) HTTPS proxy to access external services. For example, your company may already
|
||||||
|
have such a proxy in place and all the applications within the organization may be required to direct their traffic
|
||||||
|
through it.
|
||||||
|
|
||||||
|
This example shows how to enable access to an external HTTPS proxy. Since access to HTTPS proxies is performed by the
|
||||||
|
HTTP [CONNECT](https://tools.ietf.org/html/rfc7231#section-4.3.6) method, configuring traffic to an external HTTPS
|
||||||
|
proxy is different from configuring traffic to external HTTP and HTTPS services.
|
||||||
|
|
||||||
|
## Before you begin
|
||||||
|
|
||||||
|
* Setup Istio by following the instructions in the [Installation guide](/docs/setup/).
|
||||||
|
|
||||||
|
* Start the [sleep]({{< github_tree >}}/samples/sleep) sample
|
||||||
|
which will be used as a test source for external calls via the proxy.
|
||||||
|
|
||||||
|
If you have enabled
|
||||||
|
[automatic sidecar injection](/docs/setup/kubernetes/sidecar-injection/#automatic-sidecar-injection), do
|
||||||
|
|
||||||
|
{{< text bash >}}
|
||||||
|
$ kubectl apply -f @samples/sleep/sleep.yaml@
|
||||||
|
{{< /text >}}
|
||||||
|
|
||||||
|
otherwise, you have to manually inject the sidecar before deploying the `sleep` application:
|
||||||
|
|
||||||
|
{{< text bash >}}
|
||||||
|
$ kubectl apply -f <(istioctl kube-inject -f @samples/sleep/sleep.yaml@)
|
||||||
|
{{< /text >}}
|
||||||
|
|
||||||
|
Note that any pod that you can `exec` and `curl` from would do.
|
||||||
|
|
||||||
|
* Create a shell variable to hold the name of the source pod for sending requests to external services.
|
||||||
|
If you used the [sleep]({{<github_tree>}}/samples/sleep) sample, run:
|
||||||
|
|
||||||
|
{{< text bash >}}
|
||||||
|
$ export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
|
||||||
|
{{< /text >}}
|
||||||
|
|
||||||
|
## Deploy an HTTPS proxy
|
||||||
|
|
||||||
|
For this example, to simulate a legacy proxy, you deploy an HTTPS proxy inside your cluster. Also, to simulate a more
|
||||||
|
realistic proxy that is running outside of your cluster, you will address the pod of the proxy by its IP address and
|
||||||
|
not by a Kubernetes service.
|
||||||
|
You can use any HTTPS proxy that supports HTTP Connect. We used [Squid](http://www.squid-cache.org).
|
||||||
|
|
||||||
|
1. Create a namespace for the HTTPS proxy. Note that since you do not label it for Istio automatic sidecar injection,
|
||||||
|
Istio will not control traffic in this namespace.
|
||||||
|
|
||||||
|
{{< text bash >}}
|
||||||
|
$ kubectl create namespace external
|
||||||
|
{{< /text >}}
|
||||||
|
|
||||||
|
1. Create a configuration file for the Squid proxy.
|
||||||
|
|
||||||
|
{{< text bash >}}
|
||||||
|
$ 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
|
||||||
|
{{< /text >}}
|
||||||
|
|
||||||
|
1. Create a Kubernetes [ConfigMap](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/)
|
||||||
|
to hold the configuration of the proxy:
|
||||||
|
|
||||||
|
{{< text bash >}}
|
||||||
|
$ kubectl create configmap proxy-configmap -n external --from-file=squid.conf=./proxy.conf
|
||||||
|
{{< /text >}}
|
||||||
|
|
||||||
|
1. Deploy a container with Squid:
|
||||||
|
|
||||||
|
{{< text bash >}}
|
||||||
|
$ kubectl apply -f - <<EOF
|
||||||
|
apiVersion: extensions/v1beta1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: squid
|
||||||
|
namespace: external
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
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
|
||||||
|
{{< /text >}}
|
||||||
|
|
||||||
|
1. Deploy the [sleep]({{< github_tree >}}/samples/sleep) sample in the `external` namespace to test traffic to the
|
||||||
|
proxy without Istio traffic control.
|
||||||
|
|
||||||
|
{{< text bash >}}
|
||||||
|
$ kubectl apply -n external -f @samples/sleep/sleep.yaml@
|
||||||
|
{{< /text >}}
|
||||||
|
|
||||||
|
1. Define an environment variable to hold the IP address of the proxy pod:
|
||||||
|
|
||||||
|
{{< text bash >}}
|
||||||
|
$ export PROXY_IP=$(kubectl get pod -n external -l app=squid -o jsonpath={.items..podIP})
|
||||||
|
{{< /text >}}
|
||||||
|
|
||||||
|
1. Define an environment variable to hold the port of your proxy. The deployment of Squid in this example uses port
|
||||||
|
3128.
|
||||||
|
|
||||||
|
{{< text bash >}}
|
||||||
|
$ export PROXY_PORT=3128
|
||||||
|
{{< /text >}}
|
||||||
|
|
||||||
|
1. Send a request from the `sleep` pod in the `external` namespace to an external service via the proxy:
|
||||||
|
|
||||||
|
{{< text bash >}}
|
||||||
|
$ 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>"
|
||||||
|
<title>Wikipedia, the free encyclopedia</title>
|
||||||
|
{{< /text >}}
|
||||||
|
|
||||||
|
1. Check the access log of the proxy for your request:
|
||||||
|
|
||||||
|
{{< text bash >}}
|
||||||
|
$ 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
|
||||||
|
1544160065.248 228 172.30.109.89 TCP_TUNNEL/200 87633 CONNECT en.wikipedia.org:443 - HIER_DIRECT/91.198.174.192 -
|
||||||
|
{{< /text >}}
|
||||||
|
|
||||||
|
At this point the proxy has been deployed and tested by using `curl` to access `wikipedia.org` through the proxy, all
|
||||||
|
without Istio. It's just plain Kubernetes setting so far, which simulates an external HTTPS proxy.
|
||||||
|
In the following section you are going to configure traffic from Istio-enabled pods to the HTTPS proxy.
|
||||||
|
|
||||||
|
## Configure traffic to external HTTPS proxy
|
||||||
|
|
||||||
|
1. Define a TCP (!) Service Entry for the HTTPS proxy. Note that despite the fact that the HTTP
|
||||||
|
[CONNECT](https://tools.ietf.org/html/rfc7231#section-4.3.6) method is used to communicate with HTTPS proxies,
|
||||||
|
the traffic between the application and the proxy is TCP (a TCP tunnel), and not HTTP.
|
||||||
|
|
||||||
|
{{< text bash >}}
|
||||||
|
$ kubectl apply -f - <<EOF
|
||||||
|
apiVersion: networking.istio.io/v1alpha3
|
||||||
|
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
|
||||||
|
EOF
|
||||||
|
{{< /text >}}
|
||||||
|
|
||||||
|
1. Send a request from the `sleep` pod in the `default` namespace. The `sleep` pod has Istio sidecar injected and its
|
||||||
|
traffic is controlled by Istio.
|
||||||
|
|
||||||
|
{{< text bash >}}
|
||||||
|
$ 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>"
|
||||||
|
<title>Wikipedia, the free encyclopedia</title>
|
||||||
|
{{< /text >}}
|
||||||
|
|
||||||
|
1. Check the Istio sidecar proxy's logs for your request:
|
||||||
|
|
||||||
|
{{< text bash >}}
|
||||||
|
$ 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 -
|
||||||
|
{{< /text >}}
|
||||||
|
|
||||||
|
1. Check the access log of the proxy for your request:
|
||||||
|
|
||||||
|
{{< text bash >}}
|
||||||
|
$ 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
|
||||||
|
1544160065.248 228 172.30.109.89 TCP_TUNNEL/200 87633 CONNECT en.wikipedia.org:443 - HIER_DIRECT/91.198.174.192 -
|
||||||
|
{{< /text >}}
|
||||||
|
|
||||||
|
## Understanding what happened
|
||||||
|
|
||||||
|
In this example you configured access to an external legacy HTTPS proxy from the Istio service mesh. To simulate a
|
||||||
|
remote HTTPS proxy, you deployed an HTTPS proxy in a separate namespace, without Istio automatic sidecar injection. In addition, for simulation of a remote proxy, you addressed the HTTPS proxy by its IP address and not by a Kubernetes
|
||||||
|
service.
|
||||||
|
|
||||||
|
To enable Istio-controlled traffic to the external HTTPS proxy you created a TCP service entry with the IP address and
|
||||||
|
the port of the proxy. Note that you must not create service entries for the external services you access though the
|
||||||
|
external proxy, like `wikipedia.org`. This is because from Istio's point of view the requests are sent to the
|
||||||
|
external proxy only; Istio is not aware of the fact that the external proxy forwards the requests further.
|
||||||
|
|
||||||
|
## Cleanup
|
||||||
|
|
||||||
|
1. Shutdown the [sleep]({{<github_tree>}}/samples/sleep) service:
|
||||||
|
|
||||||
|
{{< text bash >}}
|
||||||
|
$ kubectl delete -f @samples/sleep/sleep.yaml@
|
||||||
|
{{< /text >}}
|
||||||
|
|
||||||
|
1. Shutdown the [sleep]({{<github_tree>}}/samples/sleep) service in the `external` namespace:
|
||||||
|
|
||||||
|
{{< text bash >}}
|
||||||
|
$ kubectl delete -f @samples/sleep/sleep.yaml@ -n external
|
||||||
|
{{< /text >}}
|
||||||
|
|
||||||
|
1. Shutdown the Squid proxy, remove the `ConfigMap` and the configuration file:
|
||||||
|
|
||||||
|
{{< text bash >}}
|
||||||
|
$ kubectl delete -n external deployment squid
|
||||||
|
$ kubectl delete -n external configmap proxy-configmap
|
||||||
|
$ rm ./proxy.conf
|
||||||
|
{{< /text >}}
|
||||||
|
|
||||||
|
1. Delete the `external` namespace:
|
||||||
|
|
||||||
|
{{< text bash >}}
|
||||||
|
$ kubectl delete namespace external
|
||||||
|
{{< /text >}}
|
||||||
|
|
||||||
|
1. Delete the Service Entry:
|
||||||
|
|
||||||
|
{{< text bash >}}
|
||||||
|
$ kubectl delete serviceentry proxy
|
||||||
|
{{< /text >}}
|
Loading…
Reference in New Issue