Kong拾遗

插件

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 namePhaseDescription
init_workerinit_workerNginx woker启动时执行
rewriterewrite客户端每个request重写阶段调用,这是用Service与Consumer都没有被识别
accessaccess客户度每个request被转发给上游服务之前调用
responseaccess从上游服务接收到整个response之后,返回给客户端之前调用
header_filterheader_filter从上游服务接收完response header之后调用
body_filterbody_filter每次从上游服务接收到response body体的chunk之后调用,当reponse的body大,有多个chunk时会调用多次
loglog当最后一个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个层次:

  1. L1:worker层,即只在这个woker中缓存
  2. L2:Shared memory chache,整个nginx 节点缓存

定义entity时就可以开启缓存

local cache = kong.cache

常用的函数如下:

Function NameDesiciption
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

插件的安装方式

  1. 写插件:handler.lua、schema.lua等文件
  2. 拷贝到/usr/local/share/lua/5.1/kong/plugins/目录下
  3. 修改环境变量KONG_PLUGINS="bundled,kong-jwt2header

使用Dockfile自定义插件

  1. 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
    
  2. 打镜像

    docker build --no-cache -t kong-demo .
    
  3. 运行

    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方式更方便一些,一来配置比较少,二来方便部署与维护。

  1. 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
    
  2. 通过config导入到kong

    curl -X POST http://localhost:8001/config -F config=@test.yaml
    
  3. 测试

    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延伸出的:网络攻击、流控算法

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×