使用平台:Ubuntu 20.04使用软件:kong-enterprise-edition-3.3.1.0.amd64.deb
plugin模板:git clone https://github.com/Kong/kong-plugin.git
参考文档:https://docs.konghq.com/gateway/3.3.x/plugin-development/
参考文章:https: //zhuanlan.zhihu.com/p/52402537、https://segmentfault.com/a/1190000039683513
以下步骤假设你已经了解到如何安装kong网关和数据库,如何使用kong网关进行代理转发
1.plugin文件结构
基本结构
simple-plugin ├── handler.lua └── schema.lua
- handler.lua 插件的核心,可以定义一些在请求的各个声明周期运行的函数。
- schema.lua 插件的一些配置信息。比如可以配置哪些字段,默认值,校验之类的
- 高级结构
如果需要更加深度的和 kong 进行集成,比如在 kong 的数据库中有自己的表,在 Admin API 中有自己的管理断点等等。还有一些其他可以定义的文件。
complete-plugin
├── api.lua
├── daos.lua
├── handler.lua
├── migrations
│ ├── cassandra.lua
│ └── postgres.lua
└── schema.lua
api.lua | No | Defines a list of endpoints to be available in the Admin API to interact with the custom entities handled by your plugin. |
---|---|---|
daos.lua | No | Defines a list of DAOs (Database Access Objects) that are abstractions of custom entities needed by your plugin and stored in the data store. |
handler.lua | Yes | An interface to implement. Each function is to be run by Kong at the desired moment in the lifecycle of a request / connection. |
migrations/*.lua | No | The database migrations (e.g. creation of tables). Migrations are only necessary when your plugin has to store custom entities in the database and interact with them through one of the DAOs defined by daos.lua. |
schema.lua | Yes | Holds the schema of your plugin’s configuration, so that the user can only enter valid configuration values. |
- 模块名称
"kong.plugins.<plugin_name>.<module_name>"
2.插件开发
我们开发一个简单的插件 Demo,对每个请求添加一个 uuid 叫 my-uuid,添加的 header 我们可以自己在插件的配置中定义(Kong 实际已经自带了一个类似的插件
下载kong的插件模板
git clone https://github.com/Kong/kong-plugin.git #以上步骤是一个参考,这里我们徒手开发 #创建插件目录my-uuid mkdir my-uuid #cd my-uuid,创建并编辑handler.lua,内容如下
local uuid = require "kong.tools.utils".uuid
local MyUUIDHandler = {}
MyUUIDHandler.PRIORITY = 1
MyUUIDHandler.VERSION = "0.1.0"
function MyUUIDHandler:access(conf)
-- Set header for upstream
local trace_id = kong.request.get_header(conf.header_name)
if not trace_id or trace_id == "" then
-- Generate the header value
trace_id = uuid()
if trace_id then
kong.service.request.set_header(conf.header_name, trace_id)
end
end
kong.ctx.plugin.trace_id = trace_id
end
function MyUUIDHandler:header_filter(conf)
local trace_id = kong.ctx.plugin.trace_id or
kong.request.get_header(conf.header_name)
if not trace_id or trace_id == "" then
trace_id = uuid()
end
kong.response.set_header(conf.header_name, trace_id)
end
return MyUUIDHandler
#创建并编辑schema.lua
local typedefs = require "kong.db.schema.typedefs"
return {
name = "my-uuid",
fields = {
{
consumer = typedefs.no_consumer
},
{
config = {
type = "record",
fields = {
{ header_name = { type = "string", required = true }, },
},
},
},
},
}
## 3.安装插件
新建rockspec文件,Lua模块的包管理器 [LuaRocks]
#cd ../ 创建kong-plugin-my-uuid-0.1.0-1.rockspec package = "kong-plugin-my-uuid" version = "0.1.0-1" local pluginName = package:match("^kong%-plugin%-(.+)$") supported_platforms = {"linux", "macosx"} source = { url = "https://gitxxxxxx.com/xxxx/kong-plugins", tag = "0.1.0" } description = { summary = "Add uuid in request/response header" } dependencies = {} build = { type = "builtin", modules = { ["kong.plugins."..pluginName..".handler"] = pluginName.."/handler.lua", ["kong.plugins."..pluginName..".schema"] = pluginName.."/schema.lua", } }
使用命令
sudo luarocks make
编译安装插件,编译完显示"kong-plugin-my-uuid 0.1.0-1 is now installed in /usr/local "
4.加载插件
- 编辑kong.conf 文件,找到plugins参数,修改为
plugins = bundled,my-uuid
- 重启kong网关
sudo kong restart
- 检查my-uuid插件是否加载
curl http://localhost:8001|grep my-uuid
验证插件
启用插件
首先我们新建一个API 服务叫
mockbin
,上游地址是http://mockbin.org/bin/xxxxx-79b5-4eb9-9558-c3bc57b7bf48
。网关上绑定其路由为/mockbin/v1
。
这样我们访问http://${网关 IP}:${端口}/mockbin/v1
就可以直接被代理到上游的服务http://mockbin.org//bin/xxxxx-79b5-4eb9-9558-c3bc57b7bf48
上。
将my-uuid
插件绑定到该服务中,并且设置 uuid 的 header 名称为 my-trace-id
请求网关地址 http://${网关 IP}:${端口}/mockbin/v1/instances
5. 参考
这里kong使用了lua的框架Lapis,参考 https://leafo.net/lapis/
6. konga的显示设置
/usr/local/share/lua/5.1/kong/constants.lua
修改此文件的主要目的是为了让自定义插件在konga 界面上显示,如果不用ui管理界面可以忽略。
local plugins = {
"jwt",
"acl",
"correlation-id",
"cors",
"oauth2",
"tcp-log",
"udp-log",
"file-log",
"http-log",
"key-auth",
"hmac-auth",
"basic-auth",
"ip-restriction",
"request-transformer",
"response-transformer",
"request-size-limiting",
"rate-limiting",
"response-ratelimiting",
"syslog",
"loggly",
"datadog",
"ldap-auth",
"statsd",
"bot-detection",
"aws-lambda",
"request-termination",
"prometheus",
"proxy-cache",
"session",
"acme",
"grpc-gateway",
"grpc-web",
"pre-function",
"post-function",
"azure-functions",
"zipkin",
"demo", ## 此项为我的自定义插件
}