0
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?

Kong GatewayでDB−lessモード利用時にAPIOpsを動かす

Last updated at Posted at 2025-09-11

Kong Gatewayには展開方法として、Traditional、Hybrid、DB-lessの3種類の方法がある。
DB-lessモードについては他の展開方法と異なりDBを利用せず、各ノードごとに予めKong Gatewayのエンティティ(ServiceやRouteなど)を定義したファイルを用意して構築する形になる。

これのメリットとしては以下あたりがある。

  • DBのライセンス、構築やメンテナンスが不要
  • Kong Gatewayの状態は基本的にはYAMLが全てとなる(稼働中の設定変更はあまり考慮する必要がない)

一方で以下のようなデメリットもある。

  • Admin APIやKong Managerによる変更が基本的には出来ない
  • Admin APIを使うdeckも一部利用できない
  • 構成変更をする時、各ノードごとに設定変更を行っていく必要がある(中央で管理してくれるControl Planeのようなものがないため)
  • DBを前提とする機能(Rate Limiting Pluginのカウンタ保存先など)が利用できない

Kubernetes環境だとetcdで吸収できるところもあるが、オンプレ環境などでは特にスケール観点で制約が重くのしかかるケースがあり、適用されるケースは限定的ではある。
とはいえ、DBが不要というメリットは大きいので特性を理解した上で使うのは有りだと思う。

このような特性を持つDB-lessモードのKong Gatewayに対して、APIOpsのパイプラインを組むとどんな感じになるかを少し考えてみる。

APIOps

APIOpsではOpen API Spec(OAS)を入力として、その内容を自動的にKong Gatewayの設定に変換して設定変更を行ったり、Dev Portalのようなものにドキュメントを自動更新するような一連のフレームワークである。
DBが利用可能な場合の一連のフローはざっくり以下のような感じになる。

それぞれに対応するコマンドは以下となる。

プロセス コマンド
OASのLinting inso lint spec
OASをdeck形式に変換 deck file openapi2kong
Pluginの設定を追加 deck file add-plugins
deckのYAMLを検証 deck gateway validate
既存環境との差分を出力 deck gateway diff
既存環境のバックアップ deck gateway dump
deckのYAMLを適用 deck gateway sync
動作確認 ./tests/e2e.sh
Portalにアップロード curl -X PATCH ...

テストの部分やPortalの部分はプロジェクトごとに異なるので割愛するが、基本的にはdeckを中心に一連のパイプラインが構成されていることが分かる。
ここでDB-lessだと問題になるのが、Admin APIのGET以外のメソッドを利用している部分が1つ、あとはDB-lessモードで使えるYAMLはDeckのYAMLと完全な互換性がない点がある。
そのため、それぞれ代替案を考える必要がある。

DB-lessのYAML

DB-lessモードではKong Gatewayの設定をYAMLで定義するが、deckのYAMLと完全な互換性がない。
具体的には以下のような点がある。

  • _info(default値の設定などで利用)を設定するとエラーとなる
  • _workspaceはdefaultのみ利用可能で、その他のworkspaceを指定しても無視される

_infoは非常に便利なため使いたい人も多いと思う。
そういう人のためにdeck file renderというコマンドが用意されている。
これは本来完全なdeck形式同士のYAMLをマージするためのコマンドであるが、_infoを展開してくれるという副次的な効果もある。
これを使ってDB-lessモードでのYAMLを生成することが出来る。
なお、validateの機能も備えているので、検証も併せて行うことが出来る。

Admin APIの代替

DB-lessモードではAdmin APIのGET以外のメソッドを利用できないが、例外が一部存在する。

  • /configエンドポイントへのPOST
  • UpstreamエンティティのTargetのhealthy/unhealthyへのPUT

前者の仕様は実は動的にKong Gatewayの設定を変更可能であり、ここにYAMLをPOSTすることで設定変更が可能である。
ただし、メモリ上のみ更新されるため、Kong Gatewayの再起動で設定が元に戻ってしまう。
実際に利用する際は一時的な変更でない場合はファイルの置換も併せて実施したい。

これまでの説明を踏まえると、以下のように変更することでDB-lessモードでもAPIOpsのパイプラインを構築できる。

コマンドは以下のように置き換わる。

プロセス コマンド
OASのLinting inso lint spec
OASをdeck形式に変換 deck file openapi2kong
Pluginの設定を追加 deck file add-plugins
deckのYAMLをDB-less用に変換 deck file render
既存環境との差分を出力 deck gateway diff
既存環境のバックアップ deck gateway dump
DB-lessのYAMLを置換 scp
DB-lessのYAMLを適用 curl -X POST :8001/config
動作確認 ./tests/e2e.sh
Portalにアップロード curl -X PATCH ...

各ノードへのscpはノード数が増えると面倒なので、その場合はpull型の仕組みを導入したり他の自動化ツールと組み合わせたり、NFSの利用を検討するなどもしてみてよいと思う。

実機検証

実際に上記フローで上手くいくかをGitLab環境で検証した。
検証した際のコードを以下に置いており、コードを読めばAPIOpsの実装自体は大体分かると思うので、個々のステップの詳細は割愛する。
https://github.com/imurata/gitlab-dbless-apiops

ジョブのフローは以下のように組んでいる。

.gitlab-ci.ymlもDB-less部分に絞って少し解説する。
DB-less用にファイルを変換している箇所は以下となる。

  stage: convert-dbless
  script:
  - |
    set -x
    echo "Convert deck.yaml to db-less.yaml"
    deck file render deck.yaml -o db-less.yaml
  artifacts:
    paths:
      - db-less.yaml

前のステージでdeck.yamlが生成されているため、それをDB-less用に変換している。
またアーティファクトとして残すようにし、後から確認できるようにもしている。
deployステージでは最初にscpするための前処理を行っている。

  before_script:
  - |
    set -euox pipefail
    apk add --no-cache openssh-client bash coreutils curl ca-certificates

    mkdir -p "$HOME/.ssh"
    chmod 700 "$HOME/.ssh"

    SSH_KEY="$CI_PROJECT_DIR/ssh-key"
    echo "$SSH_PRIVATE_KEY" | base64 -d > "$SSH_KEY"
    chmod 600 "$SSH_KEY"

    : > "$HOME/.ssh/known_hosts"
    for h in $DEPLOY_HOSTS; do
      h_no_user="${h#*@}"      # "host:/path"
      host="${h_no_user%%:*}"  # "host"
      ssh-keyscan -p "${SSH_PORT:-22}" -H "$host" >> "$HOME/.ssh/known_hosts" 2>/dev/null || true
    done
    chmod 644 "$HOME/.ssh/known_hosts"

SSH_PRIVATE_KEYはGitLabのCI/CDの変数で登録しておき、Base64エンコードしたものをSSHの鍵として利用する。
またknown_hostsファイルには、初回ログイン時に聞かれるメッセージを省略するためにデプロイ先のホストの情報を追加しておく必要がある。
script部分が実装になるが、ここでは各ホストごとにscpでファイルを配置した後、/configエンドポイントにPOSTしてプロセスを再起動せずに設定値を有効化している。

  script:
  - |
    set -x
    echo "Deploy"
    for h in $DEPLOY_HOSTS; do
      echo ">>> distributing to $h"
      scp -i $SSH_KEY ./db-less.yaml "$h"

      h_no_user="${h#*@}"      # "host:/path"
      host="${h_no_user%%:*}"  # "host"
      RESPONSE=$(curl -s -w "\n%{http_code}" -X POST http://${host}:8001/config \
        -H "Content-Type: application/yaml" \
        --data-binary @./db-less.yaml)
      BODY=$(echo "$RESPONSE" | head -n -1)
      CODE=$(echo "$RESPONSE" | tail -n1)
      echo "Response body:"
      echo "$BODY"
      echo "Response code: $CODE"
      if [[ "$CODE" =~ ^2 ]]; then
        return 0
      else
        return 1
      fi
    done

また、curlの戻り値は基本ゼロなので、HTTPステータスコードを取得して2xx系以外だとエラーにするようにしている。

実際にOASを更新して動作させると、以下のようにジョブが成功し、Kong Gatewayの設定も更新されていることが確認できた。

Deploy
+ echo '>>> distributing to ubuntu@44.212.196.195:/home/ubuntu/dbless/kong-dbless.yaml'
>>> distributing to ubuntu@44.212.196.195:/home/ubuntu/dbless/kong-dbless.yaml
+ scp -i /builds/imurata/db-less-apiops/ssh-key ./db-less.yaml ubuntu@44.212.196.195:/home/ubuntu/dbless/kong-dbless.yaml
+ h_no_user=44.212.196.195:/home/ubuntu/dbless/kong-dbless.yaml
+ host=44.212.196.195
+ curl -s -w '\n%{http_code}' -X POST http://44.212.196.195:8001/config -H 'Content-Type: application/yaml' --data-binary @./db-less.yaml
+ RESPONSE='{"services":{"0c51a34b-17a7-54b6-968a-4a8d05539b87":{"port":80,"tls_verify":null,"enabled":true,"tls_verify_depth":null,"ca_certificates":null,"client_certificate":null,"tags":["db-less"],"updated_at":1757552461,"connect_timeout":60000,"protocol":"http","name":"httpbin","id":"0c51a34b-17a7-54b6-968a-4a8d05539b87","created_at":1757552461,"path":"/","write_t
:(省略)
+ echo 'Response code: 201'
Response code: 201
+ '[[' 201 '=~' ^2 ]]
+ return 0
Cleaning up project directory and file based variables
00:00
Job succeeded

おまけ

DB-lessモードの注意点がDB-less mode limitationsに記載されている。
ここでは以下5つの項目について制限として挙げられている。

  • Memory cache requirements
  • No central database coordination
  • Read-only Admin API
  • Kong Manager compatibility
  • Plugin compatibility

このうち、mem_cache_sizeについての制限は古い仕様の頃の制限であり、ドキュメントの記載ミスの類であるので実際は気にしなくて問題ない。
あとUpstreamのTargetのhealthy/unhealthyはPOSTで変更出来るようなことが書いているが、これも誤りでありPUTが正しい。
DB-lessモードについては利用者が少ないせいか、このようにドキュメントのミスとかがちらほらあるのでドキュメントを参照するのも大事だが、同時に実機検証などもしっかり行った方が良さそうだ。

0
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
0
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?