Kong是Mashape开源的高性能高可用API网关和API服务管理层。自2015年在github开源后,广泛受到关注。它基于OpenResty,进行API管理,并提供了插件实现API的AOP。Kong 的插件机制是其高可扩展性的根源,Kong 可以很方便地为路由和服务提供各种插件,网关所需要的基本特性。Kong支持特性:
云原生: 与平台无关,Kong可以从裸机运行到Kubernetes
动态路由: Kong 的背后是 OpenResty+Lua,所以从 OpenResty 继承了动态路由的特性
熔断
健康检查
日志: 可以记录通过 Kong 的 HTTP,TCP,UDP 请求和响应。
鉴权: 权限控制,IP 黑白名单,同样是 OpenResty 的特性
SSL: Setup a Specific SSL Certificate for an underlying service or API.
监控: Kong 提供了实时监控插件
认证: 如数支持 HMAC, JWT, Basic, OAuth2.0 等常用协议
限流
REST API: 通过 Rest API 进行配置管理,从繁琐的配置文件中解放
可用性: 天然支持分布式
高性能: 背靠非阻塞通信的 nginx,性能自不用说
插件机制: 提供众多开箱即用的插件,且有易于扩展的自定义插件接口,用户可以使用 Lua 自行开发插件
要理解kong,我们需要先了解几个核心组件的概念。
- Route :请求的转发规则,按照Hostname和PATH,将请求转发给Service,Kubernetes的Ingress中每个path对应一个Route。
- Services :多个Upstream的集合,是Route的转发目标。
- Consumer :API的用户,记录用户的一些信息,里面可以对该用户配置认证的信息。
- Plugin :插件,plugin可以是全局的,也可以绑定到Service,绑定到Router,绑定到Consumer。
- Certificate :https证书。
下面我们通过docker 安装kong和kong的管理项目konga,然后配置一个路由转发请求。
1. 安装kong
创建网络
docker network create kong-net
为kong创建pg数据库
docker pull postgres:9.6
docker run -d \
--name kong-database \
--network=kong-net \
-v /data/postgresql:/var/lib/postgresql/data \
-p 5432:5432 \
-e "POSTGRES_USER=kong" \
-e "POSTGRES_DB=kong" \
-e "POSTGRES_PASSWORD=kong" \
postgres:9.6
拉取kong镜像
docker pull kong:2.1.4
初始化kong数据库
docker run --rm --network=kong-net \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_PG_USER=kong" \
-e "KONG_PG_PASSWORD=kong" \
-e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
kong:2.1.4 kong migrations bootstrap
启动kong容器
docker run -d \
--name kong \
--network=kong-net \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_PG_PASSWORD=kong" \
-e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
-e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
-e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
-e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
-e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
-e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl" \
-p 8000:8000 \
-p 8443:8443 \
-p 8001:8001 \
-p 8444:8444 \
kong:2.1.4
2. konga
当前KONG的社区版是没有dashboard的,但是付费的企业版是有带的,并且还有一些企业版才能使用的插件以及升级后的企业版插件。所以对于使用社区版的用户而言,排除自己去撸一个dashboard的这种选择,第三方开源的dashboard无疑是首选。当前GitHub上还在更新维护的dashboard有三个,分别是kong-dashboard,kongdash 和 konga。
说道Kong的管理GUI,网上说的比较多的都是kong-dashboard,但目前最新版(v3.6.0)似乎并未支持最新版本的Kong。而目前在github能找到star比较多的就是konga了。konga不仅支持了Kong的最新版本(service和route的拆分新特性)同时支持管理员的权限控制和多个Kong连接池的管理。Konga由于自带了用户权限控制和Kong连接池管理,所以需要一些数据持久化处理。默认支持的数据库有mongodb、postgres、mysql。这里我们选择的是PostgresSQL,原因是KONG连接的数据库也是PGSQL,这样可以减少数据库的部署。
Konga 安装
拉取konga镜像
docker pull pantsel/konga:0.14.9
启动konga
docker run -d \
-p 1337:1337 \
--network kong-net \
-e "TOKEN_SECRET=kongtoken" \
-e "DB_ADAPTER=postgres" \
-e "DB_HOST=kong-database" \
-e "DB_USER=kong" \
-e "DB_PASSWORD=kong" \
--name konga \
pantsel/konga:0.14.9
启动成功后,访问 http://ip:1337 访问konga
创建管理员账户
第一次进入页面, 将会提示我们创建个管理员账户
创建连接
我们需要新建kong的管理连接,连接的url可以使用前面创建的网络 kong-net,我们通过该网络的内部DNS直接就可以访问kong了。这里的url使用 http://kong:8001 , 其中 kong 是容器名
3. 配置一个转发的例子
我们将使用优秀的在线虚假API(由typicode提供的)进行测试和原型设计 ,具体可以参考 官网 。
Konga操作
(1)添加一个服务
我们添加一个服务名为 json-placeholder 的服务, 该服务的URL是 https://jsonplaceholder.typicode.com
属性
描述
name(必填)
服务名称.
tags(可选)
可选地向服务添加标记
url(可选)
将协议、主机、端口和路径立即设置成简短的属性。这个属性是只写的(管理API从来不“返回”url)
protocol(必填)
该协议用于与upstream通信。它可以是http(默认)或https。
host(必填)
upstream服务器的主机。
port(必填)
upstream服务器端口。默认为80
path(可选)
在向upstream服务器请求中使用的路径。默认为空。
retries(可选)
在代理失败的情况下执行的重试次数。默认值是5。
connect_timeout(可选)
建立到upstream服务器的连接的超时时间。默认为60000。
write_timeout(可选)
将请求发送到upstream服务器的两个连续写操作之间的超时时间。默认为60000。
read_timeout(可选)
将请求发送到upstream服务器的两个连续读取操作之间的超时时间。默认为60000。
(2)添加路由
点击服务 ,进入页面添加一个路由,把请求转发到上面 json-placeholder 服务上。我们这里对来自任何域名(如果只是响应某个域名,需要在路由中配置host)的请求都做响应,匹配该请求的path为/posts。strip path设置为false,这里在转发到后端服务的时候不会对请求URI进行截取。
字段说明:
属性
描述
name(可选)
定义名称
tags(可选)
向路由添加标记
protocols(可选)
这条路线应该允许的协议列表。默认情况下,它是“http”、“https”,这意味着路由接受这两种方式。当设置为“HTTPS”时,HTTP请求会被请求升级到HTTPS。通过表单编码,符号是协议=http&协议=https。使用JSON,使用数组。
methods(半可选)
与此路由相匹配的HTTP方法列表。例如: ["GET", "POST"].至少有一个主机、路径或方法必须被设置。用表单编码参数是methods[]=GET&methods[]=OPTIONS。使用JSON,使用数组。
hosts(半可选)
与此路径匹配的域名列表。例如:example.com. 至少有一个主机、路径或方法必须被设置。用表单编码参数是 hosts[]=foo.com&hosts[]=bar.com。使用JSON,使用数组。
paths(半可选)
与此路径相匹配的路径列表。例如: /my-path.至少有一个主机、路径或方法必须被设置。用表单编码参数是 paths[]=/foo&paths[]=/bar. 使用JSON,使用数组。
Regex priority(可选)
当多个路由同时使用正则表达式匹配某个给定请求时,用来选择哪个路由解析该请求的数字。当两个路由匹配路径并且具有相同的regex_优先级时,将使用较旧的路由(最低创建位置)。注意,非regex路由的优先级不同(较长的非regex路由在较短的路由之前匹配)。默认为0。
strip_path(可选)
当通过其中一条路径匹配路由时,从上游upstream请求URL中去掉匹配前缀。默认值为true。
preserve_host(可选)
当通过一个主机域名匹配一条路由时,在upstream请求头中使用请求主机头。默认设置为false,upstream主机头将是服务主机的主机头。
添加成功,我们可以发出请求到地址 http://yourip:8000/posts/1 , 该请求将会转发到 http://jsonplaceholder.typicode.com/posts/1 。这里的ip地址是kong的地址,8000是kong对外服务的端口