默认情况下,启用Istio的服务无法访问集群外的URL,因为在pod中使用iptables将所有出站流量透明地重定向到仅处理集群内目的地的sidecar代理。
这个task描述如何配置Istio向启用Istio的客户端暴露外部服务。你将了解如何使用egress规则启用对外部服务的访问,或者简单地绕过特定范围IP的Istio代理。
kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml)
注意在任何pod中,你可以使用 exec
和 curl
。
使用Istio的egress规则,你可以从你的Istio集群访问任何公共可访问的服务。在这个task中。我们将使用 httpbin.org 和 www.google.com 作为例子。
1.为能够访问一个外部HTTP服务创建一个egress规则:
cat <apiVersion: config.istio.io/v1alpha2
kind: EgressRule
metadata:
name: httpbin-egress-rule
spec:
destination:
service: httpbin.org
ports:
- port: 80
protocol: http
EOF
2.为能访问一个外部HTTPS服务创建一个egress规则:
cat <apiVersion: config.istio.io/v1alpha2
kind: EgressRule
metadata:
name: google-egress-rule
spec:
destination:
service: www.google.com
ports:
- port: 443
protocol: https
EOF
1.进入作为测试源使用的pod。例如,如果你正使用sleep服务,使用下列命令:
export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
kubectl exec -it $SOURCE_POD -c sleep bash
2.发出一个外部HTTP服务的请求:
curl http://httpbin.org/headers
3.发出一个外部HTTPS服务的请求。外部HTTPS类型的服务必须使用HTTP加特殊端口的请求方式:
curl http://www.google.com:443
和集群内部请求类似,Istio的 routing rules 也可以通过使用egress rules访问外部服务。为了说明这一点,我们将使用Istioctl对调用 httpbin.org服务设置一个超时规则。
1.从用作测试源的pod内部调用 httpbin.org 外部服务的 /delay
端点
kubectl exec -it $SOURCE_POD -c sleep bash
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
请求应该在大约5s内返回200(OK)。
2.退出源pod,并使用 istioctl
设置一个调用 httpbin.org 外部服务的3s超时:
cat <apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
name: httpbin-timeout-rule
spec:
destination:
service: httpbin.org
http_req_timeout:
simple_timeout:
timeout: 3s
EOF
3.等待几秒,然后再次 curl 发送请求:
kubectl exec -it $SOURCE_POD -c sleep bash
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
这次在3s后返回504(网关超时)。尽管 httpbin.org 等待了5s,但是Istio 在3s时就切断了请求。
Istio的egress规则目前只支持HTTP/HTTPS请求。如果你想要通过其他协议(e.g., mongodb://host/database
)访问服务,或者你想完全绕过Istio特定范围IP,你需要配置源服务的Envoy sidecar来防止它 intercepting 外部请求。这可能在开始服务的时候,在 istioctl kube-inject 使用 --includeIPRanges
选项。
使用 --includeIPRanges
选项最简单的方式是将它用于集群内部服务的IP范围,从而排除外部IP被重定向到sidecar proxy中。然而,内部IP范围的值取决于你正在运行的集群。例如,Minikube的范围是 10.0.0.1/24,因此你将以下面这种方式启动sleep服务:
kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml --includeIPRanges=10.0.0.1/24)
通过这种方式启动你的服务后,Istio的sidecar仅拦截和管理集群内的请求。任何外部请求将简单绕过sidecar并直接到达它想去的目标。
export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
kubectl exec -it $SOURCE_POD -c sleep curl http://httpbin.org/headers
这个task中,我们在Istio集群中使用两种方式调用外部服务:
第一种方法(egress rule)目前仅支持HTTP(S)请求,但允许你对集群内部或外部的调用服务使用所有相同的Istio服务网格功能。我们通过为调用外部服务设置超时规则来演示这部分。
第二种方法绕过Istio sidecar proxy,让你的服务直接访问任何外部URL。但是,以这种方式配置代理需要能够提供特定知识和配置。
1.移除规则
istioctl delete egressrule httpbin-egress-rule google-egress-rule
istioctl delete routerule httpbin-timeout-rule
2.关闭 sleep 服务
kubectl delete -f samples/sleep/sleep.yaml
注意到Istio Egress Rules不是一个安全功能。他们启用对外部服务(服务网格外)的访问。用户可以部署适当的安全机制,如防火墙,以及防止未经授权访问外部服务。我们正在添加对外部服务的访问控制支持。