Kongとは
詳しくはこちらの記事が参考になりました。
KONGことはじめ - Qiita
- 無料のAPI Gateway
- 無料のものと、Enterprise版がある(この記事では無料版を使用)
- 無料のものには、デフォルトでは管理コンソール的なものはない(非公式・無料の管理コンソールKongaがある)
- Admin APIと呼ばれるKongに標準搭載されているAPIを介してルーティングなどを設定する
- Gatewayのポートは8000、Admin APIのポートは8001が使用される
Kongに登場するService、Routeオブジェクトについて
詳しくはこちらが参考になりました
(Kongaの使い方の説明記事ですが、Kongの概念について冒頭で紹介されています)
Kongの使い方を知る① ~Service & Route編~ | ウルシステムズ株式会社
また、公式のドキュメントにも同様の説明がありました。
Expose your Services with Kong Gateway - vlatest | Kong - Open-Source API Management and Microservice Management
ざっくり言うと、Routeはクライアントがアクセスしてくるときのパスを表していて、
Serviceはそのパスにアクセスがきた時にどのバックエンドサーバーにリクエストを飛ばすかを設定するもの。
なのでServiceには1つ以上のRouteを設定して、ルーティングを設定する。
準備
すべてローカルで実施。
構成のイメージ
環境
- MacOS Catalina v10.15.4
- docker version 19.03.8
- docker-compose version 1.25.4 ← Kong、Postgresql、Kongaの起動に使用
APIの準備
今回はNode Expressで適当なGET、POSTのAPIを用意。
https://github.com/popy1017/sample-express
これをポートとメッセージを適当に変えて2つ起動
& をつけるとバックグラウンドで起動できる。
node app.js &
確認
※ jq は JSON形式の文字列をパースするコマンド
curl localhost:3000 | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 35 100 35 0 0 35000 0 --:--:-- --:--:-- --:--:-- 35000
{
"message": "This is service1. GET"
}
curl -X POST -H 'Content-type:application/json' -d '{"service": 1 }' localhost:3000 | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 72 100 57 100 15 28500 7500 --:--:-- --:--:-- --:--:-- 36000
{
"message": "This is service1. POST",
"body": {
"service": 1
}
}
Kongを起動する
KongやDB、Kongaは下記のdocker-compose.ymlで行った。
https://github.com/Kuari/kong-konga-docker-compose
ただし、1箇所だけ修正
〜略〜
konga:
image: pantsel/konga
ports:
- 1337:1337
links:
- kong:kong
container_name: konga
environment:
- NODE_ENV=production
networks: # <- 追加
- kong-net # <- 追加
〜略〜
起動と確認
まだルーティングなどを設定していないので、Gatewayにアクセスすると、"no Route matched with those values"というメッセージが返ってくる。
docker-compose up -d
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cb08a1c66bdc pantsel/konga "/app/start.sh" 41 hours ago Up 41 hours 0.0.0.0:1337->1337/tcp konga
6562aeafeb48 kong "/docker-entrypoint.…" 41 hours ago Up 41 hours 0.0.0.0:8000-8001->8000-8001/tcp, 0.0.0.0:8443-8444->8443-8444/tcp kong
8df4ff5a0599 postgres:9.6 "docker-entrypoint.s…" 41 hours ago Up 41 hours 0.0.0.0:5432->5432/tcp kong-database
curl localhost:8000 | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 48 100 48 0 0 5333 0 --:--:-- --:--:-- --:--:-- 5333
{
"message": "no Route matched with those values"
}
まずはAdmin API経由で使ってみる
Kongでは、Admin APIを介してServiceやRouteなどの設定を行う。
Admin APIの詳細な仕様については下記を参照してください。
Admin API - v2.0.x | Kong - Open-Source API Management and Microservice Management
Serviceを追加する
Serviceを追加するためには、http://{Kongサーバーのアドレスorドメイン}:8001/services
にPOSTリクエストを投げる。(今回はローカルで作業するので、http://localhost:8001/services
)
必須パラメータはurl
または、host
,port
,path
の3点セット。例えば、url=http://localhost:3000/hoge
と設定するのと、host=localhost, port=3000, path=/hoge
と設定するのは同義だと思われる。
※ 今回の構成では、Dockerコンテナの中(kong)からローカルサーバー(Node Express)にアクセスする必要があるため、hostにhost.docker.ineternal
を設定する。(localhostを指定すると、コンテナ内のローカルと認識されてしまう。)
urlのみ指定したが、レスポンスを見るとhost="host.docker.internal",port=3000,path="/"
となっていることが確認できる。
curl -X POST http://localhost:8001/services \
--data name=service1 \
--data url=http://host.docker.internal:3000/ | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 351 100 300 100 51 42857 7285 --:--:-- --:--:-- --:--:-- 50142
{
"host": "host.docker.internal",
"created_at": 1587283600,
"connect_timeout": 60000,
"id": "936cd429-1e8b-4732-87a6-1215634c5c98",
"protocol": "http",
"name": "service1",
"read_timeout": 60000,
"port": 3000,
"path": "/",
"updated_at": 1587283600,
"retries": 5,
"write_timeout": 60000,
"tags": null,
"client_certificate": null
}
Serviceの確認
GETで/services
または、/services/{service name or id}
を実行すると、Service一覧やSerivceの情報が取得できる。
# Service一覧
curl http://localhost:8001/services | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 323 100 323 0 0 64600 0 --:--:-- --:--:-- --:--:-- 64600
{
"next": null,
"data": [
{
"host": "host.docker.internal",
"created_at": 1587283600,
"connect_timeout": 60000,
"id": "936cd429-1e8b-4732-87a6-1215634c5c98",
"protocol": "http",
"name": "service1",
"read_timeout": 60000,
"port": 3000,
"path": "/",
"updated_at": 1587283600,
"retries": 5,
"write_timeout": 60000,
"tags": null,
"client_certificate": null
}
]
}
# 特定のService情報
curl http://localhost:8001/services/service1 | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 300 100 300 0 0 75000 0 --:--:-- --:--:-- --:--:-- 75000
{
"host": "host.docker.internal",
"created_at": 1587283600,
"connect_timeout": 60000,
"id": "936cd429-1e8b-4732-87a6-1215634c5c98",
"protocol": "http",
"name": "service1",
"read_timeout": 60000,
"port": 3000,
"path": "/",
"updated_at": 1587283600,
"retries": 5,
"write_timeout": 60000,
"tags": null,
"client_certificate": null
}
Routeを追加する
Routeは/services/{service name or id}/routes
にPOSTで追加できる。
必須パラメータは、methods
, hosts
, headers
, paths
のいずれか。
今回は、methodとpathを指定。
curl -X POST http://localhost:8001/services/service1/routes --data name=service1-api --data methods[]="GET" --data methods[]="POST" --data paths[]="/service1" | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 512 100 448 100 64 44800 6400 --:--:-- --:--:-- --:--:-- 51200
{
"id": "c2c410e4-5f0f-4e8f-a040-e5dc55f90a42",
"path_handling": "v0",
"paths": [
"/service1"
],
"destinations": null,
"headers": null,
"protocols": [
"http",
"https"
],
"methods": [
"GET",
"POST"
],
"snis": null,
"service": {
"id": "936cd429-1e8b-4732-87a6-1215634c5c98"
},
"name": "service1-api",
"strip_path": true,
"preserve_host": false,
"regex_priority": 0,
"updated_at": 1587285662,
"sources": null,
"hosts": null,
"https_redirect_status_code": 426,
"tags": null,
"created_at": 1587285662
}
確認
Admin APIで確認
特定のServiceが持つRoute一覧を取得するには、GETで/services/{service name or id}/routes
を実行する。
curl http://localhost:8001/services/service1/routes | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 471 100 471 0 0 78500 0 --:--:-- --:--:-- --:--:-- 78500
{
"next": null,
"data": [
{
"id": "c2c410e4-5f0f-4e8f-a040-e5dc55f90a42",
"path_handling": "v0",
"paths": [
"/service1"
],
"destinations": null,
"headers": null,
"protocols": [
"http",
"https"
],
"methods": [
"GET",
"POST"
],
"snis": null,
"service": {
"id": "936cd429-1e8b-4732-87a6-1215634c5c98"
},
"name": "service1-api",
"strip_path": true,
"preserve_host": false,
"regex_priority": 0,
"updated_at": 1587285662,
"sources": null,
"hosts": null,
"https_redirect_status_code": 426,
"tags": null,
"created_at": 1587285662
}
]
}
Gatewayから確認
{GatewayURL}:8000/{Routeで設定したPath}
で実行
# GET
curl localhost:8000/service1 | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 35 100 35 0 0 4375 0 --:--:-- --:--:-- --:--:-- 4375
{
"message": "This is service1. GET"
}
# POST
curl -X POST -H 'Content-type:application/json' -d '{"aaa":"bbb"}' localhost:8000/service1 | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 70 100 57 100 13 8142 1857 --:--:-- --:--:-- --:--:-- 10000
{
"message": "This is service1. POST",
"body": {
"aaa": "bbb"
}
}
以上がAdmin API経由でのルーティング設定。
慣れれば楽なんだろうが、何が起こっているのか、どう設定されているのかが非常にわかりにくい。
ので、続いてKongの非公式GUI Kongaを使ってみる。
Konga経由でルーティング設定をす
初期設定&ログイン
KongaのURLは http://localhost:1337/
初回アクセス時に、管理アカウントを作成する画面が表示されるので、適当に作成する。
作成が完了すると、ログイン画面に遷移するので、作成した管理アカウントでログインする。
ログインすると下記のような画面が表示されるので、下記のように設定する。(Nameは任意)
Name: KongSample
Kong Admin URL: http://kong:8001
※ KongaとKongはコンテナ間通信であるため、docker-compose.ymlで設定しているcontainer_name(=kong)で名前解決できる。ここでをlocalhostとしてしまうと、Kongaコンテナはコンテナ内を探しにいってしまう。
API経由で追加したService&Route確認
Admin URLの設定(Connectionという)が完了すると、以下のような画面が表示される。
サイドメニューのServicesやRoutesを選択すると、上記でAdmin API経由で追加したServiceやRouteの情報がみられる。
Konga経由でServiceを追加する
- 左サイドメニューの「Services」を選択する
- 「+Add New Service」ボタンを押す
- 「CREATE SERVICE」というモーダルが表示されるので、下記のように設定する。
- Name: service2
- Url: http://host.docker.internal:3001/
- 「Submit Service」ボタンを押し、Serviceを追加する。
登録が完了すると、Service一覧にservice2が追加されているはず。
Konga経由でRouteを追加する
続いてRouteを追加するが、Routeはサイドメニューの「Services」を選択して、いずれかのServiceを選択した後表示される画面で追加する。(サイドメニューRoutesを選択した場合の画面からは追加できない)
- 左サイドメニューの「Services」を選択する
- Service一覧から、「service2」を選択する
- 画面中央のサイドメニューから「Routes」を選択する
- 「+Add Route」ボタンを押す
- モーダルが表示されるので、下記のように設定する(他はデフォルト)
- Name: service2-api
- Paths: /service2
- Methods: GET,POST
※ PathsやMethodsのように複数の値を設定できる項目は、値を1つ入力するごとにEnterを押さないと反映されないので注意
- 追加が成功すると、Route一覧にservice2-apiが表示されるはず
Gatewayから確認してみる
# GET
curl localhost:8000/service2 | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 35 100 35 0 0 4375 0 --:--:-- --:--:-- --:--:-- 4375
{
"message": "This is service2. GET"
}
# POST
curl -X POST -H 'Content-type:application/json' -d '{"aaa":"bbb"}' localhost:8000/service2 | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 70 100 57 100 13 3000 684 --:--:-- --:--:-- --:--:-- 3684
{
"message": "This is service2. POST",
"body": {
"aaa": "bbb"
}
}