参考:https://istio.io/latest/zh/docs/tasks/traffic-management/egress/egress-control/#controlled-access-to-external-services
使用 Istio ServiceEntry
配置,你可以从 Istio 集群中访问任何公开的服务。本节将向你展示如何在不丢失 Istio 的流量监控和控制特性的情况下,配置对外部 HTTP 服务(httpbin.org) 和外部 HTTPS 服务(www.baidu.com) 的访问。
1、更改为默认的封锁策略
为了演示如何控制对外部服务的访问,你需要将 global.outboundTrafficPolicy.mode
选项,从 ALLOW_ANY
模式 改为 REGISTRY_ONLY
模式。这个对开发有一定的习惯上的要求,为了生产稳定还是ALLOW_ANY吧。
ALLOW_ANY
模式下的可访问服务添加访问控制。通过这种方式,你可以在一些外部服务上使用 Istio 的特性,而不会阻止其他服务。一旦你配置了所有服务,就可以将模式切换到 REGISTRY_ONLY
来阻止任何其他无意的访问。istioctl install <flags-you-used-to-install-Istio> \ --set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY
1.2)如果REGISTRY_ONLY,可以从pod向外发出测试
kubectl exec -it $SOURCE_POD -c sleep -- curl -I https://www..com | grep "HTTP/"; kubectl exec -it $SOURCE_POD -c sleep -- curl -I https://edition.cnn.com | grep "HTTP/"
2、访问一个外部http服务
2.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.2) 从 SOURCE_POD
向外部的 HTTP 服务发出一个请求:
kubectl exec -it $SOURCE_POD -c sleep -- curl http://httpbin.org/headers
2.3) 检查 SOURCE_POD
的 sidecar 代理的日志:
kubectl logs $SOURCE_POD -c istio-proxy | tail [2022-04-02T03:19:38.585Z] "GET /headers HTTP/1.1" 200 - via_upstream - "-" 0 1140 607 579 "-" "curl/7.81.0-DEV" "1b749c4b-c187-974e-b949-ec82f16107ef" "httpbin.org" "3.229.191.75:80" PassthroughCluster 10.1.0.33:45100 3.229.191.75:80 10.1.0.33:45092 - allow_any
有无se的日志上的区别,没有se就变成了PassthroughCluster(透传)
无: [2022-04-02T03:19:38.585Z] "GET /headers HTTP/1.1" 200 - via_upstream - "-" 0 1140 607 579 "-" "curl/7.81.0-DEV" "1b749c4b-c187-974e-b949-ec82f16107ef" "httpbin.org" "3.229.191.75:80" PassthroughCluster 10.1.0.33:45100 3.229.191.75:80 10.1.0.33:45092 - allow_any 有: [2022-04-02T03:27:16.401Z] "GET /headers HTTP/1.1" 200 - via_upstream - "-" 0 1196 730 729 "-" "curl/7.81.0-DEV" "1c761aa4-8b7d-998d-be09-c759b423bd20" "httpbin.org" "34.195.113.193:80" outbound|80||httpbin.org 10.1.0.33:59326 44.195.242.112:80 10.1.0.33:42906 - default
3、访问外部https服务
3.1) 创建一个ServiceEntry
,允许对外部服务的访问。kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1alpha3 kind: ServiceEntry metadata: name: baidu spec: hosts: - www.baidu.com ports: - number: 443 name: https protocol: HTTPS resolution: DNS location: MESH_EXTERNAL EOF
3.2) 从 SOURCE_POD
往外部 HTTPS 服务发送请求:
kubectl exec -it $SOURCE_POD -c sleep -- curl -I https://www.baidu.com | grep "HTTP/"
3.3) 有无加se的日志上的区别,没有se就变成了PassthroughCluster(透传)
没有: [2022-04-02T03:22:55.379Z] "- - -" 0 - - - "-" 785 4645 59 - "-" "-" "-" "-" "180.97.34.94:443" PassthroughCluster 10.1.0.33:33466 180.97.34.94:443 10.1.0.33:33464 - - 有: [2022-04-02T03:24:43.408Z] "- - -" 0 - - - "-" 785 4645 94 - "-" "-" "-" "-" "180.97.34.94:443" outbound|443||www.baidu.com 10.1.0.33:35094 180.97.34.94:443 10.1.0.33:35092 www.baidu.com -
4、管理到外部的流量
与集群内的请求相似,也可以为使用 ServiceEntry
配置访问的外部服务设置 Istio 路由规则。在本示例中,你将设置对 httpbin.org
服务访问的超时规则。当对方访问时间太长时主动断开请求。
4.1)从用作测试源的 pod 内部,向外部服务 httpbin.org
的 /delay
endpoint 发出 curl 请求:
jichengwei@localhost istio-1.12.1 % kubectl exec "$SOURCE_POD" -c sleep -- time curl -o /dev/null -sS -w "%{http_code}\n" http://httpbin.org/delay/5 200 real 0m 6.95s user 0m 0.00s sys 0m 0.00s
4.2)退出测试源 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
4.3)重新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 0m 3.04s user 0m 0.00s sys 0m 0.01s