Istio Ingress流量入口配置原理

18-09-02 banq
         

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:
    - "*"
<p>

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

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

得到结果:

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
<p>

一旦启动,我们就可以打开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
<p>

配置中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
<p>

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

总结

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

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

Understanding Istio Ingress – FireHydrant – Medium