插件
lua-nginx-module使得nginx有了lua脚本的能力,也就从nginx到了OpenResty,Kong是lua应用,加载、执行lua模块。Kong中plugin通过 Plugin Development Kit(PDK)来与request/response对象交互。
从lua可以进一步引申到编译原理上
插件所需要的module
complete-plugin
├── api.lua 定义Admin API可以访问的接口
├── daos.lua 定义DAO,用于访问数据库
├── handler.lua 必须,定义在nginx处理请求的生命周期(阶段)被调用的接口
├── migrations 定义数据迁移,通常与DAO连用
│ ├── init.lua
│ └── 000_base_complete_plugin.lua
└── schema.lua 必须,定义该插件配置的schema
handler
先来看看handler,这些handler是与nginx http模块的13个phase结合的,这里只整理几个关注,原文:
Http Module相关的函数
Function name | Phase | Description |
init_worker | init_worker | Nginx woker启动时执行 |
rewrite | rewrite | 客户端每个request重写阶段调用,这是用Service与Consumer都没有被识别 |
access | access | 客户度每个request被转发给上游服务之前调用 |
response | access | 从上游服务接收到整个response之后,返回给客户端之前调用 |
header_filter | header_filter | 从上游服务接收完response header之后调用 |
body_filter | body_filter | 每次从上游服务接收到response body体的chunk之后调用,当reponse的body大,有多个chunk时会调用多次 |
log | log | 当最后一个reponse发送给客户端时调用 |
response与header_filter、body_filter不能联用
这些函数可以在不同的文件(Module)里,
-- handler.lua
local access = require "kong.plugins.my-custom-plugin.access"
local body_filter = require "kong.plugins.my-custom-plugin.body_filter"
local CustomHandler = {
VERSION = "1.0.0",
PRIORITY = 10
}
CustomHandler.access = access
CustomHandler.body_filter = body_filter
return CustomHandler
-- access.lua
return function(self, config)
kong.log("access phase")
end
-- body_filter.lua
return function(self, config)
kong.log("body_filter phase")
end
DAO
原文
所有Kong中的Entity需要有:
- 一个schema,用于定义与数据库相关联的对象
- 一个DAO,定义对数据库的操作
核心的DAO对象,用它们可以直接操作数据库:
local services = kong.db.services
local routes = kong.db.routes
local consumers = kong.db.consumers
local plugins = kong.db.plugins
示例:
local inserted_service, err = kong.db.services:insert({
name = "mockbin",
url = "http://mockbin.org",
})
local inserted_plugin, err = kong.db.plugins:insert({
name = "key-auth",
service = inserted_service,
})
这里是对kong提供的表进行操作,如果要对自定义的表操作需要:
- 通过migration定义表结构
- 通过schema定义使用entity
- 通过dao访问数据库
详细内容见:原文
缓存
这里的缓存并不是访问redis,而是与spring-cache类似,对数据库对象在内存中缓存,用于加快访问的速度。
缓存有2个层次:
- L1:worker层,即只在这个woker中缓存
- L2:Shared memory chache,整个nginx 节点缓存
定义entity时就可以开启缓存
local cache = kong.cache
常用的函数如下:
Function Name | Desiciption |
value, err = cache:get(key, opts?, cb, ...) | 获取数据 |
cache:invalidate(key) | 从整个node中删除 |
cache:purge() | 删除全部值 |
详细内容见:原文
实践
https://www.bilibili.com/video/BV1i44y1q7df/?spm_id_from=333.337.search-card.all.click&vd_source=928c39982102f8db90201a966f230931
https://tech.aufomm.com/use-custom-plugins-with-kong/#Lua-Plugin
插件的安装方式
- 写插件:handler.lua、schema.lua等文件
- 拷贝到
/usr/local/share/lua/5.1/kong/plugins/
目录下
- 修改环境变量
KONG_PLUGINS="bundled,kong-jwt2header
使用Dockfile自定义插件
-
docker file
FROM kong:2.4-alpine
USER root
RUN mkdir /usr/local/share/lua/5.1/kong/plugins/kong-jwt2header
COPY --from=builder /jwt2header/plugin/. /usr/local/share/lua/5.1/kong/plugins/kong-jwt2header
USER kong
-
打镜像
docker build --no-cache -t kong-demo .
-
运行
docker run -d --name kong-demo \
-p "8000-8001:8000-8001" \
-e "KONG_ADMIN_LISTEN=0.0.0.0:8001" \
-e "KONG_PROXY_LISTEN=0.0.0.0:8000" \
-e "KONG_DATABASE=off" \
-e "KONG_PLUGINS=bundled,kong-jwt2header" \
kong-demo
使用yaml方式配置Kong
这种方式只使用与DB-LESS模式,有DB时是不适用的,https://duyanghao.github.io/kong-usage/,https://news.ycombinator.com/item?id=19504480。对我们来说,DB-LESS方式更方便一些,一来配置比较少,二来方便部署与维护。
-
test.yaml
_format_version: "2.1"
_transform: true
services:
- name: first-demo
url: https://httpbin.org/anything
routes:
- name: first-demo-route
paths:
- /demo
- name: second-demo
url: https://mockbin.org/request
routes:
- name: second-demo-route
headers:
x-kong-jwt-claim-demo:
- test
paths:
- /demo
plugins:
- config:
strip_claims: "false"
token_required: "false"
enabled: true
name: kong-jwt2header
-
通过config导入到kong
curl -X POST http://localhost:8001/config -F config=@test.yaml
-
测试
curl http://localhost:8000/demo
通过lua插件连接redis
https://blog.csdn.net/u012246511/article/details/107964551
在request中add_headerhttps://docs.konghq.com/gateway/3.1.x/plugin-development/pdk/kong.service.request/#kongservicerequestset_headerheader-value
确认脚本
curl http:/192.168.31.231:8000/auth/api/user/test --header "Authorization:TEST-TOKEN-HEADER13370579617"
curl -X POST http://192.168.31.231:8000/auth/api/user/login --header "Content-Type: application/json" -d "{"phone":"13370579617","password":"123456"}"
官网拾遗
-
Kong的访问安全:Access Control,还有一种是不对外暴露访问端口,只在那台机器上调用。
-
Kong的配置文件:/etc/kong/kong.config
-
代理静态网站:通过配置nginx来实现,详情
-
通过Promethues进行监控,安装插件,配置Promethues来取详情
-
链路追踪:详情 Zipkin plugin,进行router、http_client的追踪
-
资源建议:详情,基线,参考延时(latency)与吞度量(throughput)。kong将数据库当成配置中心,只在启动与变动时读取配置。当然配置修改时,也会写库。
-
日志:日志的配置与静态网站的代理类似,也是通过nginx的配置来实现的,详情
迁移一下Kong延伸出的:网络攻击、流控算法