Azure Web App for Containers 上で kong (API gateway) を docker で動かす

はじめに

image.png

この記事で説明する/しないこと

  • kong 自体の説明は割愛したい。API Gateway のソフトウェア。
    • Hosted なサービスである、Mashape というサービスが、 そのプラットフォームである Kong をオープンソース化した。
    • kong の代替はこのあたりApigeeTykKrakenD あたりとのこと。
  • なぜ API Gateway か、についても割愛したい。すでに多くは API Gateway Pattern などで言及されている。
  • 大事:kong は client から接続用と admin から接続用で二つポートが必要なのだが、Azure Web App for Containers はポートを一つしか公開できない制約があるため、Web App をそれぞれようにデプロイする。以下のような具合。
    1. client 接続用 kong.azurewebsite.net -> 8000 port
    2. admin 接続用 kong-admin.azurewebsite.net -> 8001 port

なぜ

  • Web App for Containers 上に API Gateway を置くことで、API アプリケーションを複数または単体で公開するときに Gateway レイヤを設けることができる。
  • Azure の App Service プランの性質上、複数アプリケーションを一つのプラン内で作成できるので、(端的に言うと、価格は1インスタンス分で複数アプリケーション)トラフィックの成長に合わせて少ないうちは節約できる。
  • なぜ kong を選んだか、についてはいくつか理由はあるが、ひとつ挙げると、nginx 上に OpenResty で実装されていて、軽量そうなところが個人的に好みである、という点。Gateway Layer に重厚なものは避けたい。
    • KrakenD というのは今回知ったが、もっとgolang 製でさらに軽量らしい。試してみたい。
  • 必要なもの全て Cloud 上の PaaS 環境を使って構築したい。

環境

$ docker version
Client:
 Version:       17.12.1-ce
 API version:   1.35
 Go version:    go1.9.4
 Git commit:    7390fc6
 Built: Tue Feb 27 22:17:40 2018
 OS/Arch:       linux/amd64

Server:
 Engine:
  Version:      17.12.0-ce
  API version:  1.35 (minimum version 1.12)
  Go version:   go1.9.2
  Git commit:   c97c6d6
  Built:        Wed Dec 27 20:12:29 2017
  OS/Arch:      linux/amd64
  Experimental: true

手順

原則、Kong 公式の手順通りだが、デプロイ先を local docker コンテナではなく、Azure Web App for Containers と Azure Database for PostgreSQL としている。
https://getkong.org/install/docker/

まずは、Local kong -> Azure PostgreSQL

Azure Database for PostgreSQL

Azure PostgreSQL から作る。Azure ポータルからポチポチ作った。

次にローカル環境から接続するので、ここでメニュー「接続のセキュリティ」から「自分の IP を追加」しておく。

さらに、同じメニュー内で 「SSL 設定」の 「SSL 接続を強制する」を "無効" にしておく。
この設定は本来は非推奨。今回、最終的に接続は Azure 内(Web App -> PostgreSQL)に閉じるのでまだいいが。
TODO: ちゃんと SSL 接続する手順は後ほど追記したい。
image.png

接続の確認は楽をしたいので GUI で済ませたい。ローカルの docker コンテナに、 pgadmin4 を起動して確認した。
https://hub.docker.com/r/dpage/pgadmin4/
手順は、Docker Hub 上記ページに詳細はあるが、ざっくりと以下の具合。

docker pull dpage/pgadmin4
docker run -p 8080:80 \
  -d dpage/pgadmin4

Web UI http://localhost:8080 のログインはデフォルト以下で。
Default: container@pgadmin.org
Default: Conta1ner

Azure 上 PostgreSQL に初期データを投入する

pgadmin4 上で "kong" という database を作成する。
:exclamation: 注意:オリジナルの手順ではこのステップがない。PostgreSQL は docker コンテナ上で起動していて、"kong" Database は既に作成済みなため。

$ docker run --rm \
    -e "KONG_DATABASE=postgres" \
    -e "KONG_PG_HOST=****.postgres.database.azure.com" \
    -e "KONG_PG_USER=****" \
    -e "KONG_PG_PASSWORD=****" \
    kong:latest kong migrations up --vv

**** 部分はそれぞれの環境に応じて置き換えて。--vv を付けると debug モードでやってくれる
上記の接続元 IP 設定や、SSL設定が漏れていると、ここで接続エラーになってしまうはず。

local docker container 上に kong アプリケーションを起動する

docker run (**** 部分はそれぞれの環境に応じて置き換えて。)

docker run -d --name kong \
    -e "KONG_DATABASE=postgres" \
    -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
    -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
    -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
    -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
    -e "KONG_ADMIN_LISTEN=0.0.0.0:8001" \
    -e "KONG_ADMIN_LISTEN_SSL=0.0.0.0:8444" \
    -e "KONG_PG_HOST=****.postgres.database.azure.com" \
    -e "KONG_PG_USER=****" \
    -e "KONG_PG_PASSWORD=****" \
    -p 8000:8000 \
    -p 8443:8443 \
    -p 8001:8001 \
    -p 8444:8444 \
    kong:latest

確認する。 8001 ポートは admin API のほう。

curl -i http://localhost:8001 

Azure Web App に kong をデプロイする

さあ、これで最後。大事なことをもう一回。

  • 大事:kong は client から接続用と admin から接続用で二つポートが必要なのだが、Azure Web App for Containers はポートを一つしか公開できない制約があるため、Web App をそれぞれようにデプロイする。以下のような具合。
    1. client 接続用 kong.azurewebsite.net -> 8000 port
    2. admin 接続用 kong-admin.azurewebsite.net -> 8001 port

Web App for Containers は 二つ 作成する。Azure Portal から Docker Hub の "kong:latest" イメージで作成する。

上記 docker run -e "HOGEHOGE=hogehoge" で指定した環境変数は、Azure Web App ではアプリケーション設定として設定する。
Azure Portal 上から設定も可能だが CLI が楽できる。
参考:Azure CLI: az webapp config appsettings set

Kong の設定、 /etc/kong/kong.conf の内容は、実行環境の環境変数によって上書きすることができる。

参考:どんな設定ができるか。 Kong Configuration Reference
Environment variables
All environment variables prefixed with KONG_

1. Client 接続用

Web App が作成されたら、環境変数を設定する。
Web App の公開ポートは WEBSITES_PORT で設定可能。

export RG=****(作成したリソースグループ)****
export APPNAME=****(作成したApp名)****
az webapp config appsettings set -g $RG -n $APPNAME --settings \
  KONG_DATABASE=postgres \
  KONG_PROXY_ACCESS_LOG=/dev/stdout \
  KONG_ADMIN_ACCESS_LOG=/dev/stdout \
  KONG_PROXY_ERROR_LOG=/dev/stderr \
  KONG_ADMIN_ERROR_LOG=/dev/stderr \
  KONG_ADMIN_LISTEN=0.0.0.0:8001 \
  KONG_ADMIN_LISTEN_SSL=0.0.0.0:8444 \
  KONG_PG_HOST=****.postgres.database.azure.com \
  KONG_PG_USER=**** \
  KONG_PG_PASSWORD=**** \
  WEBSITES_PORT=8000

アクセスしてみる。URL はそれぞれの環境に応じて。ここでは hello-kong としている。ここでポートを 8000 と付ける必要はない。80 で公開されている。

curl -i https://hello-kong.azurewebsites.net

ちゃんど起動しているか、こんな CLI コマンドでログを tail できる。

az webapp log tail -g $RG -n $APPNAME 

以下のようなメッセージが表示されたらOK。hello-kong の部分は アプリケーション名がくる。

2018-03-16 HH:MM:SS.SSS INFO  - Container hello-kong_0 for site hello-kong initialized successfully.

2. Admin 接続用

export RG=****(作成したリソースグループ)****
export APPNAME=****(作成したApp名 admin 用)****
az webapp config appsettings set -g $RG -n $APPNAME --settings \
  KONG_DATABASE=postgres; \
  KONG_PROXY_ACCESS_LOG=/dev/stdout; \
  KONG_ADMIN_ACCESS_LOG=/dev/stdout; \
  KONG_PROXY_ERROR_LOG=/dev/stderr; \
  KONG_ADMIN_ERROR_LOG=/dev/stderr; \
  KONG_ADMIN_LISTEN=0.0.0.0:8001; \
  KONG_ADMIN_LISTEN_SSL=0.0.0.0:8444; \
  KONG_PG_HOST=****.postgres.database.azure.com; \
  KONG_PG_USER=****; \
  KONG_PG_PASSWORD=****; \
  WEBSITES_PORT=8001

アクセスしてみる。URL はそれぞれの環境に応じて。ここでは hello-kong-admin としている。ここでポートを 8001 と付ける必要はない。80 で公開されている。

curl -i https://hello-kong-admin.azurewebsites.net

ちゃんど起動しているか、こんな CLI コマンドでログを tail できる。

az webapp log tail -g $RG -n $APPNAME 

以下のようなメッセージが表示されたらOK。hello-kong の部分は アプリケーション名がくる。

2018-03-16 HH:MM:SS.SSS INFO  - Container hello-kong-admin_0 for site hello-kong-admin initialized successfully.

参考 URL

やり残し

  • 全体の構成図を追記する
  • SSL 接続の手順を追記する
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.