Istio配置 Egress流量控制

作者: root007 分类: kubernetes 发布时间: 2019-03-04 17:35

在 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/