Kongで WebAPIゲートウェイを作ります。
こんにちは。
「Kongインストール(前編)」では、OSS版インストール手順を探すのに手間取った上に、GUIの Adminツール Kong Managerが OSS版では使えないと分かったりと、踏んだり蹴ったりでしたので、クソして寝てしまいました。
中編では APIゲートウェイとしての設定をしてみたいと思います。
前提としてダミーの WebAPIを提供するサーバーを 2つ用意したいのですが、それっぽく JSON形式のレスポンスを返したいので何かしらで作らないといけない。
こういう検証の為に直ぐに使えるテスト用の WebAPIサーバーを持っておくものだなぁと思いますね。
手持ちの環境で早そうなのは、Spring Bootか Node-REDのどちらかなので、Node-REDでやることにします。
具体的にはこんな構成で。
折角なので、WebAPIのサーバーが色々な所にある「雰囲気」だけでもと思って、ラズパイも出してきました。
実験環境のIPとマシン名はこうなっています。
用途 | マシン名 |
---|---|
Kongサーバー | UbuntuServer2204 |
WebAPIサーバー1 | nginx-web2 |
WebAPIサーバー2 | raspberrypi |
WebAPIサーバー1と2には予め Node.jsと Node-REDのインストールはしてあります。
ご参考1:「Node.jsインストール」
ご参考2:「Ubuntu 22.04の IPv6無効化」
ご参考3:「Node-REDインストール」
WebAPIサーバー1と2の Node-REDでちょろい JSONを返すだけの簡単な機能を実装します。
左から[http in]-[template]-[http-response]のノードです。
[http-in]ノード
エンドポイントは「/message」にしました。
[template]ノード
レスポンスに乗せる JSONデータを作っています。
赤枠のところはデフォルトから変えていますよ。
WebAPIサーバー1では「Ubuntuっすわ」と答え、
WebAPIサーバー2では「ラズパイっすわ」と答えるようにしてあります。
[http response]ノード
何も変えていません。
これで WebAPIサーバー側の実装は完了です。
簡単ですね〜。
動作確認をします。
クライアントの Lubuntuからやりました。
subro@Lubuntu2204:~$ curl http://nginx-web2:1880/message
{"message":"Ubuntuっすわ"}
subro@Lubuntu2204:~$ curl http://raspberrypi:1880/message
{"message":"ラズパイっすわ"}
本当は改行がされませんが、見やすいよう加工しています。
良さげです。
ではいよいよ上記 2つの WebAPIを Kongに登録します。
Kongの使い方のドキュメントはこちら(Enterprise版のですが)
Kong Gateway
Kongの構成を説明しているページがこちら。
Services and Routes
これを読むと Kongでのエンドポイントとなる [Route]、実際の WebAPIサーバーのエンドポイントを指す [Service]、この 2つの設定が必要なようです。
このページの下の方に、curlコマンドで Kongの管理用WebAPIを叩いて設定する方法が書いてありますので、それに従ってやってみます。
なお管理用の WebAPIは Kongサーバーの [http://127.0.0.1:8001] で提供されていますので、この実験環境であれば Ubuntu Server 22.04.1で作った Kongサーバーにリモートログインして、ローカル作業として実行する必要があります。
Serviceを設定します。
subro@UbuntuServer2204:~$ curl -i -s -X POST http://localhost:8001/services --data name=ubuntu_message_service --data url='http://nginx-web2:1880/message'
HTTP/1.1 201 Created
Date: Sun, 18 Dec 2022 12:28:46 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Access-Control-Allow-Origin: *
Content-Length: 390
X-Kong-Admin-Latency: 14
Server: kong/3.1.1
{"write_timeout":60000,"tls_verify":null,"client_certificate":null,"tls_verify_depth":null,"protocol":"http","connect_timeout":60000,"created_at":1671366526,"read_timeout":60000,"host":"nginx-web2","name":"ubuntu_message_service","tags":null,"ca_certificates":null,"enabled":true,"updated_at":1671366526,"id":"900ef199-07a0-4a07-b760-be8176a580b0","path":"/message","retries":5,"port":1880}
subro@UbuntuServer2204:~$ curl -i -s -X POST http://localhost:8001/services --data name=raspberrypi_message_service --data url='http://raspberrypi:1880/message'
HTTP/1.1 201 Created
Date: Sun, 18 Dec 2022 12:29:05 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Access-Control-Allow-Origin: *
Content-Length: 396
X-Kong-Admin-Latency: 14
Server: kong/3.1.1
{"write_timeout":60000,"tls_verify":null,"client_certificate":null,"tls_verify_depth":null,"protocol":"http","connect_timeout":60000,"created_at":1671366545,"read_timeout":60000,"host":"raspberrypi","name":"raspberrypi_message_service","tags":null,"ca_certificates":null,"enabled":true,"updated_at":1671366545,"id":"6bc3e050-3cad-42f5-a2bc-51c5ca1b8337","path":"/message","retries":5,"port":1880}
設定した Serviceの内容。
見辛いので、jqコマンド(Command-line JSON processorq)で整形しています。
subro@UbuntuServer2204:~$ curl -sX GET http://localhost:8001/services | jq
{
"next": null,
"data": [
{
"write_timeout": 60000,
"tls_verify": null,
"client_certificate": null,
"tls_verify_depth": null,
"protocol": "http",
"connect_timeout": 60000,
"created_at": 1671366545,
"read_timeout": 60000,
"host": "raspberrypi",
"name": "raspberrypi_message_service",
"tags": null,
"ca_certificates": null,
"enabled": true,
"updated_at": 1671366545,
"id": "6bc3e050-3cad-42f5-a2bc-51c5ca1b8337",
"path": "/message",
"retries": 5,
"port": 1880
},
{
"write_timeout": 60000,
"tls_verify": null,
"client_certificate": null,
"tls_verify_depth": null,
"protocol": "http",
"connect_timeout": 60000,
"created_at": 1671366526,
"read_timeout": 60000,
"host": "nginx-web2",
"name": "ubuntu_message_service",
"tags": null,
"ca_certificates": null,
"enabled": true,
"updated_at": 1671366526,
"id": "900ef199-07a0-4a07-b760-be8176a580b0",
"path": "/message",
"retries": 5,
"port": 1880
}
]
}
イイ…んだと思います。
Routeを設定します。
subro@UbuntuServer2204:~$ curl -i -X POST http://localhost:8001/services/ubuntu_message_service/routes --data 'paths[]=/message/ubuntu' --data name=ubuntu_service_route
HTTP/1.1 201 Created
Date: Sun, 18 Dec 2022 12:40:12 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Access-Control-Allow-Origin: *
Content-Length: 502
X-Kong-Admin-Latency: 20
Server: kong/3.1.1
{"paths":["/message/ubuntu"],"request_buffering":true,"response_buffering":true,"destinations":null,"https_redirect_status_code":426,"protocols":["http","https"],"preserve_host":false,"updated_at":1671367212,"regex_priority":0,"service":{"id":"900ef199-07a0-4a07-b760-be8176a580b0"},"id":"98cc971a-e3a3-49ce-9f78-e56c19db85d0","sources":null,"path_handling":"v0","tags":null,"headers":null,"snis":null,"created_at":1671367212,"name":"ubuntu_service_route","hosts":null,"strip_path":true,"methods":null}
subro@UbuntuServer2204:~$ curl -i -X POST http://localhost:8001/services/raspberrypi_message_service/routes --data 'paths[]=/message/raspberrypi' --data name=raspberrypi_service_route
HTTP/1.1 201 Created
Date: Sun, 18 Dec 2022 12:40:58 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Access-Control-Allow-Origin: *
Content-Length: 512
X-Kong-Admin-Latency: 13
Server: kong/3.1.1
{"paths":["/message/raspberrypi"],"request_buffering":true,"response_buffering":true,"destinations":null,"https_redirect_status_code":426,"protocols":["http","https"],"preserve_host":false,"updated_at":1671367258,"regex_priority":0,"service":{"id":"6bc3e050-3cad-42f5-a2bc-51c5ca1b8337"},"id":"eae78125-734b-4d88-8f4a-42e158456504","sources":null,"path_handling":"v0","tags":null,"headers":null,"snis":null,"created_at":1671367258,"name":"raspberrypi_service_route","hosts":null,"strip_path":true,"methods":null}
設定した Routeの内容。
subro@UbuntuServer2204:~$ curl -sX GET http://localhost:8001/services/ubuntu_message_service/routes | jq
{
"next": null,
"data": [
{
"paths": [
"/message/ubuntu"
],
"request_buffering": true,
"response_buffering": true,
"destinations": null,
"https_redirect_status_code": 426,
"protocols": [
"http",
"https"
],
"preserve_host": false,
"updated_at": 1671367212,
"regex_priority": 0,
"service": {
"id": "900ef199-07a0-4a07-b760-be8176a580b0"
},
"id": "98cc971a-e3a3-49ce-9f78-e56c19db85d0",
"sources": null,
"path_handling": "v0",
"tags": null,
"headers": null,
"snis": null,
"created_at": 1671367212,
"name": "ubuntu_service_route",
"hosts": null,
"strip_path": true,
"methods": null
}
]
}
subro@UbuntuServer2204:~$ curl -sX GET http://localhost:8001/services/raspberrypi_message_service/routes | jq
{
"next": null,
"data": [
{
"paths": [
"/message/raspberrypi"
],
"request_buffering": true,
"response_buffering": true,
"destinations": null,
"https_redirect_status_code": 426,
"protocols": [
"http",
"https"
],
"preserve_host": false,
"updated_at": 1671367258,
"regex_priority": 0,
"service": {
"id": "6bc3e050-3cad-42f5-a2bc-51c5ca1b8337"
},
"id": "eae78125-734b-4d88-8f4a-42e158456504",
"sources": null,
"path_handling": "v0",
"tags": null,
"headers": null,
"snis": null,
"created_at": 1671367258,
"name": "raspberrypi_service_route",
"hosts": null,
"strip_path": true,
"methods": null
}
]
}
これもイイ…のではないかと。
これで、とりあえずの Kongの設定はできていると思います。
クライアント(Lubuntu)から Kongの APIエンドポイントである [http://UbuntuServer2204:8000/message] 以下に集約された(はずの) URLにアクセスしてみます。
subro@Lubuntu2204:~$ curl -s http://UbuntuServer2204:8000/message/ubuntu
{"message":"Ubuntuっすわ"}
subro@Lubuntu2204:~$ curl -s http://UbuntuServer2204:8000/message/raspberrypi
{"message":"ラズパイっすわ"}
おぉ、こんな下らぬメッセージを吐くサーバーは私が作った他にあるはずもなく、想定通りの動きをしています。
2つのサーバーの WebAPIがまるで 1つのサーバー(Kongサーバー)にあるように見える!(なんちゃって)
とりあえず、エンドポイントの集約・一元化はこうしてやれば OKなようですね。
本当の WebAPIサーバーのマシン名が変わったりエンドポイントの位置が変わったりしても、Kongを通すことで URLを恒久的なものにするのには役立つのでしょう。
でもこれじゃ単なるリバプロだ。
後編では、ユーザー認証機能のない WebAPIに対して、Kongでユーザー認証を追加しちゃおうと思います。
「Kongインストール(後編)」につづく。