notes

Kong

前言

目前我使用kong主要是由于以下几点

kong需要一个数据库,用来保存用户配置的数据,我们这边使用PostgreSQL

kong

kong对外提供了四个端口

部署 Kong 和 PostgreSQL

我们使用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

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.1localhost,因为大家都在docker里面,要填局域网地址。

配置api转发接口

选中 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字段。