LoginSignup
5
1

Go で Kong Gateway カスタムプラグインを作成する

Last updated at Posted at 2023-12-27

この記事の目的

以下の記事で Kong Gateway の公式ドキュメントを読んで動作確認を行いました.

こちらの記事では Kong Gateway のドキュメントから特にカスタムプラグイン作成について確認と検証をしてみます.

こちらの記事を参考にして Kong Gateway (OSS) および Kong Gateway (Free) 用のカスタムプラグインを Go 言語を使って作成することができます.

こちらの記事の動作確認は上記の記事による Kong Gateway 環境構築を前提としています.

動作確認環境

動作確認を行った環境情報を以下に示します.

Name Version
Windows 10 22H2
Ubuntu (WSL2) 20.04 LTS
Docker 20.10.17
Docker Compose v2.10.2
Kong Gateway (OSS) 3.5.0
Go 1.21.3
go-pdk v0.10.0

Kong Gateway のカスタムプラグインと言語選択

lua-nginx-module enables Lua scripting capabilities in Nginx. Instead of compiling Nginx with this module, Kong is distributed along with OpenResty, which already includes lua-nginx-module. OpenResty is not a fork of Nginx, but a bundle of modules extending its capabilities.
Hence, Kong is a Lua application designed to load and execute Lua modules (which we more commonly refer to as plugins) and provides an entire development environment for them, including an SDK, database abstractions, migrations, and more.

公式ドキュメントにある通り Kong Gateway は Lua モジュールを利用する Lua アプリケーションです.

Kong からは Lua の関数セットであるプラグイン開発キット (PDK) が提供されています.
PDK は複数の言語でサポートされています.

Language GitHub Link
Lua https://github.com/Kong/kong/tree/master/kong/pdk
Go https://github.com/Kong/go-pdk
JavaScript https://github.com/Kong/kong-js-pdk
Python https://github.com/Kong/kong-python-pdk

言語選択と実装方法は「何の言語で書きたいか」と「パフォーマンス」を考慮して選択することになります (Go/Python ではマルチコアが動作可能だが,JavaScript では不可など).

本記事では Go による Kong Gateway カスタムプラグインを作成してみます.
Go で作成されたプラグインはプロセスとして稼働し,Kong Gateway には Socket を登録することになります.

Lua によるカスタムプラグイン作成は,公式ドキュメントと以下の記事を参考にして進めてみるとよさげです.(筆者もそのうちやってみることとします...)

参考 : Lua とは

Lua is a powerful, efficient, lightweight, embeddable scripting language. It supports procedural programming, object-oriented programming, functional programming, data-driven programming, and data description.

Go による Kong Gateway のカスタムプラグインを利用する

こちらでは go-pdk を使ってカスタムプラグインを作成し,Kong Gateway で利用できるようにします.

(go-pdk はドキュメントもまだ作成中で,最新版が v0.10.0 という状態ではありますが...)

プラグインの作成

Kong Gateway の公式ドキュメントによると,以下の実装が必要になります.

  • 取り扱うデータを含める structure を作成
  • New()structure を利用するインスタンスを作成
  • structure を利用するメソッドを作成
  • go-pdk/server ライブラリをインポート
  • server.StartServer(New, Version, Priority) を呼ぶ main() 関数を実装
  • go build でビルド

手順に従って Go ファイルを記述していきます.
ここでは HTTP ヘッダに foo: bar を含めるプラグインを作成します.

go-pdk を使うリポジトリを作成 & Go ファイル作成
mkdir -p $HOME/codes/GitHub/kong-go-sample-plugin && cd $_ && \
go mod init kong-go-sample-plugin && \
go get github.com/Kong/go-pdk
vim add_header.go
add_header.go
package main

import (
	"github.com/Kong/go-pdk"
	"github.com/Kong/go-pdk/server"
)

func main() {
	server.StartServer(New, Version, Priority)
}

const Version = "1.0.0"
const Priority = 1

type MyConfig struct {
	FieldValue string
 }

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

func (conf MyConfig) Access(kong *pdk.PDK) {
	value := conf.FieldValue
	if value == "" {
		value = "bar"
	}
	kong.Response.AddHeader("foo", value)
}

go-pdk が提供している関数は go-pdk のファイル群から探します.
例えば AddHeadergo-pdk/response/response.go に記載されています.

参考にリクエストとレスポンスに関する使いそうな関数を以下の表に書き出しておきます.

File Function Argument
go-pdk/request/request.go GetScheme ()
GetHost ()
GetPort ()
GetForwardedScheme ()
GetForwardedPort ()
GetHttpVersion ()
GetMethod ()
GetPath ()
GetQuery (max_args int)
GetHeader (k string)
go-pdk/response/response.go GetStatus ()
GetHeader (name string)
GetSource ()
SetHeader (k string, v string)
AddHeader (k string, v string)
ClearHeader (k string)

Access(kong *pdk.PDK) では実行するフェーズを指定しています.
利用できるものは以下です.1

Handler Phase
Certificate SSL ハンドシェイク時
Rewrite リクエストが届いてからプロキシする前 (Global設定時のみ)
Access リクエストが届いてからプロキシする前
Response 上流 API からのレスポンスが届いた時
Preread リクエストが届く前 (不正確かもしれません...)
Log 最後の応答がクライアントに送信された時

続いてビルドします.

Go プラグインビルド
go mod tidy
go build
ls
> add_header.go  go.mod  go.sum  kong-go-sample-plugin

プラグインを有効化

ビルドしたプラグインを Kong Gateway コンテナに渡す方法については,

  • プラグインを含めた Kong Gateway コンテナイメージを作成する
  • プラグインをマウントボリュームに配置する

が一般的かと思いますが,ここでは簡単のため直接コンテナにコピーします.
また Kong Gateway 設定ファイル kong.conf にプラグイン情報を記載し,コンテナにコピーします.

Kong Gateway コンテナにプラグインと設定ファイルをコピー
docker cp ./kong-go-sample-plugin kong-kong-1:/usr/local/bin/kong-go-sample-plugin
vim kong.conf
docker cp ./kong.conf kong-kong-1:/etc/kong/kong.conf
kong.conf
plugins = bundled,kong-go-sample-plugin
pluginserver_names = kong-go-sample-plugin

pluginserver_kong_go_sample_plugin_socket = /usr/local/kong/kong-go-sample-plugin.socket
pluginserver_kong_go_sample_plugin_start_cmd = /usr/local/bin/kong-go-sample-plugin
pluginserver_kong_go_sample_plugin_query_cmd = /usr/local/bin/kong-go-sample-plugin  -dump

Write plugins in Go には記載ありませんが plugins = bundled,kong-go-sample-plugin の追加が必要です.特に bundled を除くと前回の記事で利用したものが使えなくなります.

Kong Gateway 再起動後にカスタムプラグインを有効化して動作確認をします.

カスタムプラグインの有効化
docker compose --profile gateway restart

curl -i -X POST http://localhost:8001/plugins \
 --data name=kong-go-sample-plugin
> HTTP/1.1 201 Created
> ...

curl --head -X GET http://localhost:8000/mock/api/timezone/Asia/Tokyo
> HTTP/1.1 200 OK
> Content-Type: application/json; charset=utf-8
> Content-Length: 346
> Connection: keep-alive
> foo: bar
> ...

以上で Go で作成した Kong Gateway カスタムプラグインが正常に起動していることが確認できました.
なお,プラグインを有効化すると管理 GUI でも kong-go-sample-plugin プラグインの管理ができるようになります.

Kong-Go-Custom-Plugin.png

また,Kong Gateway コンテナの中に入ると kong-go-sample-plugin がプロセスとして動いていることも観察できます.

docker exec -it kong-kong-1 /bin/bash
> ps -aux
>> USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
>> kong         1  0.0  0.6 399560 53040 ?        Ss   07:49   0:01 nginx: master process /usr/local/openresty/nginx/sbin/n
>> kong      1288  0.6  1.3 458132 107504 ?       S    07:49   0:09 nginx: worker process
>> kong      1289  0.2  1.1 446892 95352 ?        S    07:49   0:04 nginx: worker process
>> kong      1290  0.2  1.1 440324 89900 ?        S    07:49   0:03 nginx: worker process
>> kong      1291  0.2  1.1 440516 90128 ?        S    07:49   0:04 nginx: worker process
>> kong      1292  0.0  0.1 1603596 12468 ?       Sl   07:49   0:00 /usr/local/bin/kong-go-sample-plugin
>> kong      3840  0.1  0.0   4492  3852 pts/0    Ss   08:13   0:00 /bin/bash
>> kong      3906  0.0  0.0   7060  1608 pts/0    R+   08:13   0:00 ps -aux

まとめ

今回は Go による Kong Gateway のカスタムプラグインを作成しました.

go-pdk が整ってくるとより開発の幅が広がったり,わかりやすいドキュメントが公開されたりしてくるのかなと思います.

カスタムプラグインを使って Kong Gateway をより高機能に使っていきたいと思います!

  1. https://docs.konghq.com/gateway/latest/plugin-development/custom-logic/#available-contexts

5
1
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
5
1