こんにちは。エクセルソフトの田淵です。
今回は API Management ツールの Kong を Docker で動かしてみます。
Dockerについては、弊社ページ や Ubuntuにインストールしたエントリー などをご参照ください。
2019/9/27 更新しました
Kong インストール
最初にコンテナ同士が発見や通信ができるようにカスタムネットワークをを作ります。Docker 環境で以下を実行します。
docker network create kong-net
次に Postgres のデータベースを起動します。
docker run -d --name kong-database \
--network=kong-net \
-p 5432:5432 \
-e "POSTGRES_USER=kong" \
-e "POSTGRES_DB=kong" \
postgres:9.6
1行バージョン
docker run -d --name kong-database --network=kong-net -p 5432:5432 -e "POSTGRES_USER=kong" -e "POSTGRES_DB=kong" postgres:9.6
次にデータベースをマイグレーションします。KONG_DATABASE の環境変数で利用しているデータベース(Casandora と Postgres があり、今回は Postgres を使用しています)を指定します。
docker run --rm \
--network=kong-net \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
kong:latest kong migrations up
1行バージョン
docker run --rm --network=kong-net -e "KONG_DATABASE=postgres" -e "KONG_PG_HOST=kong-database" -e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" kong:latest kong migrations up
以下のようなメッセージが表示され、データベースの準備ができます。
XX migrations processed XX executed database is up-to-date
準備が完了したら、Kong のコンテナを起動します。
docker run -d --name kong \
--network=kong-net \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
-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, 0.0.0.0:8444 ssl" \
-p 8000:8000 \
-p 8443:8443 \
-p 8001:8001 \
-p 8444:8444 \
kong:latest
1行バージョン
docker run -d --name kong --network=kong-net -e "KONG_DATABASE=postgres" -e "KONG_PG_HOST=kong-database" -e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" -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, 0.0.0.0:8444 ssl" -p 8000:8000 -p 8443:8443 -p 8001:8001 -p 8444:8444 kong:latest
起動を確認します。
curl -i http://localhost:8001/
API の追加と確認
API の開発は、Admin API ポートの各種エンドポイントに POST/UPDATE/DELETE などでデータを送って行っていきます。ローカルの Docker で動かしている場合は、標準で localhost:8001 が Admin API のポートです。
最初に Service を追加します。
curl -i -X POST \
--url http://localhost:8001/services/ \
--data 'name=example-service' \
--data 'url=http://httpbin.org'
1行バージョン
curl -i -X POST --url http://localhost:8001/services/ --data 'name=example-service' --data 'url=http://httpbin.org'
以下のようなレスポンスが返ってくれば成功です。
HTTP/1.1 201 Created
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 258
Content-Type: application/json; charset=utf-8
Date: Tue, 12 Feb 2019 01:24:35 GMT
Server: kong/1.0.2
{
"connect_timeout": 60000,
"created_at": 1549934675,
"host": "httpbin.org",
"id": "f535ce6b-28af-4d17-b9a1-ce0ef41ee8ea",
"name": "example-service",
"path": null,
"port": 80,
"protocol": "http",
"read_timeout": 60000,
"retries": 5,
"updated_at": 1549934675,
"write_timeout": 60000
}
POST データに含める name が作成した Service の名前(一意である必要があります)で、url が転送先の API のエンドポイントです。今回は httpbin を使用します。
次に作成したサービスにルートを追加します。
curl -i -X POST \
--url http://localhost:8001/services/example-service/routes \
--data 'hosts[]=example.com&hosts[]=foo.bar'
1行バージョン
curl -i -X POST --url http://localhost:8001/services/example-service/routes --data 'hosts[]=example.com&hosts[]=foo.bar'
次のようなレスポンスが返ってくれば成功です。
HTTP/1.1 201 Created
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 358
Content-Type: application/json; charset=utf-8
Date: Tue, 12 Feb 2019 05:57:25 GMT
Server: kong/1.0.2
{
"created_at": 1549951045,
"destinations": null,
"hosts": [
"example.com",
"foo.bar"
],
"id": "8b11b596-4f7c-4e62-a6fb-bfad52c56351",
"methods": null,
"name": null,
"paths": null,
"preserve_host": false,
"protocols": [
"http",
"https"
],
"regex_priority": 0,
"service": {
"id": "e96f86d5-fe53-4385-a4bc-77235663535f"
},
"snis": null,
"sources": null,
"strip_path": true,
"updated_at": 1549951045
}
Routes は指定した Host がリクエストヘッダーにあった場合に、紐付けた Service の返信を返す設定を行います。
アクセスして確かめてみます。動作しているユーザー向けポートはデフォルトでは 8000 で、先ほど作成した Route では example.com のヘッダーを受け付けるので、次のコマンドでアクセスしてみましょう。
curl -i -X GET \
--url http://localhost:8000/get?data=value \
--header 'Host: example.com'
1行バージョン
curl -i -X GET --url http://localhost:8000/get?data=value --header 'Host: example.com'
次のようなレスポンスが返ってきて、正しく転送されていることがわかります。
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 301
Connection: keep-alive
Server: gunicorn/19.9.0
Date: Tue, 12 Feb 2019 06:01:31 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Via: kong/1.0.2
X-Kong-Upstream-Latency: 395
X-Kong-Proxy-Latency: 26
{
"args": {
"data": "value"
},
"headers": {
"Accept": "*/*",
"Connection": "close",
"Host": "httpbin.org",
"User-Agent": "curl/7.54.0",
"X-Forwarded-Host": "example.com"
},
"origin": "172.18.0.1, 219.106.251.57",
"url": "http://example.com/get?data=value"
}
ここでは、url が example.com になっていることに注目しましょう。
同じ URL にもう一度アクセスしてみましょう。
X-Kong-Proxy-Latency: 0 X-Kong-Upstream-Latency: 370
今度は Kong がキャッシュしているので Kong のレイテンシーが 0 になっているのが分かります。
まとめ/次のステップ
Kong を使用して API を Forward して提供できることが分かりました。次は各種プラグインを使用して認証やアクセス制御などを行ってみます。
試してみてください
ダウンロード方法は こちら をご覧ください。OSS 版は API Management のみで、Enterprise には Analytics や Developer Portal の機能とサポートが付いてきます。まずは OSS 版で試していただくのが良いかと思います。


