Istio配置 Egress流量控制
在 Istio中配置从网格内访问外部服务的流量路由。
认情况下,启用 Istio 的应用程序无法访问集群外的 URL。要启用此类访问,必须定义外部服务的服务条目,或者直接访问外部服务。
Istio 0.8 引入了 ingress 和 egress 网关的概念。 Ingress 网关允许定义进入服务网格的入口点,所有入站流量都通过该入口点。 缺省情况下,Istio 服务网格内的 Pod,由于其 iptables 将所有外发流量都透明的转发给了 Sidecar,所以这些集群内的服务无法访问集群之外的 URL,而只能处理集群内部的目标。
以之前部署好的pod为例
export SOURCE_POD=$(kubectl get pod -l app=tomcat-istio -o jsonpath={.items..metadata.name})
在pod 使用 exec
和 curl
验证
定义 Istio ServiceEntry
通过配置 Istio ServiceEntry
,可以从 Istio 集群中访问外部任意的可用服务 , 使用Istio ServiceEntry
配置. 为 baidu.com
定义一个 ServiceEntry
放行http/hpps:
cat <<EOF | istioctl create -f -
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: baidu
spec:
hosts:
- baidu.com
ports:
- number: 80
name: http-port
protocol: HTTP
- number: 443
name: https
protocol: HTTPS
resolution: DNS
EOF
测试2使用 httpbin.org
创建一个 ServiceEntry
对象,放行对一个外部 HTTP 服务的访问:
cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: httpbin-ext
spec:
hosts:
- httpbin.org
ports:
- number: 80
name: http
protocol: HTTP
resolution: DNS
EOF
验证没配置egress之前
root@tomcat-istio:/usr/local/tomcat# curl -I http://httpbin.org/delay/5
HTTP/1.1 404 Not Found
date: Mon, 04 Mar 2019 08:50:25 GMT
server: envoy
transfer-encoding: chunked
配置之后
root@tomcat-istio:/usr/local/tomcat# curl -I http://httpbin.org/delay/5
HTTP/1.1 200 OK
access-control-allow-credentials: true
access-control-allow-origin: *
content-length: 740
content-type: application/json
date: Mon, 04 Mar 2019 08:51:15 GMT
server: envoy
x-envoy-upstream-service-time: 5590
建一个 ServiceEntry
以及 VirtualService
,允许访问外部 HTTPS 服务。注意:包括 HTTPS 在内的 TLS 协议,在除ServiceEntry
之外,还需要创建 TLS VirtualService
。
未配置之前
root@tomcat-istio:/usr/local/tomcat# curl -I https://httpbin.org/headers
curl: (51) SSL: no alternative certificate subject name matches target host name 'httpbin.org'
cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: google
spec:
hosts:
- www.google.com
ports:
- number: 443
name: https
protocol: HTTPS
resolution: DNS
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: google
spec:
hosts:
- www.google.com
tls:
- match:
- port: 443
sni_hosts:
- www.google.com
route:
- destination:
host: www.google.com
port:
number: 443
weight: 100
EOF
为外部服务设置路由规则
在测试 Pod 内部,使用 curl
调用 httpbin.org 这一外部服务的 /delay
端点:
root@tomcat-istio:/usr/local/tomcat# time curl -o /dev/null -s -w "%{http_code}\n" http://httpbin.org/delay/5
200
real 0m5.580s
user 0m0.006s
sys 0m0.003s
这个请求会在大概五秒钟左右返回一个内容为 200 (OK)
的响应。
使用 istioctl
为 httpbin.org 外部服务的访问设置一个 3 秒钟的超时。创建
VirtualService 对象
cat <<EOF | istioctl create -f -
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin-ext
spec:
hosts:
- httpbin.org
http:
- timeout: 3s
route:
- destination:
host: httpbin.org
weight: 100
EOF
[root@k8s-master ~]# kubectl get VirtualService
NAME AGE
bookinfo 5d
httpbin-ext 53s
tomcat-istio 3d
再次发起 curl
请求:
3 秒钟之后收到一个内容为 504 (Gateway Timeout)
的响应。虽然 httpbin.org 还在等待他的 5 秒钟,Istio 却在 3 秒钟的时候切断了请求。
root@tomcat-istio:/usr/local/tomcat# time curl -o /dev/null -s -w "%{http_code}\n" http://httpbin.org/delay/5
504
real 0m3.039s
user 0m0.006s
sys 0m0.005s
直接调用外部服务
如果想要跳过 Istio,直接访问某个 IP 范围内的外部服务 参考https://istio.io/zh/docs/tasks/traffic-management/egress/