お問い合わせフォーム
(ウルシステムズ株式会社のBlueRabbitサイトへ )

1. 概要

ユーザーとマイクロサービスAPIとの間の交通整理役としてマイクロサービス開発とは切っても切り離せない仲にあるAPIゲートウェイですが、数ある実装の中でも有名なものが「 Kong 」です。

OSSの Community Edition と企業ユース向けの Enterprise Edition があり、それぞれ豊富なプラグインを追加することで簡単に機能を拡張することもできます。


このシリーズではKong Community Editionの使い方を、ブラウザベースの管理ツールである「 Konga 」を利用しながら調べていきます。

今回はマイクロサービスを登録するための「Service」と「Route」の設定項目と手順についてです。

2. 環境

今回使用するKong、Konga、登録マイクロサービスついての詳細は以下の通りです。

なお、KongとKongaのインストール方法については省略しますが、弊社の提供する無料の「ServiceManager Online」(近日提供)による自動構築も可能です。これはマイクロサービス/サービスメッシュ化ソリューションである NanaHoshiプラットフォーム にも組み込まれています。

2.1. Kong

【バージョン】

kong-0.14.1

kongが使用するデータベースはPostgreSQLかApache Cassandraを選択できますが、スケーラビリティと可用性のためにCassandra 3.11を使用しています。


【メモ】

初期設定時に行うmigration時にスキーマ情報がCassandraクラスタ内で完全に同期されるのを待つ時間を、念のためデフォルトより長めに変更した方がタイムアウトエラーが発生しにくくなっていいかもしれません。

Kongの設定ファイル「kong.conf」の「cassandra_schema_consensus_timeout」という項目が該当し、今回はデフォルトの10000(ミリ秒=10秒)から120000(=120秒)に変更してmigrationを実施しました。

2.2. Konga

【バージョン】

konga-0.11.2


【メモ】

現在(2018年9月)の段階での最新のバージョンを使用してますが、このバージョンではCONSUMERSとPLUGINSの一覧画面で一覧データを取得できない現象が発生しました。

原因はKongaがKongに一覧データを問い合わせる際に、指定できるデータ数上限が2147483647となっている所、その倍の4294967295が指定されているためです。

これを解消するため、今回はKongaのソースファイル「assets/js/app/core/services/ListConfigService.js」にあるパラメータ「itemFetchSize」を4294967295から2147483647に変更しています。

2.3. サンプルマイクロサービス

【メモ】

今回用にPythonで作成したサンプルプログラムです。ソースコードはGitHub上の こちら の「article01」に置いてあります。

標準モジュールのみで作成しており、Python 2.7で動作確認をしています。


とてもシンプルな仕様となっており、

http://[host_or_ip]:8000/utc

をGETメソッド又はPOSTメソッドで呼び出すと

YYYY-MM-DD hh:mm:ss

というフォーマットで現在日時(協定世界時)の文字列を戻してくれるサンプルマイクロサービスになっています。

3. マイクロサービスをKongaからKongに登録する

ユーザーとマイクロサービス、Kongの関係は下図の通りです。ユーザーはKongの「Route」にリクエストを出し、Kongがこれを「Service」と結び付け、このServiceと関連付けられているマイクロサービスにリクエストを転送する、という流れになります。

「Service」はマイクロサービスのAPIを、「Route」はユーザーから見たAPIアクセス方法をそれぞれ抽象化したもので、今回はKongaを使ってこれらを設定していきます。


また、「Route」には複数のアクセス方法を登録できるため、ユーザーからの異なるリクエスト方法を1つのRouteで扱うことができます。

例えば下図のように、

hostAの/abcへのGETメソッドでのユーザーからのリクエスト

hostDの/defへのPOSTメソッドでのユーザーからのリクエスト

を単一の

hostXの/xyzへのGET/POSTメソッドでのマイクロサービスへのリクエスト

に集約できます。


さらに複数の「Route」を1つの「Service」で扱うことができます。つまり、マイクロサービスと「Service」は1対1ですが、「Service」と「Route」及び「Route」とクライアントからのリクエスト方法はそれぞれ1対Nにすることができます。これにより様々なユーザーからのアクセスパターンを1つのマイクロサービスに集約することがKongでは簡単に実現できます。


今回は下図のようなシンプルなシステム構成を想定しながらマイクロサービスをKongに登録し、最後に複数のリクエスト方法を1つにまとめてみます。

まずはKongaを使用しながら、最初にKongの「Service」(①)にマイクロサービスのURL(②)を登録し、次に「Route」(③)にユーザーから見えるAPIのURL(④)を登録するという全体の流れになります。


以下の文中の用語を統一させるため、以下のようにURLの各部分の名称を定義しておきます。

3.1. Service の登録

インストール後のKongaにログインしてから、画面左側にある「SERVICES」メニューをクリックすると、Service一覧画面が表示されます。(インストール直後はServiceがまだ登録されていないため一覧には何も表示されていません)


ここで「+ ADD NEW SERVICE」ボタンをクリックすると下図のようなService登録モーダルが表示されます。


各入力フィールドついては以下の表にまとめました。「必須」列の「△」は入力状況に応じて必須かどうかが変わることを表しています。参考までに、直接KongのAPIを使用してServiceを登録する際のパラメータに対応する項目である場合は「APIパラメータ名」列に記載しています。

フィールド名 必須 APIパラメータ名 説明
Name × name Serviceの名前。
半角英数と「.-_~」のいずれかのみ入力可。
Description × Serviceの説明文。
Kongaの独自項目。日本語入力可。
Tags × Serviceに付けるタグ。
Kongaの独自項目。日本語入力可。複数指定可。
1つのタグ文字列を入力する毎にエンターキーで確定する必要あり。
Url url このServiceに紐付けるマイクロサービスAPIのURL。
以降のProtocol、Host、Port、およびPathを一括で設定する場合に利用します。入力した場合はこれらを別途指定する必要はありません。
Protocol × protocol このServiceに紐付けるマイクロサービスAPIのprotocol部分。
選択肢はhttpとhttpsのみ。デフォルトはhttp。
Host host このServiceに紐付けるマイクロサービスAPIのhost部分。
デフォルト値がないため、Urlフィールドを入力しない場合は入力必須。
Port × port このServiceに紐付けるマイクロサービスAPIのport部分。
デフォルトは80。文字列を入力してもエラーにはなりませんが、数字以外はデフォルト値が採用されるようになっています。
Path × path このServiceに紐付けるマイクロサービスAPIのpath部分。
デフォルトは空白文字列""なので、ルート(/)になります。
Retries × retries Kongサーバからマイクロサービスへのリクエストが失敗した場合のリトライ回数。
デフォルトは5。リクエスト失敗からカウントアップされるため、Kongサーバからのリクエストは最大で指定数+1回実施されることになります。
リクエストの失敗とはサーバからのレスポンスがない場合を指すため、マイクロサービス側でリクエストが処理されている可能性もあり、この場合はリトライにより同じ処理を複数回行うことになるため注意が必要。
Connect timeout × connect_timeout Kongサーバからマイクロサービスへの接続が確立されるまで待つ時間。
単位はミリ秒。デフォルトは60000(= 60秒 = 1分)。
Write timeout × write_timeout マイクロサービスとのコネクション確立後、リクエストの送信が完了するまで待つ時間。
単位はミリ秒。デフォルトは60000(= 60秒 = 1分)。
Read timeout × read_timeout マイクロサービスへのリクエスト送信完了後、レスポンスの受信が完了するまで待つ時間。
単位はミリ秒。デフォルトは60000(= 60秒 = 1分)。

取り急ぎマイクロサービスを手っ取り早く登録したいだけであれば、マイクロサービスのURLをそのままUrlフィールドに入力するだけで大丈夫ですが、今回は下図のように8000番ポートへの"/clock"というpathでマイクロサービスへリクエストするように明示的に各フィールドに指定しました。

Name: ClockService

Description: 時間を取得するAPI(協定世界時)

Tags: clock, 協定世界時

Protocol: http

Host: (下図ではマスクしていますが、ご利用環境に合わせてマイクロサービスのホスト名/IPアドレスを指定してください)

Port: 8000

Path: /utc

この時、Tagsフィールドへの入力時は、入力したタグ文字列毎にエンターキーでの確定が必要です。(エンターキーで確定せず、フィールドに記入しただけの状態で「SUBMIT SERVICEW」ボタンを押しても登録されません)


最後に「SUBMIT SERVICE」ボタンをクリックしてServiceの登録の完了となり、Service一覧画面には登録されたServiceが表示されるようになります。


登録したServiceの詳細を見たい又は編集したい場合は、「NAME」列のService名をクリックすることで詳細・編集画面が表示されます。

3.2. Route の登録

マイクロサービスをServiceに登録したので、残るはユーザーからのアクセス方法となるRouteの登録のみです。

先ほどのService詳細画面にある「Routes」をクリックして登録画面を表示させます。(まだRouteを登録していないので「no data found」と表示されます)


次に「ADD ROUTE」ボタンをクリックして以下のような登録モーダルを表示させます。


各入力フィールドついては以下の表にまとめました。参考までに、直接KongのAPIを使用してRouteを登録する際のパラメータに対応する項目である場合は「APIパラメータ名」列に記載しています。

フィールド名 必須 APIパラメータ名 説明
Hosts hosts 入力した文字列がユーザーからのリクエストURLのhost部分に合致した場合にこのRouteが使用されます。
Paths、Methodsフィールドが未指定の場合のみ必須。未入力の場合はKongサーバのhostが指定されたと見なされます。
Paths paths 入力した文字列がユーザーからのリクエストURLのpath部分に前方一致した場合にこのRouteが使用されます。
"/"から始まる必要があり、"/abc"を指定した場合、"/abc"、"/abc/def"というユーザーからのリクエストにはマッチしますが、"/abcd/ef"にはマッチしません。
Hosts、Methodsフィールドが未指定の場合のみ必須。未入力の場合はルート「/」が指定されたと見なされます。
Methods methods 入力した文字列がユーザーからのリクエストのメソッドに合致した場合にこのRouteが使用されます。
選択肢はGET、POST、PUT、DELETE、CONNECT、HEAD、OPTIONS、TRACE。
Hosts、Pathsフィールドが未指定の場合のみ必須。未入力の場合、すべてのメソッドが指定されたと見なされます。
Strip Path × strip_path ユーザーからのリクエストURLのpathから、Pathsフィールドで指定された文字列を取り除いた上で、Serviceに登録されているPathに追加するかどうか。
選択肢はYESかNOのみ。デフォルトはYES(取り除く)。

例)
ServiceのPathに"/x/y/z"が登録されており、RouteのPathsに"/a/b/c"が登録されている場合、ユーザーからのリクエストURLのpathが"/a/b/c/d/e/f"の時に最終的にマイクロサービス側に届くpathは
  YESの場合: /d/e/f/x/y/z (←"/a/b/c"が取り除かれる)
   Noの場合: /a/b/c/d/e/f/x/y/z
となります。
Preserve Host × preserve_host マイクロサービスへのリクエストのHostヘッダを、ユーザーからのリクエストURLのhost部分とport部分のままにするかを指定する。
選択肢はYESかNOのみ。デフォルトはNO(指定しない)。
システム構成図の例の場合で言えば
  Yesの場合: Hostヘッダが「hostX」(Routeへのリクエストにポート番号portXも指定されている場合はhostX:portX)に置き換わる
   Noの場合: Hostヘッダも接続先と同じ「hostA:PortA」のまま
Protocols × protocols マイクロサービスAPIとの接続に使用するプロトコル。
選択肢はhttpとhttpsのみ。デフォルトはhttpとhttpsの両方が登録される。

取り急ぎマイクロサービスを手っ取り早く登録したいだけであれば、指定したいpathを1つPathsに登録するだけで大丈夫ですが、今回は下図のようにhttpプロトコルによる"/clock"というpathへのGETリクエストをマッチさせるように明示的に各フィールドに指定しました。

Hosts: (下図ではマスクしていますが、ご利用環境に合わせてKongサーバのホスト名/IPアドレスを指定してください)

Paths: /clock

Methods: GET

Protocols: http

Service登録時の「Tags」と同様に、Hosts、Paths、Methods、Protocolsの各フィールドは複数入力が可能なため、1項目ごとにエンターキーを押す必要があります。


最後に「SUBMIT ROUTE」ボタンをクリックしてRouteの登録の完了となり、Route一覧画面には登録されたRouteが表示されるようになります。


登録したRouteの詳細を見たい又は編集したい場合は、「EDIT」ボタンをクリックすることで詳細・編集画面が表示されます。

3.3. 動作確認

以上でServiceとRouteの登録が完了したので、実際に動作確認を行います。

今回登録した内容に沿って以下のようにcurlコマンドでGETリクエストを出してみると、現在時刻が格納されたレスポンスを受信できることを確認できます。([host:port]の部分はご利用環境に合わせてKongサーバのホスト名とポートを指定してください)

[bluerabbit]# curl http://[host:port]/clock
2018/08/30 03:00:09

続いてPOSTでリクエストを出してみたところ、ボディに「no route and no API found with those values」というエラーメッセージが格納がされたレスポンスを受信しました。

[bluerabbit]# curl -X POST http://[host:port]/clock
{"message":"no route and no API found with those values"}

これはマイクロサービス自体はPOSTメソッドを受け入れるようになっていますが、KongにはGETメソッドのみ通過できるように制限していたためです。

POSTメソッドを許可するためにRouteの詳細画面でMethodsにPOSTを追加してみます。


この設定で再度リクエストを出すと時刻が取得できるようになったことを確認できます。

[bluerabbit]# curl -X POST http://[host:port]/clock
2018/08/30 03:19:04

次にRouteに新しいpathを追加し、"/clock"とは別の"/time"というpathでもマイクロサービスを利用できるようにしてみます。

Route詳細画面に遷移し、Pathsに「/time」を追加してみます。


これで"/time"にリクエストを出しても時刻が取得できるようになりました。複数のURLに対して同じマイクロサービスを割り当てられていることがわかります。

[bluerabbit]# curl http://[host:port]/time
2018/08/30 03:26:38