Kong API网关使用入门

介绍

Kong是一个可扩展的开源API网关, 基于OpenResty(lua-nginx-module)开发, 底层使用Apache Cassandra或PostgreSQL数据库,运行在任何RESTful API的前面,并通过插件扩展,开发者可以方便的添加已定义的插件,甚至可以自己开发插件并使用,来达到代理、负载均衡、健康检查、日志、登录等功能。

kong

Kong主要有三个组件:

  • Kong Server :基于nginx的服务器,用来接收API请求。
  • Cassandra/PostgreSQL :用来存储数据。
  • Kong dashboard:官方推荐UI管理工具,当然,也可以使用 restfull 方式 管理admin api

安装部署

Kong官方提供了各平台/系统的安装文档,推荐用Docker来进行安装部署。

创建Docker网络

Kong Server依赖Cassandra/PostgreSQL数据库,便于容器之间通信,先创建一个docker网络。

1
docker network create kong-net

安装启动postgresSQL

1
2
3
4
5
6
docker run -d --name kong-database \
--network=kong-net \
-p 5432:5432 \
-e "POSTGRES_USER=kong" \
-e "POSTGRES_DB=kong" \
postgres:9.6

导入数据

1
2
3
4
5
6
docker run --rm \
--network=kong-net \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
kong:latest kong migrations bootstrap

安装启动Kong

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
docker run -d --name kong \
--network=kong-net \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-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:latest

Kong默认监听下面端口:

  • 8000:监听来自客户端的HTTP流量,转发到你的upstream服务上
  • 8443:监听HTTPS的流量,功能跟8000一样。可以通过配置文件禁止
  • 8001:Kong的HTTP监听的api管理接口
  • 8444:Kong的HTTPS监听的API管理接口

安装Kong Admin-UI

Kong暴露了一个RESTful管理Api在8001端口上,Kong的配置,包括添加Service和Route,都是通过这个Api发送请求。市面上有很多基于RESTful管理API后台项目,官方的Kong dashboard在我本地安装之后,无法正常使用,推荐一个纯前端的管理后台:Kong-admin-ui

1
docker run -d --name kong-admin-ui -p 8899:80 pocketdigi/kong-admin-ui:0.4.0

kong

安装完成之后,运行docker ps看一下当前运行的容器:

1
2
3
4
CONTAINER ID        IMAGE                            COMMAND                  CREATED             STATUS              PORTS                                                                NAMES
47968f8067bd pocketdigi/kong-admin-ui:0.3.2 "nginx -g 'daemon of…" 43 seconds ago Up 43 seconds 0.0.0.0:8899->80/tcp kong-admin-ui
c8096b5374f5 kong:latest "/docker-entrypoint.…" 10 minutes ago Up 10 minutes 0.0.0.0:8000-8001->8000-8001/tcp, 0.0.0.0:8443-8444->8443-8444/tcp kong
bf526e28d65a postgres:9.6 "docker-entrypoint.s…" 30 minutes ago Up 30 minutes 0.0.0.0:5432->5432/tcp

Kong配置

安装完成各项服务之后,我们就可以通过RESTful管理Api配置服务/路由/插件,因为可视化操作相对直观,这里推荐使用管理后台进行。

添加服务

RESTful接口

1
2
3
4
curl -i -X POST \
--url http://localhost:8001/services/ \
--data 'name=example-service' \
--data 'url=http://mockbin.org'

返回数据格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
HTTP/1.1 201 Created
Content-Type: application/json
Connection: keep-alive

{
"host":"mockbin.org",
"created_at":1519130509,
"connect_timeout":60000,
"id":"92956672-f5ea-4e9a-b096-667bf55bc40c",
"protocol":"http",
"name":"example-service",
"read_timeout":60000,
"port":80,
"path":null,
"updated_at":1519130509,
"retries":5,
"write_timeout":60000
}
Permalink

也可以通过管理后台添加:

kong

kong

为服务添加路由

添加为服务(API)配置之后,还需要给服务添加路由,让网关知道在什么情况下将请求转发给服务。

RESTful接口:

1
2
3
curl -i -X POST \
--url http://localhost:8001/services/example-service/routes \
--data 'hosts[]=example.com'

返回数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
HTTP/1.1 201 Created
Content-Type: application/json
Connection: keep-alive

{
"created_at":1519131139,
"strip_path":true,
"hosts":[
"example.com"
],
"preserve_host":false,
"regex_priority":0,
"updated_at":1519131139,
"paths":null,
"service":{
"id":"79d7ee6e-9fc7-4b95-aa3b-61d2e17e7516"
},
"methods":null,
"protocols":[
"http",
"https"
],
"id":"f9ce2ed7-c06e-4e16-bd5d-3a82daef3f9d"
}

通过管理后台操作:

kong

通过Kong转发请求

配置完服务和路由之后,就可以通过Kong来转发请求了。

1
2
3
curl -i -X GET \
--url http://localhost:8000/ \
--header 'Host: example.com'

在上面请求中,因为配置了指定的host路由,Kong会转发请求到对应的服务。

添加插件

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的插件可以看官方文档:https://docs.konghq.com/hub/

RESTful接口:

1
2
3
4
curl -X POST http://localhost:8001/services/example-service/plugins \
--data "name=rate-limiting" \
--data "config.second=5" \
--data "config.hour=10000"

这样,我们就为example-service添加了一个rate-limiting插件,该插件会依据config配置限制example-service的请求频率,当超限是就会报错:

1
2
3
{
"message": "API rate limit exceeded"
}

同样,我们也可以在管理后台操作。

kong

添加Consumer

Consumer可以理解为用户(消费者),用来标记某个用户或者某个服务。例如某个Service开启了key-auth插件,那么访问这个Service需要传入key,这个时候我们可以定义一个Consumer,给它添加一个key,这个时候通过这个key(当然key是唯一的)访问Service时,网关就可以判断是哪个Consumer发送的请求。

创建Consumer

1
2
3
curl -i -X POST \
--url http://localhost:8001/consumers/ \
--data "username=Jason"

为Consumer添加证书

1
2
3
curl -i -X POST \
--url http://localhost:8001/consumers/Jason/key-auth/ \
--data 'key=ENTER_KEY_HERE'

验证Consumer凭证

执行下面的命令,验证Consumer凭证

1
2
3
4
curl -i -X GET \
--url http://localhost:8000 \
--header "Host: example.com" \
--header "apikey: ENTER_KEY_HERE"

参考文档

有用就打赏一下作者吧!