1. kong简介

Kong是一款基于OpenResty(Nginx + Lua模块)编写的高可用、易扩展的,由Mashape公司开源的API Gateway项目。Kong是基于NGINX和Apache Cassandra或PostgreSQL构建的,能提供易于使用的RESTful API来操作和配置API管理系统,所以它可以水平扩展多个Kong服务器,通过前置的负载均衡配置把请求均匀地分发到各个Server,来应对大批量的网络请求。
具体介绍参考

2. kong安装配置

1. 下载安装(以centos 6为例,其他平台见链接

下载rpm包

1
https://bintray.com/kong/kong-rpm/download_file?file_path=centos/6/kong-1.1.2.el6.noarch.rpm
1
2
sudo yum install epel-release
sudo yum install kong-1.1.2.*.noarch.rpm --nogpgcheck

2. 配置/etc/kong/kong.conf

需要修改postgres的配置

1
2
3
4
5
6
7
pg_host = hjapp25.add.bjyt.qihoo.net            # Host of the Postgres server.
pg_port = 5432 # Port of the Postgres server.

pg_user = kong # Postgres user.
pg_password = kong # Postgres user's password.
pg_database = kong # The database name to connect to.

3. 初始化启动

初始化数据库

1
kong migrations bootstrap [-c /etc/kong/kong.conf]

启动kong

1
kong start [-c /etc/kong/kong.conf]

3. kong-adminAPI

方法1 -通过api

  1. 本地调用localhost:8001/service

方法2 -通过后台

  1. 配置kong.conf
1
admin_listen=0.0.0.0:8001

然后重启kong
2. 通过konga后台链接(自行搭建,这里是在k8s上搭建,创建一个service,指向localhost:8001
4. 创建对应routes,可自定义,例如path[] = /admin-api
5. 添加认证插件,例如jwt,key-auth等
6. 创建consumer,并声称对应认证信息
7. 配置connection,按照对应认证信息配置成kong:8000/admin-api
8. 最后修改kong.conf,改回localhost:8001,重启即可

3. kong插件使用

1. 插件简介

kong的插件功能很多,其内置了很多包括认证,限流,日志等相关插件,当然也可以自定义插件,加载成功后就可以在这个界面进行添加使用(konga是kong的一个免费dashboard)
1557221554453.jpg
点击add
kong插件列表.jpg

不同的插件有不同的参数,需要进行设定,设定完成后就会启用
例如–这是内置的key-auth插件,作用是进行api认证,设定key之后只有认证通过的才能访问

2. . kong插件开发和部署

参考

1. tree

base

1
2
3
simple-plugin
├── handler.lua
└── schema.lua

advanced

1
2
3
4
5
6
7
8
complete-plugin
├── api.lua
├── daos.lua
├── handler.lua
├── migrations
│ ├── cassandra.lua
│ └── postgres.lua
└── schema.lua

必要文件就是handler.lua和schema.lua

2. handler.lua

这个文件有很多函数,自定义逻辑就是在这些函数中写
kong会在一些特定阶段调用对应的函数
参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
local BasePlugin = require "kong.plugins.base_plugin"

-- The actual logic is implemented in those modules
local access = require "kong.plugins.my-custom-plugin.access"
local body_filter = require "kong.plugins.my-custom-plugin.body_filter"

local CustomHandler = BasePlugin:extend()

function CustomHandler:new()
CustomHandler.super.new(self, "my-custom-plugin")
end

function CustomHandler:access(config)
CustomHandler.super.access(self)

-- Execute any function from the module loaded in `access`,
-- for example, `execute()` and passing it the plugin's configuration.
access.execute(config)
end

function CustomHandler:body_filter(config)
CustomHandler.super.body_filter(self)

-- Execute any function from the module loaded in `body_filter`,
-- for example, `execute()` and passing it the plugin's configuration.
body_filter.execute(config)
end

return CustomHandler

3. schame.lua

主要是配置一些参数,以及参数检查
参考

1
2
3
4
5
6
7
8
9
10
return {
no_consumer = true, -- this plugin will only be applied to Services or Routes,
fields = {
-- Describe your plugin's configuration's schema here.
},
self_check = function(schema, plugin_t, dao, is_updating)
-- perform any custom verification
return true
end
}

4. 配置部署

比如以上插件文件在

1
/data/kong/plugins/simple-plugin/

则配置kong.conf

1
2
lua_package_path = /data/?.lua;($default);
plugins = bundled,simple-plugin

然后重新reload kong
如果lua插件没有错误,就可以在后台看到加载出来了

5. 示例插件开发

同一个kong集群,按照机房进行分配请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
local BasePlugin = require "kong.plugins.base_plugin"
local plugin = BasePlugin:extend()

-- 插件构造函数
function plugin:new()
plugin.super.new(self, "first")
end

function split(input, delimiter)
input = tostring(input)
delimiter = tostring(delimiter)
if (delimiter=='') then return false end
local pos,arr = 0, {}
for st,sp in function() return string.find(input, delimiter, pos, true) end do
table.insert(arr, string.sub(input, pos, st - 1))
pos = sp + 1
end
table.insert(arr, string.sub(input, pos))
return arr
end

function plugin:access(plugin_conf)
plugin.super.access(self)
local socket = require('socket')
local host = kong.request.get_host()
local hostName = socket.dns.gethostname() --本机名
local list = split(hostName,'.')
local hostroom = list[3]
local ok, err = kong.service.set_upstream(hostroom)
if not ok then
kong.log.err(err)
return
end
end
return plugin