1
0

More than 3 years have passed since last update.

kongのカスタムプラグイン(Go)の作り方

Last updated at Posted at 2021-05-24

はじめに

kongのカスタムプラグインについて、色々ハマったので、メモ。
情報自体はそれなりにあるのだが、kongバージョンが古いときの情報が多く、最新(2.4.1)ではちゃんと動作しなかったので、まとめておく。

TL;DR

  • コンパイルするコンテナイメージ(kong/go-plugin-tool)のバージョンは新しいものにしておく。そうしないとコンパイルが通らなかった。
  • kong自体はdockerで構築したので、Dockerfile内で/usr/local/binに生成したバイナリをコピーしておく。
  • 起動時の環境変数は以下を設定する。今回はプラグインをkey-checkerとした。
変数名
KONG_PLUGINSERVER_NAMES key-checker
KONG_PLUGINSERVER_KEY_CHECKER_QUERY_CMD /usr/local/bin/key-checker -dump
KONG_PLUGINS bundled, key-checker

作業の流れ

最初はバージョンとか全く意識せずやっていたので、コンパイルもできるけど動かない状態が続いた。
改めてマニュアルを見ると、作業の流れがちゃんと書いてあった。

  1. 構造体を定義する
  2. コンスタラクタを定義する
  3. 処理を定義する
  4. コンパイルする(-buildmode pluginにして.soファイルを作る)
  5. ライブラリをgo_plugins_dirで定義したディレクトリにおく。
  6. go-pdk/serverライブラリをインクルードする(プラグインをstandaloneにする場合)
  7. main関数を定義し、server.StartSefverを呼び出す(プラグインをstandaloneにする場合)
  8. 実行ファイルを作る

今回はstandaloneとして動かすため4や5は割愛した。

構造体を定義

こんな感じで定義した。

type Config struct {
    Apikey string
}

コンストラクタを定義

New()を定義する。

func New() interface{}  {
    return &Config{}
}

処理するための関数を定義

  • Certificate
  • Rewrite
  • Access
  • Response
  • Preread
  • Log

が実装できるカスタムロジックらしい。シグネチャは全部同じ、とのこと。今回はわかりやすいAccessを使った。
やっていることは、

  1. host情報をログに出力
  2. ヘッダにhelloを入れる

だけ。エラー処理とかは全く入れていないので注意。

func (c Config) Access(kong *pdk.PDK)  {
    kong.Log.Notice("plugin called.")
    host, _ := kong.Request.GetHost()
    kong.Log.Notice(host)
    kong.Response.SetHeader("X-hello-from-go", "hello")
}

mainの定義

これだけ。バージョンやpriorityは適当に。

func main() {
    server.StartServer(New, "1.0.0", 1)
}

実行ファイルのコンパイル

Dockerfileはこんな感じ。

FROM kong/go-plugin-tool:latest-alpine-latest AS builder
RUN mkdir -p /tmp/key-checker/
COPY . /tmp/key-checker/
RUN cd /tmp/key-checker/ && \
    go get github.com/Kong/go-pdk && \
    go mod init kong-go-plugin && \
    go build key-checker.go

FROM kong:latest
COPY --from=builder /tmp/key-checker/key-checker /usr/local/bin/key-checker

起動

docker-composeで以下の様に指定した。

  kong:
    image: kong-demo:latest
    user: "${KONG_USER:-kong}"
    depends_on:
      - db
    environment:
      割愛
      KONG_PLUGINSERVER_NAMES: key-checker
      KONG_PLUGINSERVER_KEY_CHECKER_QUERY_CMD: /usr/local/bin/key-checker -dump
      KONG_PLUGINS: bundled, key-checker

動作確認

key-checkerを各種サービスに登録し、curlを実行すると、こんな感じ。
helloがちゃんとレスポンスヘッダに入った。

$ curl http://localhost:8000/user-api/users -H "apikey:my-key" --head 
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 42
Connection: keep-alive
RateLimit-Reset: 15
X-RateLimit-Remaining-Minute: 4
X-RateLimit-Limit-Minute: 5
RateLimit-Remaining: 4
RateLimit-Limit: 5
X-hello-from-go: hello
Date: Mon, 24 May 2021 04:02:45 GMT
X-Kong-Upstream-Latency: 7
X-Kong-Proxy-Latency: 4
Via: kong/2.4.1

ログを見ると、

docker logs 767
2021/05/24 03:55:44 [notice] 1#0: using the "epoll" event method
2021/05/24 03:55:44 [notice] 1#0: openresty/1.19.3.1
2021/05/24 03:55:44 [notice] 1#0: built by gcc 10.2.1 20201203 (Alpine 10.2.1_pre1) 
2021/05/24 03:55:44 [notice] 1#0: OS: Linux 4.19.76-linuxkit
2021/05/24 03:55:44 [notice] 1#0: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/05/24 03:55:44 [notice] 1#0: start worker processes
2021/05/24 03:55:44 [notice] 1#0: start worker process 28
2021/05/24 03:55:44 [notice] 1#0: start worker process 29
2021/05/24 03:55:44 [notice] 28#0: *1 [lua] warmup.lua:92: single_dao(): Preloading 'services' into the core_cache..., context: init_worker_by_lua*
2021/05/24 03:55:44 [notice] 28#0: *1 [lua] warmup.lua:129: single_dao(): finished preloading 'services' into the core_cache (in 87ms), context: init_worker_by_lua*
2021/05/24 03:55:44 [notice] 29#0: *2 [kong] init.lua:290 only worker #0 can manage, context: init_worker_by_lua*
2021/05/24 03:55:44 [notice] 28#0: *10 [kong] process.lua:248 Starting key-checker, context: ngx.timer
2021/05/24 03:55:50 [notice] 28#0: *37 [kong] mp_rpc.lua:286 [key-checker] plugin called., client: 172.22.0.1, server: kong, request: "HEAD /user-api/users HTTP/1.1", host: "localhost:8000"
2021/05/24 03:55:50 [notice] 28#0: *37 [kong] mp_rpc.lua:286 [key-checker] localhost, client: 172.22.0.1, server: kong, request: "HEAD /user-api/users HTTP/1.1", host: "localhost:8000"
172.22.0.1 - - [24/May/2021:03:55:50 +0000] "HEAD /user-api/users HTTP/1.1" 200 0 "-" "curl/7.64.1"
172.22.0.1 - - [24/May/2021:03:56:06 +0000] "HEAD /user-api/users HTTP/1.1" 401 0 "-" "curl/7.64.1"

ちゃんとログに出力された。めでたしめでたし。

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