第十七部分 Istio控制 Egress 流量

简述

默认情况下,Istio服务Mesh中的Pod,由于其 iptables 将所有外发流量都透明的转发给了 Sidecar,所以这些集群内的服务无法访问集群之外的 URL,而只能处理集群内部的目标。本文主要介绍如何让Istio 集群中的服务访问外部的服务,即如何通过定义 ServiceEntry 来调用外部服务简单的对 Istio 进行配置,或要求其直接放行对特定 IP 范围的访问。

前提

  • 正确安装Istio
  • 安装实例程序sleep
  • 手动或自动注入sidecar
kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml)

YAML具体内容如下:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: sleep
---
apiVersion: v1
kind: Service
metadata:
  name: sleep
  labels:
    app: sleep
spec:
  ports:
  - port: 80
    name: http
  selector:
    app: sleep
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: sleep
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: sleep
    spec:
      serviceAccountName: sleep
      containers:
      - name: sleep
        image: pstauffer/curl
        command: ["/bin/sleep", "3650d"]
        imagePullPolicy: IfNotPresent

 

  • 将 SOURCE_POD 环境变量设置为已部署的 sleep pod:
export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})

在 Istio 中配置外部服务

通过配置 Istio ServiceEntry,可以从 Istio 集群中访问任何可公开外部的服务。 这里我们会使用 httpbin.org 以及 www.google.com 进行试验。

  • 配置外部服务

1.创建一个 ServiceEntry 对象,放行对一个外部 HTTP 服务的访问:

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: httpbin-ext
spec:
  hosts:
  - httpbin.org
  ports:
  - number: 80
    name: http
    protocol: HTTP
  resolution: DNS
  location: MESH_EXTERNAL
EOF

2.进入具体的服务Pod:

kubectl exec -it $SOURCE_POD -c sleep sh

3.向外部 HTTP 服务发出请求。

curl http://httpbin.org/headers
  • 配置外部 HTTPS 服务

1.创建一个 ServiceEntry 以允许访问外部 HTTPS 服务。

对于 TLS 协议(包括 HTTPS),除了 ServiceEntry 之外,还需要 VirtualService。 没有 VirtualService, ServiceEntry 所暴露的服务将不被定义。VirtualService 必须在 match 子句中包含 tls 规则和 sni_hosts 以启用 SNI 路由。

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: google
spec:
  hosts:
  - www.google.com
  ports:
  - number: 443
    name: https
    protocol: HTTPS
  resolution: DNS
  location: MESH_EXTERNAL
---
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

2.执行 sleep service 源 pod:

kubectl exec -it $SOURCE_POD -c sleep sh

3.向外部 HTTPS 服务发出请求:

curl https://www.google.com
  • 为外部服务设置路由规则

通过 ServiceEntry 访问外部服务的流量,和网格内流量类似,都可以进行 Istio 路由规则 的配置。下面我们使用 istioctl 为 httpbin.org 服务设置一个超时规则。在测试 Pod 内部,使用 curl 调用 httpbin.org 这一外部服务的 /delay 端点:

kubectl exec -it $SOURCE_POD -c sleep sh
time curl -o /dev/null -s -w "%{http_code}\n" http://httpbin.org/delay/5
200

real    0m5.024s
user    0m0.003s
sys     0m0.003s

这个请求会在大概五秒钟左右返回一个内容为 200 (OK) 的响应。退出测试 Pod,使用 kubectl  httpbin.org 外部服务的访问设置一个 3 秒钟的超时:

kubectl apply -f - <<EOF
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

等待几秒钟之后,再次发起 curl 请求:

kubectl exec -it $SOURCE_POD -c sleep sh
time curl -o /dev/null -s -w "%{http_code}\n" http://httpbin.org/delay/5
504

real    0m3.149s
user    0m0.004s
sys     0m0.004s

这一次会在 3 秒钟之后收到一个内容为 504 (Gateway Timeout) 的响应。虽然 httpbin.org 还在等待他的 5 秒钟,Istio 却在 3 秒钟的时候切断了请求。

直接调用外部服务

如果想要跳过 Istio直接访问某个 IP 范围内的外部服务,就需要对 Envoy sidecar 进行配置,阻止 Envoy 对外部请求的劫持。不推荐此方式,详细了解请自行查阅文档。

总结

控制Egress流量,可以使用两种方式从 Istio 服务Mesh内部来完成对外部服务的调用:

  • 使用 ServiceEntry (推荐方式)
  • 配置 Istio sidecar,从它的重定向 IP 表中排除外部服务的 IP 范围

第一种方式(ServiceEntry)中,Mesh内部的服务不论是访问内部还是外部的服务,都可以使用同样的 Istio 服务Mesh的特性。我们通过为外部服务访问设置超时规则的例子,来证实了这一优势。第二种方式越过了 Istio sidecar proxy,让服务直接访问到对应的外部地址。然而要进行这种配置,需要了解云供应商特定的知识和配置。

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值