apisix~lua外掛開發與外掛註冊

张占岭發表於2024-05-14

開發外掛的步驟

在APISIX中,要自定義外掛,一般需要按照以下步驟進行操作:

  1. 編寫Lua指令碼:首先,你需要編寫Lua指令碼來實現你想要的功能。可以根據APISIX提供的外掛開發文件和示例進行編寫。

  2. 將Lua指令碼放置到APISIX外掛目錄:將編寫好的Lua指令碼檔案放置到APISIX的外掛目錄下,一般是/usr/local/apisix/lua-plugins/目錄。

  3. 編輯配置檔案:修改APISIX的配置檔案,啟用自定義外掛。在conf/config.yaml檔案中新增對應的外掛配置,指定使用你編寫的Lua指令碼。

  4. 重啟APISIX服務:完成以上步驟後,記得重啟APISIX服務使配置生效,可以使用命令apisix restart來重啟APISIX。

  5. 測試外掛:在完成上述步驟後,你就可以透過傳送請求測試你自定義的外掛是否按照預期工作了。

總的來說,自定義外掛的過程主要包括編寫Lua指令碼、放置到外掛目錄、編輯配置檔案、重啟APISIX服務以及測試外掛。詳細的開發步驟和示例可以參考APISIX官方文件。

部署到k8s

如果你使用Helm將APISIX部署到Kubernetes中,並且想要新增自定義外掛,可以按照以下步驟進行操作:

  1. 編寫Lua指令碼:首先,按照之前提到的步驟編寫Lua指令碼,實現你需要的功能。

  2. 建立ConfigMap:將編寫好的Lua指令碼內容放入一個ConfigMap中,可以使用如下命令建立一個ConfigMap:

    kubectl create configmap my-custom-plugin --from-file=my_plugin.lua
    
  3. 修改Helm Chart模板:編輯APISIX的Helm Chart模板,找到對應的配置檔案(一般是values.yaml或者configmap.yaml),在其中新增對應的ConfigMap配置,指定使用你的Lua指令碼。

  4. 升級APISIX部署:透過Helm命令升級APISIX的部署,使新的ConfigMap生效:

 helm -n apisix upgrade apisix -f ./apisix/values.override.yaml ./apisix

  1. 驗證外掛:升級完成後,可以傳送請求測試你自定義的外掛是否按照預期工作了。

透過以上步驟,你就可以在使用Helm部署的APISIX中新增自定義外掛。記得根據實際情況修改對應的檔案路徑和配置項,確保外掛能夠成功載入併發揮作用。

對dash board可見自定義外掛

1 配置中新增外掛

只有新增到配置檔案中的外掛才可以被apisix使用。在apisix 的conf 目錄的config.yaml 中有個plugins欄位,將示例外掛的外掛名"insert-header"新增到該欄位下。

2 裝載外掛

需要對apisix 進行reload。直接執行 apisix reload 就可以裝載外掛

3 dashboard中新增外掛

雖然apisix 提供了管理介面可以透過介面的方式給路由新增外掛,但使用dashboard 操作會方便很多。

1、重新生成schema.json.

curl 127.0.0.1:9092/v1/schema > /usr/local/apisix/dashboard/conf/schema.json

2、重啟dashboard

kill -9
(ps -ef|grep "/usr/local/apisix/dashboard"|gawk '

OpenResty

OpenResty階段

在OpenResty中,階段(phase)指的是請求處理過程中的不同階段或環節。OpenResty基於Nginx並使用Lua語言進行擴充套件,透過定義不同的階段可以在請求處理過程中插入自定義的Lua程式碼來實現各種功能。

在OpenResty中,請求經過一系列預定義的處理階段,每個階段都有對應的處理函式,開發者可以在這些階段中編寫Lua程式碼來實現各種功能,例如請求重寫、訪問控制、日誌記錄等。這些階段可以被稱為請求生命週期中的鉤子點,允許開發者在特定的時機執行自定義邏輯。

常見的OpenResty階段包括:

  • init_by_lua:在Nginx啟動時執行,用於初始化Lua程式碼。
  • init_worker_by_lua:在Worker程序啟動時執行,用於初始化Lua程式碼。
  • ssl_certificate_by_lua:用於SSL證書處理。
  • rewrite_by_lua:用於請求重寫。
  • access_by_lua:用於訪問控制。
  • content_by_lua:用於生成響應內容。
  • header_filter_by_lua:用於處理響應頭。
  • body_filter_by_lua:用於處理響應體。

透過在不同階段插入Lua程式碼,開發者可以實現高度定製化的請求處理邏輯,從而滿足各種需求,如API閘道器、反向代理、快取控制等。因此,OpenResty的階段機制提供了靈活且強大的擴充套件能力,使得開發者能夠更好地控制請求處理流程。

相關處理器方法

在APISIX中,這些_M開頭的方法是OpenResty的階段處理器,用於對請求或響應進行處理。下面是它們各自的作用:

  • _M.check_schema**:用於定義外掛配置的校驗規則,可以確保外掛配置符合預期的格式和型別。透過定義校驗規則,可以在配置外掛時進行引數檢查,避免配置錯誤導致的問題。
  • _M.header_filter:用於處理響應頭,在API響應返回給客戶端之前執行。
  • _M.new:用於建立新的請求或響應物件,可以在此階段對請求或響應進行初始化操作。
  • _M.incoming:用於處理請求體,在請求被路由到後端服務之前執行。
  • _M.access:用於訪問控制,可以在此階段進行許可權驗證、IP過濾等操作。
  • _M.rewrite:用於重寫請求,可以在此階段修改請求的URI、引數等資訊。
  • _M.api()**:用於註冊外掛的API介面,使得外掛可以透過API方式被外部呼叫。透過定義API介面,可以讓外掛暴露特定的功能給使用者使用,實現更加靈活的外掛擴充套件和定製
    除了上述提到的預置方法外,APISIX還提供了其他一些預置的方法,例如:
  • _M.balancer:用於負載均衡,可以在此階段選擇合適的後端節點進行請求轉發。
  • _M.init_worker:用於初始化Worker程序,在啟動時執行一次,通常用於載入配置、初始化資料等操作。
  • _M.log:用於日誌記錄,可以在此階段記錄請求、響應資訊到日誌系統。

總結來說,APISIX透過這些預置的方法(階段處理器)提供了豐富的擴充套件點,開發者可以根據需求在不同階段對請求和響應進行定製化處理,實現靈活的API閘道器功能。

一個完整的外掛demo

  • 向響應頭輸出X-Custom-Header頭
-- 定義一個 Lua 函式,用於處理請求
local core      = require("apisix.core")
local ngx = ngx
local ngx_encode_base64 = ngx.encode_base64
local ngx_decode_base64 = ngx.decode_base64
local ngx_time = ngx.time

local schema={} -- 注意,需要先定義它,再使用它

local _M={
    version=0.1,
    priority=1011,
    name = "lind-test",
    schema=schema
}

function _M.access(api_ctx)
    core.log.warn("hit access phase")
end


function _M.header_filter(ctx)
    core.log.warn("hit header_filter phase") -- 在apisix控制檯列印日誌
    core.response.add_header("X-Custom-Header", "apisix-3.9.1")
end


function _M.body_filter(ctx)
    core.log.warn("hit body_filter phase")
end


function _M.log(ctx)
    core.log.warn("hit log phase")
end

-- 註冊外掛
return _M

註冊外掛

values.yaml

  • 找到plugins節點,將現有的config-default.xml中的預設外掛新增,避免自定義外掛覆蓋預設外掛的情況
  • 預設外掛列表獲取方式:http://127.0.0.1:9180/apisix/admin/plugins/list 9180是apisix-admin的容器埠
plugins: ["real-ip","ai","client-control","proxy-control","request-id","zipkin","ext-plugin-pre-req","fault-injection","mocking","serverless-pre-function","cors","ip-restriction","ua-restriction","referer-restriction","csrf","uri-blocker","request-validation","chaitin-waf","multi-auth","openid-connect","cas-auth","authz-casbin","authz-casdoor","wolf-rbac","ldap-auth","hmac-auth","basic-auth","jwt-auth","jwe-decrypt","key-auth","consumer-restriction","forward-auth","opa","authz-keycloak","proxy-cache","body-transformer","proxy-mirror","proxy-rewrite","workflow","api-breaker","limit-conn","limit-count","limit-req","gzip","server-info","traffic-split","redirect","response-rewrite","degraphql","kafka-proxy","grpc-transcode","grpc-web","public-api","prometheus","datadog","loki-logger","elasticsearch-logger","echo","loggly","http-logger","splunk-hec-logging","skywalking-logger","google-cloud-logging","sls-logger","tcp-logger","kafka-logger","rocketmq-logger","syslog","udp-logger","file-logger","clickhouse-logger","tencent-cloud-cls","inspect","example-plugin","aws-lambda","azure-functions","openwhisk","openfunction","serverless-post-function","ext-plugin-post-req","ext-plugin-post-resp"]

values.override.yaml

  • 新增自定義外掛
  • 透過ConfigMap的方式將外掛內容放到配置檔案中
apisix:
  admin:
    type: NodePort
    nodePort: 30087

  customPlugins:
    enabled: true
    luaPath: "/opt/?.lua"
    plugins:
      - name: "lind-test"
        configMap:
          name: "my-plugins-config"
          mounts:
            - key: "lind-test.lua"
              path: "/opt/apisix/plugins/lind-test.lua" #相當於把my-plugins-config下的lind-test.lua這個key,對映到容器下面/opts/custom_plugins目錄,apisix/plugins是相對目錄(是固定的),檔名還是lind-test.lua

向route新增自定義外掛

  • 目前在dashborad中無法看到自定義外掛
  • 在/apisix/admin/plugins/list中可以看到外掛
curl http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "methods": ["GET"],
    "uri": "/test",
    "id": 1,
    "plugins": {
        "lind-test": {
        }
    },
    "upstream": {
        "type": "roundrobin",
        "nodes": {
            "127.0.0.1:1980": 1
        }
    }
}'

訪問頁面

  • http://apisix-gateway/test
  • 將test字首的請求,轉發到upstream,真實地址是127.0.0.1的1980埠指向的服務
  • 在瀏覽器的響應頭中,看到由lind-test外掛新增的標識X-Custom-Header

相關文章