Istio Ingress流量入口配置原理

Istio现在是一项热门技术。谷歌和IBM等巨头已经将整个工程师团队投入到项目中,从而将其推向生产准备阶段,最近自从1.0发布以来,这里介绍Istio是如何利用Kubernetes的Ingress控制器和服务负载平衡器。

本文介绍Istio的核心概念,就是如何让外部流量进入你的集群,需要以下技术:

Minikube 0.28.0
Kubernetes 1.10
Istio 1.0.1

Istio的Gateway类型
Istio有一种名为“Gateway”的资源类型,Istio Gateway告诉k8s的istio-ingressgateway pods可以打开哪些主机和端口,它这是通过使用Kubernetes创造的标签选择器( label selector)模式来实现,让我们看一下Istio文档中的httpbin网关配置:


apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: httpbin-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"

配置中selector的值是istio: ingressgateway,这里很有趣,K8s的istio-ingresgateway pod被标记为“istio = ingressgateway”的标签,这样可以使用kubectl轻松找到它们:


$ kubectl get pod -n istio-system -l istio = ingressgateway -o name

得到结果:
pod/istio-ingressgateway-6fd6575b8b-xls7g
因此,该pod将接收网关配置并最终公开打开相应端口,因为它正好与与Istio Gateway标签选择器匹配。太好了!让我们亲眼看看。

Istio会配置Envoy这个主机来接受并路由转发流量的,Envoy还附带了一个非常简单的管理功能,可以直接访问,Istio是配置Envoy侦听为15000端口用于管理,这意味着我们可以使用kubectl轻松访问它:


$ kubectl -n istio-system port-forward istio-ingressgateway-6fd6575b8b-tfc7z 15000

一旦启动,我们就可以打开http:// localhost:15000/listeners并查看已添加到此pod的监听器。

这就在Istio的ingress网关上开辟了一个端口,但是只是接受访问和流量输入,当流量到达这个网关时,它还不知道发送到哪里去。

Istio的“VirtualService”类型
现在我们的网关已准备好接收流量,我们必须告知它将收到的流量发往何处,Istio使用名为“VirtualService”类型配置流量发往何处。将一个网关列表配置给VirtualService,然后Istio使用VirtualService配置中定义的路由再配置那些网关,例如,以再次使用httpbin示例:


apiVersion:networking.istio.io/v1alpha3
kind:VirtualService
metadata:
name:httpbin
spec:
hosts:
- “*”
gateways:
- httpbin-gateway
http:
- match:
- uri:
prefix:/status
- uri:
prefix:/delay
route:
- destination:
port:
number:8000
host:httpbin

配置中gateways定义为 httpbin-gateway,这就是将VirtualService配置到指定的网关上,然后,URI路径前缀匹配/status的将发往指定目标,URI路径前缀匹配/delay将发往指定目标。

当我们使用此功能时,可以使用Envoy管理功能反复查看此情况。打开http:// localhost:15000/config_dump在输出的JSON中查找“routes”部分,如果找到相关定义:


说明Istio已采用我们的VirtualService定义并将其应用于与名称匹配的网关pod。成功!

通过这一切设置,我们可以使用一个简单的清单在我们的Kubernetes集群中安装HTTPBin项目。配置文件在github,我们还可以在kubectl上使用方便的port-forward命令来公开我们的httpbin网关:

$ kubectl -n istio-system port-forward istio-ingressgateway-6fd6575b8b-tfc7z 80

注意:可能需要使用sudo运行它。

运行此选项后,打开另一个终端选项卡并尝试curl访问:


$ curl -v localhost/status/200
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 80 (#0)
> GET /status/200 HTTP/1.1
> Host: localhost
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< server: envoy
< date: Fri, 31 Aug 2018 16:25:31 GMT
< content-type: text/html; charset=utf-8
< access-control-allow-origin: *
< access-control-allow-credentials: true
< content-length: 0
< x-envoy-upstream-service-time: 2
<
* Connection #0 to host localhost left intact

成功!我们的httpbin项目已通过我们的Istio Gateway和VirtualService公开。

总结
1. Gateway: Istio Gateway是负责打开k8s上相关Istio的pods上的端口并接收主机的流量,是接收流量与路由之间的关键链接。

2. VirtualService: Istio VirtualService是“附加”到Gateway上的,并负责定义Gateway应实现的路由。可以将多个VirtualServices连接到Gateway,但不适用于同一个域。


Understanding Istio Ingress – FireHydrant – Medium