Kong Gatewayを使ってトラフィックをプロクシする場合、一般的には以下のようにKong Gateway内にRouteとServiceのエンティティを定義してトラフィックを転送する。
しかし、負荷分散のためにService AとBにアクセスしたい場合、Serviceで直接複数の宛先を指定することは出来ないため、Serviceだけでは分散構成が作れない。
Kong Gatewayでは分散構成を取る場合、Upstreamと呼ばれるエンティティを作成して、その中にTargetと呼ばれる実際の宛先を指定して実現する。
今回はこれの設定方法と挙動を確認する。
前提
以下があるものとして進める。
- Kong Gateway
- Kong Manager
検証で使ったKong Gateway、Kong Managerはこちらの方法で構築したものを利用した。
設定方法についてはAdminAPI、Deckを使ったCLIでの設定方法もあるが、ここではKong ManagerによりUIで設定する。
CLIの設定方法が気になる方は公式ドキュメントのLoad Balancingのページが参考になると思う。
検証のための設定
httpbin.orgとhttpbun.comはそれぞれリクエストのチェックに使えるWebサイトで、
https://httpbin.org/anythingとhttps://httpbun.com/anythingにアクセスすると、HTTPリクエストの内容をそのまま返してくれる。
"args": {},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Host": "httpbin.org",
:(省略)
"method": "GET",
"args": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip",
"Host": "httpbun.com",
:(省略)
今回は<Kong GatewayのProxy>/apicheck
にアクセスすると、それぞれhttpbin.org、httpbun.comに分散するよう設定する。
ServiceとRouteの作成
最初にServiceを作成する。
通常はServiceのUpstream URL
にhttpbin.org等を設定するが、今回はUpstreamエンティティの中のTargetで設定するため、実際のホスト名を指定する必要はない。
今回はName
をdummy-service
とし、Upstream URL
をhttps://dummy.vhost
とした。
次にRouteを作成する。
こちらでは先程作成したServiceに紐づけて/apicheck
というパスにアクセスすると先程のServiceを参照するように設定する。
ここではName
をapicheck-route
とし、Pathsを/apicheck
とした。
UpstreamとTargetの作成
UpstreamエンティティはGateway Services
やRoutes
と同じようにKong Managerの左サイドバーから選択して作成することが出来る。
左サイドバーのUpstream
を選択し、Name
で先ほど作成したServiceが選択できるようになっているので選択してSaveする。
なお、ここでは細かい説明は省略するが、以下のようなものも設定できるようになっている。
- 分散アルゴリズム:
Round Robin
、Least Connections
、Consistent Hashing
、Latency
から選択可(デフォルトはRound Robin) - Hashに何を使うか:
Consumer
、IP
、Header
、Cookie
、Path
から選択可 - パスの健全性チェックやサーキットブレーカーの有効・無効
- 健全性チェック時の健全・不健全の定義
詳細な情報が必要な人はAdvanced Load Balancingあたりのページを参照すると良いと思う。
最後にTargetを作成してRouteとエンドポイントのサービス(httpbin.org、httpbun.com)を繋ぐ。
作成後、作成したUpstreamをクリックして、Targets
->New Target
を選択する。
するとTarget Addressを入力する画面に遷移するので、httpbin.orgのパスを以下のように作成する。
- Target Address:httpbin.org:443
- Weight:100(デフォルト値)
- Tags:空(デフォルト値)
注意点としては、Target Addressではポートを指定しないとデフォルトで8000番を指してしまう点と、Weightはパーセンテージではなく数値である点は気にしておいた方がよい。
作成後、同じ要領でhttpbun.comに対してもTargetを作成する。
- Target Address:httpbun.org:443
- Weight:100(デフォルト値)
- Tags:空(デフォルト値)
Weightを同値にしているので、おおよそ同じ割合でそれぞれの宛先に分散するはずだ。
以上で設定は終了となる。
検証
作成したRouteに以下のようなcurlコマンドで何度かアクセスしてみる。
curl localhost:8000/apicheck/anything
実行するとリクエストの内容が確認できる。
curl localhost:8000/apicheck/anything
{
"args": {},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Host": "httpbin.org",
"User-Agent": "curl/8.7.1",
"X-Amzn-Trace-Id": "Root=1-66cd259a-55717d764f2154693d29a442",
"X-Forwarded-Host": "localhost",
"X-Forwarded-Path": "/apicheck/anything",
"X-Forwarded-Prefix": "/apicheck",
"X-Kong-Request-Id": "12378b7549a1a531baea7f7e72b9bf7b"
},
また、"Host"
がhttpbin.orgになったりhttpbun.comになったりと、宛先が切り替わっていることも確認できる。
$ for((i=0;i<10;i++)); do curl -s localhost:8000/apicheck/anything ; done | grep \"Host\"
"Host": "httpbin.org",
"Host": "httpbin.org",
"Host": "httpbun.com",
"Host": "httpbin.org",
"Host": "httpbun.com",
"Host": "httpbin.org",
"Host": "httpbun.com",
"Host": "httpbun.com",
"Host": "httpbin.org",
"Host": "httpbun.com",
リクエストが分散して転送されていることが確認できた。
最後に
このようにUpstreamとTargetを使うと、Pluginを使わなくても分散処理が簡単に使えることが確認できた。
ただ、カナリアリリースなど特定のユーザを特定のバージョンに流したり、一定期間後に特定のバージョンを使用不可にするような用途で使うのは難しいので、あくまでも負荷分散のために利用し、カナリアリリースのようなユースケースでは専用のPluginを使った方がよい。