1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

docker buildなしでKong Gatewayのカスタムプラグインを追加する

Last updated at Posted at 2024-05-28

通常コンテナ環境でKong Gatewayのカスタムプラグインを作る場合、Kong Gatewayのイメージをベースイメージとしてdocker buildでコンテナイメージを再作成する。
ただし、Kubernetes環境でかつ少量のLuaでプラグインを作成する場合はConfigMapSecretで代用することも出来る。
今回の記事はこちらの公式手順を参考にConfigMapでカスタムプラグインを実装する方法を確認した時のメモとなる。

プラグインの作成

ここではお試しとして以下の仕様のプラグインを作成する。

  • リクエストを受け取ると一定時間sleepする
  • sleep時間は外部からパラメータで指定することが出来る
  • なるべくどのプラグインよりも早く動く

ファイル構造は公式に従って以下の構造とする。

 /sleep
 ├── handler.lua    処理本体
 └── schema.lua     パラメータ設定(スキーマ)

なお、ファイル構造については公式で指定があり、この2つは必須となる。
中身は以下のように作った

handler.lua
local RequestSleep = {
    PRIORITY = 10000,
    VERSION = "0.0.1",
  }
  
function RequestSleep:access(conf)
    ngx.log(ngx.NOTICE, "plugin.access called")

    for k, v in pairs(conf) do
      ngx.log(ngx.NOTICE, "conf[" .. tostring(k) .. "] = " .. tostring(v))
    end
    
    local sleep_time = conf.sleep_time
    
    if sleep_time and sleep_time > 0 then
      ngx.log(ngx.NOTICE, "Sleeping for " .. sleep_time .. " seconds")
      ngx.sleep(sleep_time)
      ngx.log(ngx.NOTICE, "Woke up after sleeping for " .. sleep_time .. " seconds")
    else
      ngx.log(ngx.NOTICE, "No valid sleep_time provided, proceeding without sleep")
    end 
end
return RequestSleep

コードについて少し補足する。
優先度(PRIORITY)はPlugin Ordering Referenceよりexit-transformerより高い優先度である10000とした。これでほとんどのプラグインよりは早く動く。
:accessについてはこちらにあるようにリクエストをupstream(転送先サービス)に転送する前に引っ掛けて処理するためのものとなる。
ngxについてはlua-nginx-moduleであり、Kongはnginxで動いているので特に呼び出しとかしなくても使えるようになっている。
処理としては最初にconfの中身を表示し、パラメータチェックをした後にsleepするようにしている。
内部の動きを確認するためにngx.logを呼びまくっているが、シンプルにするならlog系は全て削除してOK。
schema.luaは以下。

schema.lua
return {
    name = "sleep",
    fields = {
      { config = {
          type = "record",
          fields = {
            { sleep_time = { type = "integer", default = 0, }, },
          },
      }, },
    }
  }

schema.luaの仕様はこちらを参照いただくとしてここでは詳細は特に触れない。
sleep_timeというパラメータを整数型で定義しているだけである。

プラグインのインストール

以下の手順で行う。

  1. ConfigMapの作成
  2. Kong Gatewayにプラグイン(ConfigMap)を認識させる

最初にConfigMapを作成する。展開先はKong Gatewayと同じNamespaceにする。

kubectl create cm kong-plugin-sleep --from-file=./sleep -n kong

次にKong Gatewayをデプロイし直す。
env.pluginsに作成したプラグイン名を追加し、plugins.configMapsに作成したConfigMapからプラグインを認識するよう設定を追加する。

:(省略)
env:
  plugins: bundled,openid-connect,sleep
:(省略)
plugins:
  configMaps:
  - name: kong-plugin-sleep
    pluginName: sleep

編集したvalues.yamlを使ってupdateし設定を反映する。

helm upgrade -i kong kong/kong --namespace kong --values kong-values.yaml --wait --debug

設定が反映されるとKong ManagerのPlugin検索から作成したPluginが見えるようになる。
20240528085359.png

動作確認

前回「Kong Gatewayの通信の遅延箇所をJaegerで確認する」という記事の中でnginxをユーザサービスに見立ててJaegerでトレーシングを行ったが、同じ環境にこのプラグインを適用し、以下を確認してみたい。

  • カスタムプラグインの仕様通り遅延が起こせるか
  • 発生した遅延をJaegerで確認できるか

Kong Managerにアクセスし、左サイドバーのRoutes-><nginxのRoute>を選択し、PluginsからNew Pluginを選択する。
sleepで検索してカスタムプラグインを選択し、以下の設定を行って保存する。

  • Protocols:http, https
  • Sleep Time:5

20240528085933.png

これで設定は完了となる。

コマンドを叩いて遅延が効くか確認する。時間を測るためにtimeコマンドを使って実行する。

time curl -X GET -k -i  https://nginx.hogehoge.info

結果は以下のようになった。

real	0m5.589s
user	0m0.010s
sys	    0m0.013s

プラグインによる5秒の遅延が効いているようだ。
Jaegerのトレースを見てみる。

20240528090620.png
作成したカスタムプラグインが最初に動き、かつここだけで5秒かかっていることが確認できた。
最後にログも見てみる。

$ kubectl logs -n kong kong-kong-5d667684f8-vxlzw -c proxy | grep notice
:(省略)
2024/05/28 00:07:14 [notice] 2437#0: *3169 [lua] handler.lua:10: conf[__key__] = plugins:sleep:da7eea27-3de1-552b-8f18-c038a617fc6e::::d83c6514-b5ed-462a-86e1-f3c8c577a324, client: 192.168.59.131, server: kong, request: "GET / HTTP/1.1", host: "nginx.hogehoge.info", request_id: "6636b272c181be016d61490e1c34a106"
2024/05/28 00:07:14 [notice] 2437#0: *3169 [lua] handler.lua:10: conf[__seq__] = 13, client: 192.168.59.131, server: kong, request: "GET / HTTP/1.1", host: "nginx.hogehoge.info", request_id: "6636b272c181be016d61490e1c34a106"
2024/05/28 00:07:14 [notice] 2437#0: *3169 [lua] handler.lua:10: conf[route_id] = da7eea27-3de1-552b-8f18-c038a617fc6e, client: 192.168.59.131, server: kong, request: "GET / HTTP/1.1", host: "nginx.hogehoge.info", request_id: "6636b272c181be016d61490e1c34a106"
2024/05/28 00:07:14 [notice] 2437#0: *3169 [lua] handler.lua:10: conf[__plugin_id] = 5601f1ab-939b-4810-9c36-bf9793a250f9, client: 192.168.59.131, server: kong, request: "GET / HTTP/1.1", host: "nginx.hogehoge.info", request_id: "6636b272c181be016d61490e1c34a106"
2024/05/28 00:07:14 [notice] 2437#0: *3169 [lua] handler.lua:10: conf[sleep_time] = 5, client: 192.168.59.131, server: kong, request: "GET / HTTP/1.1", host: "nginx.hogehoge.info", request_id: "6636b272c181be016d61490e1c34a106"
2024/05/28 00:07:14 [notice] 2437#0: *3169 [lua] handler.lua:16: Sleeping for 5 seconds, client: 192.168.59.131, server: kong, request: "GET / HTTP/1.1", host: "nginx.hogehoge.info", request_id: "6636b272c181be016d61490e1c34a106"
2024/05/28 00:07:19 [notice] 2437#0: *3169 [lua] handler.lua:18: Woke up after sleeping for 5 seconds, client: 192.168.59.131, server: kong, request: "GET / HTTP/1.1", host: "nginx.hogehoge.info", request_id: "6636b272c181be016d61490e1c34a106"

意図したログが表示されていること、デバッグ情報として入力した値(sleep_time)やRouteのIDなども拾えることなどが確認できた。

所感

docker buildをやってしまうとKong GatewayのVersion Up毎にイメージの作り直しが発生するが、このやり方であればイメージの作り直しが不要なのでメンテが楽である。
ただLuaのパッケージを追加したいとかもう少し複雑なことをしたい場合はあまり向いていなさそうなので、用途が限られる点は気をつけておきたい。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?