默认情况下,启用Istio的服务无法访问集群外的URL,因为在pod中使用iptables将所有出站流量透明地重定向到仅处理集群内目的地的sidecar代理。
这个task描述如何配置Istio向启用Istio的客户端暴露外部服务。你将了解如何通过定义 ServiceEntry的配置启用对外部服务的访问,或者简单地绕过特定范围IP的Istio代理。
Before you begin
- 安装Istio
- 启动 sleep 示例来作为外部调用的测试源
如果你开启了自动注入sidecar,执行
kubectl apply -f samples/sleep/sleep.yaml
否则,你需要在部署sleep 应用前手动注入sidecar:
kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml)
注意在任何pod中,你可以使用 exec
和 curl
。
Configuring Istio external services
使用Istio的ServiceEntry
配置,你可以从你的Istio集群访问任何公共可访问的服务。在这个task中。我们将使用 httpbin.org
和 www.google.com
作为例子。
Configuring the external services
1.为能够访问一个外部HTTP服务创建一个ServiceEntry
:
cat <<EOF | istioctl create -f -
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: httpbin-ext
spec:
hosts:
- httpbin.org
ports:
- number: 80
name: http
protocol: HTTP
EOF
2.为能访问一个外部HTTPS服务创建一个ServiceEntry
:
cat <<EOF | istioctl create -f -
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: google-ext
spec:
hosts:
- www.google.com
ports:
- number: 443
name: https
protocol: HTTPS
EOF
Make request to the external services
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服务的请求。
curl https://www.google.com
Setting route rules on an external service
和集群内部请求类似,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
2.退出源pod,并使用 istioctl
设置一个调用 httpbin.org 外部服务的3s超时:
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
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时就切断了请求。
Calling external services directly
如果你想完全绕过Istio特定范围IP,你需要配置源服务的Envoy sidecar来防止它 intercepting 外部请求。通过设置 Helm 的变量 global.proxy.includeIPRanges
并通过 kubectl apply
更新 ConfigMap
istio-sidecar-injector 。在 istio-sidecar-injector 更新完成后,global.proxy.includeIPRanges
的值将影响未来应用pods的所有部署
使用 global.proxy.includeIPRanges
变量最简单的方式是将它用于集群内部服务的IP范围,从而排除外部IP被重定向到sidecar proxy中。然而,内部IP范围的值取决于你正在运行的集群。例如,Minikube的范围是 10.0.0.1/24,你需要像下面这样更新你的 ConfigMap
istio-sidecar-injector :
helm template install/kubernetes/helm/istio <the flags you used to install Istio> --set global.proxy.includeIPRanges="10.0.0.1/24" -x templates/sidecar-injector-configmap.yaml | kubectl apply -f -
注意你应该使用安装Istio相同的Helm命令,特别是 --namespace
标志的值相同。除了用于安装Istio的标志外,还要添加 --set global.proxy.includeIPRanges="10.0.0.1/24" -x templates/sidecar-injector-configmap.yaml
.
按照Before you begin那节重新部署sleep应用。
Determine the value of global.proxy.includeIPRanges
不同的集群提供商的 global.proxy.includeIPRanges
值的设置不同。
详见here。
Access the external services
在更新完ConfigMap
istio-sidecar-injector 并重新部署完sleep 应用后,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
Understanding what happened
这个task中,我们在Istio集群中使用两种方式调用外部服务:
1.使用ServiceEntry
(推荐)
2.配置Istio sidecar,使它的重新映射的IP表剔除外部IP。
第一种方法(egress rule)允许你对集群内部或外部的调用服务使用所有相同的Istio服务网格功能。我们通过为调用外部服务设置超时规则来演示这部分。
第二种方法绕过Istio sidecar proxy,让你的服务直接访问任何外部URL。但是,以这种方式配置代理需要云提供商的特定知识和配置。
Cleanup
1.移除规则
istioctl delete serviceentry httpbin-ext google-ext
istioctl delete virtualservice httpbin-ext
2.关闭 sleep 服务
kubectl delete -f samples/sleep/sleep.yaml
3.更新 ConfigMap
istio-sidecar-injector 来重定向所有外部流量到sidecar代理:
helm template install/kubernetes/helm/istio <the flags you used to install Istio> -x templates/sidecar-injector-configmap.yaml | kubectl apply -f -