在kubernetes环境下一般用Kubernetes Ingress Resource来发布集群内的服务到外部。在istio服务网格中则采用一个更好的配置模型(也能用于kubernetes和其它环境),它就是istio gateway。网关可以使用进入集群的流量应用监视和路由规则等istio的特色功能。
下面我们来看看如何采用istio 网关来实现发布服务网格中的服务到外部。
kubectl apply -f samples/httpbin/httpbin.yaml
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 - < 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 - < 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 若在浏览器中直接输入httpbin服务的URL不能成功访问,因为你无法像curl一样让浏览器假扮访问httpbin.example.com域名。但若在真实环境中这不是一个问题,因为可以配置DNS解析来实现,现实中可以用域名来访问,比如 https://httpbin.example.com/status/200。 为了绕过上面的问题进行演示测试,我们可以*替换gateway和virtualService中的配置。比如可以按如下方式修改ingress配置文件。 kubectl apply -f - < 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将会显示请求头信息。