istio应用示例-控制ingress流量
在kubernetes环境下一般用Kubernetes Ingress Resource来发布集群内的服务到外部。在istio服务网格中则采用一个更好的配置模型(也能用于kubernetes和其它环境),它就是istio gateway。网关可以使用进入集群的流量应用监视和路由规则等istio的特色功能。
下面我们来看看如何采用istio 网关来实现发布服务网格中的服务到外部。
一、准备工作
- 根据指导安装Istio Installation guide。
- 确保当前目录是istio目录。
- 启动httpbin 示例应用。
- 如何你已经开启自动sidecar注入,部署httpbin服务的命令如下:
kubectl apply -f samples/httpbin/httpbin.yaml
- 否则在部署httpbin前采用手工注入sidecar,命令如下:
kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml)
4、按照下一节的说明确定 ingress IP 和ports 。
二、确定ingress IP和ports
依据istio-ingressgateway服务是否是 load balancers还是nodeport类型采用不同的方式获取ingress ip 和ports。
1)若istio-ingressgateway是load balancers类型的服务(一般公有云上用load balancers,企业网上自建的集群用nodeport), 则采用如下的命令将ingress ip 和端口存到环境变量中。
export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].port}')
2)若istio-ingressgateway是nodeport类型的服务,则采用如下的命令获取ingress ports和ip。
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')
export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}')
三、用istio网关配置ingress
Ingress网关在服务网格的边缘为进入的http/tcp连接描述负载均衡操作,配置暴露的端口和协议等内容。与k8s ingress resources不同的是这里用istio的路由规则来代替ingress中的流量路由配置。下面我们来看看如何在80端口上配置http流量的网关。
1、创建一个istio 网关
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: httpbin-gateway
spec:
selector:
istio: ingressgateway # use Istio default gateway implementation
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "httpbin.example.com"
EOF
2、通过网关为进入流量配置路由规则
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- "httpbin.example.com"
gateways:
- httpbin-gateway
http:
- match:
- uri:
prefix: /status
- uri:
prefix: /delay
route:
- destination:
port:
number: 8000
host: httpbin
EOF
现在你已经为httpbin服务创建了一个virtual service,里面包含两条路由规则,允许流量访问/status和/delay。该配置定义了外部请求只有通过httpbin-gateway能访问成功,其它外部请求都会返回404拒绝响应。
3、采用curl 来访问httpbin服务
curl -I -HHost:httpbin.example.com http://$INGRESS_HOST:$INGRESS_PORT/status/200
注意上面使用-H标记来设置Host http头为“httpbin.example.com”,这是必须的,因为你的ingress 网关中配置要处理来自“httpbin.example.com”的流量,但你的测试环境中没有DNS绑定那个域名,仅仅直接把请求发送给ingress ip。
4、访问其它未暴露的URL将会返回404错误。
curl -I -HHost:httpbin.example.com http://$INGRESS_HOST:$INGRESS_PORT/headers
- 四、通过浏览器访问ingress服务
若在浏览器中直接输入httpbin服务的URL不能成功访问,因为你无法像curl一样让浏览器假扮访问httpbin.example.com域名。但若在真实环境中这不是一个问题,因为可以配置DNS解析来实现,现实中可以用域名来访问,比如 https://httpbin.example.com/status/200。
为了绕过上面的问题进行演示测试,我们可以*替换gateway和virtualService中的配置。比如可以按如下方式修改ingress配置文件。
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: httpbin-gateway
spec:
selector:
istio: ingressgateway # use Istio default gateway implementation
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- "*"
gateways:
- httpbin-gateway
http:
- match:
- uri:
prefix: /headers
route:
- destination:
port:
number: 8000
host: httpbin
EOF
执行以上命令后你就可以用$INGRESS_HOST:$INGRESS_PORT (e.g., 10.30.28.185:31380
) 在浏览器中通过URL进行访问了。比如http://10.30.28.185:31380/headers将会显示请求头信息。