🦍

Kongの設定ファイルを環境ごとに切り替える

2022/11/30に公開

はじめに

OSSのKongは世界で最も人気のあるAPI Gatewayで、認証認可や流量制御などプラグインを有効化するだけで用意することができます。
プロキシ先のurlやパスなどの設定をDBに保管し、管理用APIやGUIで設定を行うことができますが、一方でyamlファイルで設定を宣言的に管理しDBレスの構成を取ることも可能です(ドキュメント)。

DBレス構成で設定ファイルでの管理において、環境ごとに設定値を変えたい場合、Kongには機能がないので工夫が必要になります。

上記の対応を備忘録として記載します。

KongのDockerコンテナの起動

DBレスモードでkongのコンテナを起動します。
例としてhttpbinへのルーティング設定を記載し、rate-limitngのプラグインを有効化します。

kong.yml
_format_version: "1.1"

services:
  - name: example_service
    url: http://httpbin.org/status/200
    routes:
      - name: example_route
        paths:
          - /example
    plugins:
      - name: rate-limiting
        config:
          second: 5
          hour: 10000
          policy: local

Dockerfileでkong.ymlをコピーし、KONG_DECLARATIVE_CONFIGにファイルパスを指定します。

Dockerfile
FROM kong:3.0.0-alpine
USER root

COPY kong.yml /kong/declarative/kong.yaml

ENV KONG_DATABASE off
ENV KONG_DECLARATIVE_CONFIG=/kong/declarative/kong.yaml
ENV KONG_PROXY_ACCESS_LOG /dev/stdout
ENV KONG_ADMIN_ACCESS_LOG /dev/stdout
ENV KONG_PROXY_ERROR_LOG /dev/stderr
ENV KONG_ADMIN_ERROR_LOG /dev/stderr

USER kong

docker-compose.ymlを作成し、コンテナを起動します。

docker-compose.yml
version: "3.9"
services:
  kong:
    build: .
    container_name: dbless_kong
    restart: always
    ports:
      - 8000:8000

起動後にcurlでHTTP STATUS 200で返ってくることを確認します。またRateLimit-Limitは指定通り5になっていることを確認します。

docker-compose up -d --build
curl -i localhost:8000/example

> HTTP/1.1 200 OK
> Content-Type: text/html; charset=utf-8
> RateLimit-Limit: 5
> X-RateLimit-Remaining-Second: 4
> X-RateLimit-Limit-Second: 5
> X-RateLimit-Remaining-Hour: 9999
> X-RateLimit-Limit-Hour: 10000
> RateLimit-Remaining: 4
> RateLimit-Reset: 1
...
> Via: kong/3.0.0

envsubstコマンドで環境ごとに設定切替

envsubstという軽量なテンプレートエンジンを使うことで、kong.ymlに環境変数を埋め込むことができます

まず、envsubstが含まれるgettextをイメージにインストールします。
また、テンプレートとしてイメージにコピーし、埋め込み後のファイルのために空のkong.ymlを生成しておきます。

Dockerfile
FROM kong:3.0.0-alpine
USER root

RUN apk add gettext #追加
COPY kong.yml /kong/template/kong.yml.template #変更
RUN mkdir -p /kong/declarative && touch /kong/declarative/kong.yml #追加
...

次にkong.ymlの表記を変更する。${環境変数名}とすることでenvsubstで埋め込むことができます。ここでは例としてrate-limitingの秒間リクエスト数を切り替えることとします。

kong.yml
_format_version: "1.1"

services:
    ...
    plugins:
      - name: rate-limiting
        config:
          second: ${RATE_LIMIT_PER_SECOND}
          hour: 10000
          policy: local

最後にdocker-compose.ymlで環境変数の定義と、コンテナ起動時に埋め込むコマンドを追加します

docker-compose.yml
version: "3.9"
services:
  kong:
    build: .
    container_name: dbless_kong
    environment:
      - RATE_LIMIT_PER_SECOND=5
    command: >
      /bin/bash -c "
      envsubst < /kong/template/kong.yml.template > /kong/declarative/kong.yml &&
      kong start"
    restart: always
    ports:
      - 8000:8000

この状態で起動し、/exampleにcurlしてみます。

docker-compose up -d --build
curl -i localhost:8000/example

> HTTP/1.1 200 OK
> Content-Type: text/html; charset=utf-8
> RateLimit-Limit: 5
> X-RateLimit-Remaining-Second: 4
> X-RateLimit-Limit-Second: 5
> X-RateLimit-Remaining-Hour: 9999
> X-RateLimit-Limit-Hour: 10000
> RateLimit-Remaining: 4
> RateLimit-Reset: 1
...
> Via: kong/3.0.0

問題なくRateLimit-Limitは指定通り5になっています。
kong.ymlを確認してみます。

docker exec -it dbless_kong /bin/bash
cat /kong/declarative/kong.yml

> _format_version: "1.1"

> services:
>  - name: example_service
>    url: http://httpbin.org/status/200
>    routes:
>      - name: example_route
>        paths:
>          - /example
>    plugins:
>      - name: rate-limiting
>        config:
>          second: 5
>          hour: 10000
>          policy: local

RATE_LIMIT_PER_SECONDに値が埋め込まれています。
このようにして、環境変数を埋め込むことができるので、環境ごとに環境変数を定義することで設定を切り替えることができます。

Discussion