在kubernetes中部署kong做为api网关,分为两种方式, 一种是无数据库, 这种方式数据都是保存于内存中,不推荐在生产中使用,另一种则支持数据库(pg或cassandra),下面分别介绍.
部署
具体的部署过程不打算贴在这里,官方都有详细的文档, 可参考kubernetes-ingress-controller
由于kong提供了控制面的接口,因此会使用以下几个端口来接收相关的请求,如下图:
DBless
对于DBless的部署方式下:
只需要一个deployment, 包含2个容器,一个kong,充当proxy,这个proxy监听8000(http),8443(https), 8100(metrics)
另一个为ingress controller, 用于生成kong的配置
由于每个deployment都是这样的,不存在数据库, 因此直接扩大实例可以处理更多的请求
DBWith
对于使用数据库的部署:
对于数据平面来说,可以使用daemonset来部署, 里面只有一个容器,即kong,充当proxy, 它会负责所有流量的转发
所有从外部80/443的流量都会转到8000/8444上, 正好是kong-proxy的监听端口
而对于控制面,使用deployment部署,包含有两个容器, 一个kong,另一个则是kong-ingress-controller
控制面不转发任何的流量, 只负责将api-server的变动同步到kong的数据库中, 如果存在多个deployment,则会进行选主,确保任一时刻只有一个实例对kong的数据库进行配置.
Kong集群中的节点通过gossip协议自动发现其他节点,当通过一个Kong节点的管理API进行一些变更时也会通知其他节点。每个Kong节点的配置信息是会缓存的,如插件,那么当在某一个Kong节点修改了插件配置时,需要通知其他节点配置的变更
nginx ingress VS kong ingress
如果是用惯了nginx-ingress-controller,再来使用kong ingress controller,开始会觉得很奇怪,为何kong ingress controller使用的是deployment部署呢,先来看看官方的描述:
Ingress Controller deployment
1 | Kong Ingress deployment consists of the Ingress Controller deployed alongside Kong. The deployment will be different depending on if a database is being used or not. |
翻译: Kong Ingress部署包括与Kong一起部署的Ingress Controller。部署将根据是否正在使用数据库而有所不同。 deployment是实际运行Kong Ingress Controller的核心
Kong Proxy service
1 | Once Kong Ingress Controller is deployed, one service is needed to expose Kong outside the Kubernetes cluster so that it can receive all traffic that is destined for the cluster and route it appropriately. kong-proxy is a Kubernetes service which points to the Kong pods which are capable of proxying request traffic. This service will be usually of type LoadBalancer, however it is not required to be such. The IP address of this service should be used to configure DNS records of all the domains that Kong should be proxying, to route the traffic to Kong. |
翻译: 部署Kong Ingress Controller之后,需要一项服务来在Kubernetes群集之外公开Kong,以便它可以接收发往群集的所有流量并进行适当的路由。 kong-proxy是Kubernetes服务,它指向能够代理请求流量的Kong pod。该服务通常将是LoadBalancer类型,但不是必需的。此服务的IP地址应用于配置Kong应该代理的所有域的DNS记录,以将流量路由到Kong.
其实nginx ingress controller之所以使用daemonset部署, 是因为ingress controller与proxy都被nginx+LUA实现了,就直接部署在一个pod中了, 而kong ingress controller从上面看proxy也是kong在起作用,其实也可以合为一个pod而使用daemonset部署, 只不过需要分为数据面+控制面,而且kong后续打算向serviceMesh演进, 因此proxy使用daemonset部署, controller使用deployment部署
理解这个就比较容易从nginx ingress controller区分开来了
这里要指出的是,ingress是kubernetes里面的属性,而nginx与kong只是其中的两种实现.
当kong部署起来之后,即可当做是ingress controller使用了, 下面举个例子.
Kong ingress controller Example
1 | apiVersion: extensions/v1beta1 |
测试:
curl test.local.xyz:8000/api/auth/currentUser
在出现404,从打印出来的路由可以看到,path变成了/atuh/currentUser,源path为/api/auth/current, 这是为什么呢?
添加kongIngress
1 | apiVersion: configuration.konghq.com/v1 |
然后将该kongIngress添加到ingress的annotations中
1 | apiVersion: extensions/v1beta1 |
再次访问就没有404的问题了,使用了kong ingress controller的版本为0.5, 我不知道是不是哪里出了问题,我感觉不应该会出现这种情况, 默认情况下,proxy应该是原封不动地转发path, 在controller 0.5的版本下一直没有成功, 不知道是不是因为版本有点旧,giithub上也没有找到相应的说明
当然,在最新版的kong ingress controller默认是直接转发path,不会做处理,如果需要分隔path,也可以直接在ingress中直接添加以下的annotation
konghq.com/strip-path: "true"
当然也可以使用kongIngress,指定strip_path: true
即可,参考konghqcomstrip-path
konga
konga是kong的admin的封装, 可以可视化的对service,route,upstream等对象进行管理, 非常方便.
部署
1 | apiVersion: extensions/v1beta1 |
kubectl apply -f konga.yaml
发布到集群中即可.
配置
Name: 这里填写一个独一无二的名字
Kong Admin URL: 为kong的8001监听地址
创建连接之后konga就与kong建立了连接,可以通过konga进行对象的操作了
页面化的操作往往屏蔽了很多细节,因此建议作为辅助工具使用.
参考文章:
- https://izsk.me/2019/07/27/Kubernetes-ingress-nginx/
- https://github.com/Kong/kubernetes-ingress-controller/blob/main/README.md
- https://github.com/Kong/kubernetes-ingress-controller/blob/main/docs/references/annotations.md#konghqcomstrip-path
- https://github.com/Kong/kubernetes-ingress-controller/blob/main/docs/concepts/deployment.md