Configure an Egress Gateway
案例演示了如何通过istio edge 组件的Egress Gateway导向流量到外部的服务。 然而,一些案例请求一个外部的,传统的HTTPS代理到外部的服务进行访问。 比如,你公司可能有一个代理,公司所有到外部的请求都要经过它。
本案例演示了如何开启访问到外部的HTTPS proxy. 由于应用使用HTTP 连接方法到HTTPS 代理建立连接,配置流量到外部的HTTPS proxy到到外部HTTP和HTTPS服务是不同的。
1. 准备工作
- 部署sleep应用,如果开启了自动sidecar注入。运行以下命令
$ kubectl apply -f samples/sleep/sleep.yaml
- 手工注入执行以下命令
$ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml)
- 设置
SOURCE_POD
变量获取你source pod的名称
$ export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
- 开启Envoy的访问日志
$ istioctl manifest apply --set profile=demo --set meshConfig.accessLogFile="/dev/stdout"
2. 部署HTTPS 代理
使用squid去模拟传统的代理
- 针对HTTPS代理创建名称空间, 不要针对它开启sidecar 注入。
$ kubectl create namespace external
- 创建针对Squid proxy的配置文件
$ 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
- 创建一个拥有proxy配置的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:
selector:
matchLabels:
app: squid
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
- 在external的名称空间中部署sleep的应用到代理间的流量(没有Istio traffic的控制)
$ kubectl apply -n external -f samples/sleep/sleep.yaml
- 获得proxy pod的IP地址,并把它存储到
PROXY_IP
的变量中。
$ export PROXY_IP=$(kubectl get pod -n external -l app=squid -o jsonpath={.items..podIP})
- 获得proxy pod的端口,并把它存储到
PROXY_PORT
变量中。
$ export PROXY_PORT=3128
- 在external的名称空间中,使用sleep pod通过代理发送请求到外部。
$ 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>"
- 检查代理的访问日志
$ 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
- 针对HTTPS proxy定义TCP的服务条目。 尽管应用使用HTTP 连接方法去和HTTPS proxy建立连接。 你必须配置针对TCP流量的代理,代替HTTP。 一旦连接建立, 这个代理简单的扮演着TCP tunnel.
$ 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
- 从默认的名称空间sleep pod发送请求,因为这个sleep pod有sidecar,Istio控制它的流量。
$ 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>"
- 针对你的请求,检查Istio sidecar 代理的日志
$ kubectl logs $SOURCE_POD -c istio-proxy
- 检查你请求的代理访问日志
$ 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. 清空本实验
- 关闭sleep服务
$ kubectl delete -f samples/sleep/sleep.yaml
- 关闭在external名称空间中的sleep服务
$ kubectl delete -f samples/sleep/sleep.yaml -n external
- 关闭squid proxy, 移除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