紹介

Kong GatewayではRouteでサブパスを定義し、どのServiceにアクセスするかを決めています。例えば、以下のURLの後ろのサブパスがpathAの場合は、トラフィックがserviceAにルーティングされ、最終的に後ろにあるendpointAにアクセスされます。

1
http://mykong.org:8000/pathA => serviceA => endpointA

しかし、サブパスではなくて、もっと動的にリクエストの転送先を決めたい場合があります。このプラグインは、事前に定義されたヘッダーと転送先をルールに、リクエストヘッダ情報を見て転送先を決めています。ルールに二つのパラメータがあり、conditionは定義したヘッダーと値、upstream_nameは転送先のUpstreamオブジェクトです。

1
{"rules":[{"condition": {"location":"us-east"}, "upstream_name": "east.doamin.com"}]}

この記事では、このプラグインの実装についてメモします。 注:このプラグインを操作できるのはAdmin APIを通す方法のみ。Kong Managerでの操作はできない。

https://docs.konghq.com/hub/kong-inc/route-by-header/

デモ

実際にこのプラグインを使ってみましょう。まずは作業用のservicerouteを作成する。serviceのendpointはhttp://httpbin.org/anything となりますが、このプラグインのルールに当てはまらない時にアクセスされます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
curl -i -X POST http://localhost:8001/services \
  --data protocol=http \
  --data host=httpbin.org \
  --date path=/anything
  --data name=demo

curl -i -X POST http://localhost:8001/routes  \
  --data "paths[]=/" \
  --data service.id=<The id of service created above>
  --data name=demo

次に、転送先のUpstreamを二つ用意し、myipdateをそれぞれアクセスするとIPアドレスと時間が表示されます。

1
2
3
4
5
curl -i -X POST http://localhost:8001/upstreams -d name=myip
curl -i -X POST http://localhost:8001/upstreams/myip/targets --data target="ip.jsontest.com:80"

curl -i -X POST http://localhost:8001/upstreams -d name=date
curl -i -X POST http://localhost:8001/upstreams/date/targets --data target="date.jsontest.com:80"

最後はrouteに対してこのプラグインを作ります。

1
2
3
curl -i -X POST http://localhost:8001/routes/demo/plugins \
  -H 'Content-Type: application/json' \
  --data '{"name": "route-by-header", "config": {"rules":[{"condition": {"info":"myip"}, "upstream_name": "myip"}, {"condition": {"info":"date"}, "upstream_name": "date"}]}}'

--dataの部分はJsonで記載した振り分けのルールです。headerにinfo:myipが存在したら、myipのupstreamにふりわけされ、info:dateが存在したら、dateのupstreamに振り分けられます。

検証

リクエストのヘッダーにinfo:myipを設定したら、myipのUpstreamに転送されました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
$ curl -i -X GET http://localhost:8000/ -H "info:myip"
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 24
Connection: keep-alive
Access-Control-Allow-Origin: *
X-Cloud-Trace-Context: d2c85f05ccd0e7d1273aee2476504cac
Date: Wed, 03 Aug 2022 04:23:29 GMT
Server: Google Frontend
X-Kong-Upstream-Latency: 212
X-Kong-Proxy-Latency: 0
Via: kong/2.8.1.2-enterprise-edition

{"ip": "18.181.83.240"}

リクエストのヘッダーにinfo:dateを設定したら、dateのUpstreamに転送されました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
$ curl -i -X GET http://localhost:8000/ -H "info:date"
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 100
Connection: keep-alive
Access-Control-Allow-Origin: *
X-Cloud-Trace-Context: b03d154c04e8d788ae3c0d870ab9c2df
Date: Wed, 03 Aug 2022 04:23:33 GMT
Server: Google Frontend
X-Kong-Upstream-Latency: 214
X-Kong-Proxy-Latency: 0
Via: kong/2.8.1.2-enterprise-edition

{
   "date": "08-03-2022",
   "milliseconds_since_epoch": 1659500613301,
   "time": "04:23:33 AM"
}

リクエストのヘッダーを設定せず、つまりどのルールにも当てはまらない時は、serviceの元のendpoint、http://httpbin.org/anything に転送されました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[ec2-user@ip-10-0-18-228 ~]$ curl -i -X GET http://localhost:8000/
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 419
Connection: keep-alive
Date: Wed, 03 Aug 2022 04:26:05 GMT
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
X-Kong-Upstream-Latency: 335
X-Kong-Proxy-Latency: 3
Via: kong/2.8.1.2-enterprise-edition

{
  "args": {},
  "data": "",
  "files": {},
  "form": {},
  "headers": {
    "Accept": "*/*",
    "Host": "httpbin.org",
    "User-Agent": "curl/7.61.1",
    "X-Amzn-Trace-Id": "Root=1-62e9f8dd-7e352f095824a8b136de808a",
    "X-Forwarded-Host": "localhost",
    "X-Forwarded-Path": "/"
  },
  "json": null,
  "method": "GET",
  "origin": "127.0.0.1, 18.181.83.240",
  "url": "http://localhost/anything"
}