目前我使用kong
主要是由于以下几点
kong需要一个数据库,用来保存用户配置的数据,我们这边使用PostgreSQL
。
kong对外提供了四个端口
我们使用docker-compose
部署kong服务
version: '2'
services:
kong-database:
image: postgres:9.6
container_name: kong-database
environment:
- POSTGRES_USER=kong
- POSTGRES_DB=kong
- POSTGRES_PASSWORD=kong
ports:
- 5432:5432
networks:
- kong-net
volumes:
- ./data:/var/lib/postgresql/data
kong:
image: kong:1.2.1-alpine
container_name: kong
restart: always
links:
- kong-database:kong-database
ports:
- 80:8000
- 443:8443
- 8001:8001
- 8444:8444
environment:
- KONG_DATABASE=postgres
- KONG_PG_HOST=kong-database
- KONG_PG_USER=kong
- KONG_PG_DATABASE=kong
- KONG_PG_PASSWORD=kong
- KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl
networks:
- kong-net
networks:
kong-net:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.110.0.0/16
以上是部署kong
以及postgres
服务的,networks
经过测试,最好还是写上,不会出现奇怪的错误。而且在部署konga
的时候也可以用上,里面的172.110.0.0/16
只要保证不会跟服务器的内网ip冲突就行了。
第一步,执行
docker-compose up -d
会发现启动了两个容器,postgres正常启动,但是kong会一直在retry,说明发生了错误。原因是数据库需要初始化。
第二部,执行
docker-compose run kong kong migrations bootstrap
第三步,初始化成功后,再次执行
docker-compose up -d
就成功了,会有一个kong服务监听这8000,8001,8443,8444这四个端口。
注意:以上3步必须顺序执行才能成功,因为要prepare数据库,所以prepare后还要up一下才行,github上也有一次就运行的,我还看不懂…
此时,kong已经部署好了,那怎么使用呢?就轮到konga上场了。
Konga是kong的图形化管理平台,没有konga的话只能以命令行的方式和kong交互。
启动konga
# step1. 拉镜像
docker pull pantsel/konga
# step2. 配置数据库
docker run --network=kong_kong-net --rm pantsel/konga:latest -c prepare -a postgres -u postgresql://kong:kong@kong-database/konga_database
# step3. 启动
docker run --network=kong_kong-net -p 1337:1337 -d -e "TOKEN_SECRET=xxxxxxxxxx" -e "DB_ADAPTER=postgres" -e "DB_URI=postgresql://kong:kong@kong-database/konga_database" -e "NODE_ENV=production" --name konga pantsel/konga
注:以上命令用到了前几步的network参数。
启动成功后,访问localhost:1337
进入。注册登录操作后进入kong配置页面,在输入kong的admin api的时候注意不要填127.0.0.1
或localhost
,因为大家都在docker里面,要填局域网地址。
选中 services 菜单,点击add new service
,这里填的是上游服务(upstream)的地址,代表了一个上游服务。
然后在service detial
页面中选择routers
,创建一个router,router表示的是当kong接收到什么样的请求时转发到你的service。
比如:service的配置如下:
Protocol: http
Host: 192.168.1.2
Port: 9090
Path: /
service的router配置如下:
Hosts: www.hqqsk8.com
paths: /test
protocal: ["http"]
那么转发的效果就是,当kong收到http://www.hqqsk8.com/test/users
这个请求时,会转发到http://192.168.1.2/users
这个地址。
kong自带的plugins
里面的http-log
没有返回请求参数和响应参数,这里我们修改kong源码的方式让http-log
插件带上body参数。
首先进入kong容器,查找源码文件的位置
find / -name plugins
进入插件的目录后,我们可以看到有一个http-log
的文件夹,但是我们改的不是这个,找的是log-serializers
,因为http-log
里面引用了log-serializers
,返回的log结构也是在log-serializers
里面定义的。
log-serializers
里面就一个basic.lua
文件,找到如下代码:
...
request = {
uri = request_uri,
url = var.scheme .. "://" .. var.host .. ":" .. var.server_port .. request_uri,
querystring = req.get_uri_args(), -- parameters, as a table
method = req.get_method(), -- http method
headers = req.get_headers(),
size = var.request_length,
tls = request_tls
},
...
在里面加一行body,加完后如下:
...
request = {
uri = request_uri,
url = var.scheme .. "://" .. var.host .. ":" .. var.server_port .. request_uri,
querystring = req.get_uri_args(), -- parameters, as a table
method = req.get_method(), -- http method
headers = req.get_headers(),
size = var.request_length,
body = var.request_body,
tls = request_tls
},
...
为了以后维护方便,最好还是把log-serializers
文件夹挂载出来,这样只需要restart kong容器就可以了。
注意:只有request中body有值才会显示,如果像get或者post的body没传值,日志就没有body字段。