Kong Gatewayをデプロイする（DB-lessモード編）

# はじめに

Kong Gateway は、以下の4つのモードでデプロイすることができます。
* Traditionalモード
* DB-less and declarativeモード
* Hybridモード
* Kong Konnect

それぞれの方式には利点と制限事項があります。そのため、Kong Gateway を本番環境にインストールする際には、どのモードを選択するかを慎重に判断することが重要です。

本記事では、DB-less and declarative モードの特徴、メリット、制限事項、ならびにデプロイ手順について説明します。

Kong Gateway とは何かを知りたい場合は、以下の記事をご覧ください。

https://qiita.com/m5takeda/items/d7c74681c66692144ccc

# DB-less and declarativeモードとは

DB-less モードは、データベース (DB) に接続せずインメモリストレージのみで稼働する[^1]構成です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1997806/9326d379-09ff-9553-bbb5-1f62312e36f5.png)

[^1]: Kong 製 OSS の [lua-resty-lmdb](https://github.com/Kong/lua-resty-lmdb) で実現しているようです。

DB-less モードでは仕様上 [decK](https://docs.konghq.com/deck/latest/) を利用することができません。
ただし、decK で取り扱っていた設定ファイル ```kong.yml``` を利用して設定管理 (宣言的、Declarative) を行うことができます。

ユースケースとしては、

* ```kong.yml``` の検証 CI
* 超 Thin 環境での Kong Gateway ホスト

あたりが想定されます。

サイドカーに立ち上げてプロキシとして使うことも想定はできますが、不必要に容量が大きくなってしまうため、その場合は [Envoy](https://www.envoyproxy.io/) 等のプロキシ製品の活用を検討すると良いと思われます。Kubernetes 環境においてルーティング等に利用を考える場合は [Kong Ingress Controller](https://docs.konghq.com/kubernetes-ingress-controller/latest/) の活用をご検討ください。

## 特徴
* **Kong Gatewayの最小構成**
DB を使わない構成なので、必要なものは Kong Gateway インスタンス (と設定ファイル) のみです。

## メリット
* **Traditionalモードよりも更にシンプルな構成**
DB を使わないので疎通を含む多くの設定が不要になります。

* **全てコードベースで完結**
起動に関する設定を「**2種類** (```kong.conf```, ```kong.yml```)」のソースコードに集約することができるため、管理や複製・切り戻しが楽になります。

## デメリット
* **本番運用に適さない**
DB-less モードは本番運用のための API Gateway 構成ではありません。
検証やテスト、あるいは簡易プロキシなどのために利用するものです。

* **Kong の設定にメモリ制限がある**
```kong.yml``` に定義する全構成がメモリ内に収まる範囲である必要があります。

* **GUIによる操作はできない**
Kong Manager (管理 GUI) へのアクセスは可能ですが、設定情報の確認や設定の追加は行えません。

* **負荷分散はできない**
単一サーバ構成となるため、DB-less モード Kong Gateway を複数立てるだけでは厳密な負荷分散設定はできません。
複数の Kong Gateway 前にリバースプロキシを配置すれば疑似的な構成は可能ですが、DB-less モードの利点を損なってしまいます。

# DB-less モードのセットアップ

公式ドキュメントを参考に、Kong Gateway を DB-less モードでデプロイします。

https://docs.konghq.com/gateway/latest/install/linux/ubuntu/

Thin 環境での立ち上げを計画する場合は、CPU アーキテクチャが対応しているかについても併せてご確認ください。

https://docs.konghq.com/gateway/latest/support-policy/#supported-versions

## 環境
* WSL 2
* Ubuntu 22.04.1

## 実施手順

以下の記事では Docker を利用した起動方法の説明をしていました。

* [Kong Gatewayをデプロイする（Traditionalモード編）](https://qiita.com/m5takeda/items/f8e851ddf1ed8bb1606e)
* [Kong Gatewayをデプロイする（Hybridモード編）](https://qiita.com/m5takeda/items/162c690b9dbf393246af)
* [Kong Gatewayをデプロイする（Kong Konnect編）](https://qiita.com/m5takeda/items/45b2201d50dc98cb4bbf)

DB-less モードでは Thin な環境で実行できることが強みですので、今回は apt パッケージを利用したインストールを行います。

### Kong Gateway のインストール

```shell: Ubuntu への Kong Gateway インストール
# パッケージ情報の取得
$ curl -1sLf "https://packages.konghq.com/public/gateway-38/gpg.8F87A07D181DAA6B.key" |  gpg --dearmor | sudo tee /usr/share/keyrings/kong-gateway-38-archive-keyring.gpg > /dev/null
$ curl -1sLf "https://packages.konghq.com/public/gateway-38/config.deb.txt?distro=ubuntu&codename=jammy" | sudo tee /etc/apt/sources.list.d/kong-gateway-38.list > /dev/null

# apt リスト更新
$ sudo apt-get update

# kong インストール
$ sudo apt-get install -y kong-enterprise-edition=3.8.1.0

# インストール確認
$ kong version
> Kong Enterprise 3.8.1.0
```

### Kong Gateway の起動

DB-less モードの起動は

- ```kong.conf``` に ```database=off``` を設定して起動する。
- 環境変数 ```KONG_DATABASE``` に ```off``` を設定して起動する。

のいずれかにより行います。

```kong.conf``` の見本は GitHub を参照してください。

https://github.com/Kong/kong/blob/master/kong.conf.default

```conf: kong.conf
database=off
```

それでは起動します。

```shell
# 起動
$ sudo kong start -c kong.conf

# ポート確認
$ ss -atn
> State          Recv-Q          Send-Q                    Local Address:Port                   Peer Address:Port         Process
> ...
> LISTEN         0               4096                            0.0.0.0:8000                        0.0.0.0:*
> ...
> LISTEN         0               511                             0.0.0.0:8002                        0.0.0.0:*
> ...
> LISTEN         0               4096                          127.0.0.1:8001                        0.0.0.0:*
> ...

# 試しに Acmin API へアクセス
$ curl -i -X GET http://localhost:8001
> HTTP/1.1 200 OK
> Date: Tue, 03 Dec 2024 06:06:49 GMT
> ...
```

各ポートと用途の対応は以下をご確認ください。

https://docs.konghq.com/gateway/latest/production/networking/default-ports/

## 動作確認

Traditional モードのように Admin API から Services などの追加を行うとエラー表示されます。

```shell
$ curl -i -s -X POST http://localhost:8001/services \
 --data name=example_service \
 --data url='http://worldtimeapi.org'
 
> {
>    "code": 12,
>     "name": "operation unsupported",
>     "message": "cannot create 'services' entities when not using a database"
> }
```

起動後に設定を追加するには ```kong.yml``` を作成した後、以下を実行します。

```shell
$ curl -i -X POST http://localhost:8001/config \
  --form config=@kong.yml
```

実際に ```kong.yml``` を作成してみます。
```kong.yml``` の見本は以下のコマンドで生成できます。

```shell
$ sudo kong config -c kong.conf init
```

以下の記事を元にロードバランシングを設定するので、手動設定手順と比べてみていただけると良いかなと思います。

https://qiita.com/caunu-s/items/636aff1d04778fbbd779#%E3%83%AD%E3%83%BC%E3%83%89%E3%83%90%E3%83%A9%E3%83%B3%E3%82%B7%E3%83%B3%E3%82%B0

```yaml: kong.yml
_format_version: "3.0"

# service, route 作成
services:
- connect_timeout: 60000
  enabled: true
  host: example_upstream
  name: example_service
  port: 80
  protocol: http
  read_timeout: 60000
  retries: 5
  routes:
  - https_redirect_status_code: 426
    name: example_route
    path_handling: v0
    paths:
    - /mock
    preserve_host: false
    protocols:
    - http
    - https
    regex_priority: 0
    request_buffering: true
    response_buffering: true
    strip_path: true
  write_timeout: 60000

# upstream 作成
upstreams:
- algorithm: round-robin
  hash_fallback: none
  hash_on: none
  hash_on_cookie_path: /
  name: example_upstream
  slots: 10000
  targets:
  - target: httpbun.com:80
    weight: 100
  - target: httpbin.org:80
    weight: 100
```

```shell
# kong.yml を正しく読み取れるか検証
$ sudo kong config -c kong.conf parse kong.yml
> parse successful

# 設定適用
$ curl -i -X POST http://localhost:8001/config --form config=@kong.yml

# 数回アクセスしてみる
## httpbin.org にアクセスされた
$ curl http://localhost:8000/mock
> HTTP/1.1 200 OK
> ...

## httpbun.com にアクセスされた
$ curl -http://localhost:8000/mock
> HTTP/1.1 302 Found
> Connection: keep-alive
> Location: https://httpbun.com/
> ...
```

無事設定通りに動いていることを確認できます。

起動時から ```kong.yml``` に従って動作させたい場合は

- ```kong.conf``` に ```declarative_config=kong.yml``` を設定して起動する。
- 環境変数 ```KONG_DECLARATIVE_CONFIG``` に ```kong.yml``` を設定して起動する。

のいずれかにより行います。

また、8002 ポートでサービスが動いていることが確認できていましたが、実際に ```localhost:8002``` へアクセスすると管理 GUI にアクセスできます。

![kong-gui.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1997806/f327eeb8-782d-c100-b590-34e992fc4c18.png)

ただし、この画面から Routes や Services などを追加することはできません。
たとえ設定を行った後でも Summary の数字は増えませんので、完全に利用できない機能であると言えます。

Kong Gateway を停止するには以下を実行します。
永続化を行っていないので、先ほど設定したロードバランシングを含め、すべての設定値は削除されます。

```shell
$ sudo kong stop
```

# さいごに
本記事では、Kong Gateway のデプロイ方式の一つである DB-less モードについて、その特徴、メリット、デメリット、そして具体的なセットアップ手順を説明しました。
DB-less モードは本番運用には適しません。
ただし、検証用のセットアップとして有効であり、特に Kong Gateway 本番構成前の ```kong.yml``` 検証には強力な起動モードであるということができます。