Kong - 插件开发
环境:
kong 是用 rpm 方式安装的。 LuaRocks as it is installed along with Kong
[root@localhost kong-plugin-huidu-master]# luarocks --version
/usr/local/bin/luarocks 3.7.0
[root@localhost kong-plugin-huidu-master]# kong version
2.4.1
[root@localhost kong-plugin-huidu-master]# luarocks path --lr-path
/root/.luarocks/share/lua/5.1/?.lua;/root/.luarocks/share/lua/5.1/?/init.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua
一、下载Kong插件开发模板
下载官方插件开发模板:
git clone https://github.com/Kong/kong-plugin.git
kong插件主要有三个文件:
handler.lua 是包含插件逻辑处理相关代码。 schema.lua 包含插件的配置文件。 rockspec 文件是通过luarock安装时用的配置文件。
逻辑处理的代码根据openresty的不同处理阶段分成了不同的函数,根据插件的功能只需要在不同的函数中添加自己的业务逻辑
二、kong插件开发实践
下面是开发一个最简单的灰度发布使用的流量分发插件的全部流程。
这个插件的功能非常简单:
根据http request头中的Authorization的值将流量分发到不同的后端服务器。
插件有两个配置项:pattern和upstream,如果Authorization的值匹配pattern,那么当前请求会被代理到相应的upstream中。
2.1、代码开发
给插件起个温暖的名字,就叫huidu吧,修改模版项目中的目录名为huidu。
mv kong-plugin kong-plugin-huidu
cd kong-plugin-huidu/kong/plugins
mv myplugin huidu
修改schema.lua文件,添加插件配置代码:
local typedefs = require "kong.db.schema.typedefs" -- Grab pluginname from module name local plugin_name = ({...})[1]:match("^kong%.plugins%.([^%.]+)") local schema = { name = plugin_name, fields = { -- the 'fields' array is the top-level entry with fields defined by Kong { consumer = typedefs.no_consumer }, -- this plugin cannot be configured on a consumer (typical for auth plugins) { protocols = typedefs.protocols_http }, { config = { -- The 'config' record is the custom part of the plugin schema type = "record", fields = { -- a standard defined field (typedef), with some customizations { pattern = {type = "string", required = true, default = "^a" } }, { upstream = {type = "string", required = true, default = "hello" } } -- adding a constraint for the value }, entity_checks = { -- add some validation rules across fields -- the following is silly because it is always true, since they are both required { at_least_one_of = { "pattern", "upstream" }, }, -- We specify that both header-names cannot be the same { distinct = { "pattern", "upstream"} }, }, }, }, }, } return schema
修改handler.lua文件,添加插件处理逻辑:
-- If you're not sure your plugin is executing, uncomment the line below and restart Kong -- then it will throw an error which indicates the plugin is being loaded at least. --assert(ngx.get_phase() == "timer", "The world is coming to an end!") -- Grab pluginname from module name local plugin_name = ({...})[1]:match("^kong%.plugins%.([^%.]+)") -- load the base plugin object and create a subclass local plugin = require("kong.plugins.base_plugin"):extend() -- constructor function plugin:new() plugin.super.new(self, plugin_name) -- do initialization here, runs in the 'init_by_lua_block', before worker processes are forked end ---[[ runs in the 'access_by_lua_block' function plugin:access(plugin_conf) plugin.super.access(self) -- your custom code here local pattern = plugin_conf.pattern local token = kong.request.get_header("authorization") if token == nil then return end -- 忽略大小写 local matched = ngx.re.match(token, pattern, "joi") if matched then -- 设置upstream local ok, err = kong.service.set_upstream(plugin_conf.upstream) if not ok then kong.log.err(err) return end -- 匹配成功添加特定头部方便监控 ngx.req.set_header("X-Kong-" .. plugin_name .. "-upstream", plugin_conf.upstream) ngx.req.set_header("X-Kong-" .. plugin_name .. "-pattern", plugin_conf.pattern) end end --]] -- set the plugin priority, which determines plugin execution order plugin.PRIORITY = 1000 -- return our plugin object return plugin
huidu插件的逻辑只需要在access阶段执行就可以,可以把多余的注释和代码删掉。
2.4、安装调试
修改kong.conf文件,添加或者修改下面的配置项。注意 插件名称和安装时的名称一致
插件一般通过 luarocks 来安装,在插件根目录下执行:
luarocks make
此编译命令依靠文件 rockspec,
ackage = "kong-plugin-huidu" -- TODO: rename, must match the info in the filename of this rockspec! -- as a convention; stick to the prefix: `kong-plugin-` version = "0.1.0-1" -- TODO: renumber, must match the info in the filename of this rockspec! -- The version '0.1.0' is the source code version, the trailing '1' is the version of this rockspec. -- whenever the source version changes, the rockspec should be reset to 1. The rockspec version is only -- updated (incremented) when this file changes, but the source remains the same. -- TODO: This is the name to set in the Kong configuration `plugins` setting. -- Here we extract it from the package name. local pluginName = package:match("^kong%-plugin%-(.+)$") -- "myPlugin" supported_platforms = {"linux", "macosx"} source = { url = "https://github.com/chenyoufu/kong-plugin-huidu.git", tag = "0.1.0" } description = { summary = "Kong is a scalable and customizable API Management Layer built on top of Nginx.", homepage = "http://getkong.org", license = "Apache 2.0" } dependencies = { } build = { type = "builtin", modules = { -- TODO: add any additional files that the plugin consists of ["kong.plugins."..pluginName..".handler"] = "kong/plugins/"..pluginName.."/handler.lua", ["kong.plugins."..pluginName..".schema"] = "kong/plugins/"..pluginName.."/schema.lua", } }
安装成功后,插件安装在了luarocks目录kong->plugins 。然后重启kong
kong start -c kong.conf --vv
从Konga可以看到插件安装成功了:
注意:另外一种安装方式 直接修改文件方法参考:
所有插件在 /usr/local/share/lua/5.1/kong/constants.lua
插件具体位置在/usr/local/share/lua/5.1/kong/plugins
直接复制插件handler\schema到plugins目录,然后加到bundle里面,重启kong即可。
参考:https://www.freesion.com/article/33481210612/
2.5、测试
使用web管理界面konga来配置插件。创建一个service,然后在service下安装当前插件
配置项表示以a开头的全部流量走mocktest,如果没有匹配或者插件代码有错误,那么流量就走service本身配置的upstream。
curl -X GET 'http://127.0.0.1:8000/request?foo=bar&foo=baz' -H 'authorization: ApwPYjA8J1c9CVaFIBVkRyYV57k2bXfHFH9Jojs8HN2FfyEn39MzV1afG9'
curl -X GET 'http://127.0.0.1:8000/request?foo=bar&foo=baz' -H 'authorization: XApwPYjA8J1c9CVaFIBVkRyYV57k2bXfHFH9Jojs8HN2FfyEn39MzV1afG9'
不返回信息
如果插件中有语法错误,重启会失败,可以查阅日志找问题,日志位置在/usr/local/kong/logs/error.log
注意:
kong 插件只要编译了,就会执行对应的生命周期,不论kong是否添加改插件。
参考:
https://docs.konghq.com/gateway-oss/0.14.x/plugin-development/custom-logic/
https://docs.konghq.com/gateway-oss/0.14.x/pdk/
https://github.com/Kong/kong/blob/master/kong/plugins/tcp-log/handler.lua
https://www.jianshu.com/p/3e726106dca9?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation
posted on 2022-03-01 19:13 TrustNature 阅读(1614) 评论(0) 编辑 收藏 举报