概要
EnvoyのルーティングはListener > Network filter chain > HCM(HTTP connection manager)
のVirtual Hostで適用されます。
設定の一部は配列で複数設定することができますが、ものによっては
- 一致率が高いものから順に適用する(完全一致→部分一致→ワイルドカードなど)
- 先に設定した順で走査し、マッチしたものを適用する
といった違いがあったりなど、きちんと理解していないとハマることがあるので1つ1つ読み解いていきます。
環境
- Envoy v1.24.0
解説
例えば以下のような設定があるときに「これだけ知っておけばとりあえず大丈夫」な最低限理解しておく必要があるものを書いていきます。
route_config: name: local_route virtual_hosts: - name: local_service domains: ["*"] routes: - name: get match: { prefix: "/get" } route: cluster: httpbin timeout: 30s - name: default match: { prefix: "/" } route: cluster: default_root timeout: 30s
設定項目
よく使うものだけ解説します。それ以外の詳細はリンクのドキュメントを参照してください。
config.route.v3.VirtualHost
項目 | 型 | 説明 | required |
---|---|---|---|
name | string | Virtual Hostの論理名。statsなどで使われる。ルーティング自体とは無関係 | o |
domains | repeated string | ドメイン名。incoming requestと一致するドメインに振り分ける。ワイルドカードが利用でき、走査順は後述。 | o |
routes | repeated config.route.v3.Route | incoming requestに対するルーティングリスト。先頭から順に走査し先に一致したものが適用される。詳細は後述。 | x |
domains
の走査順
以下の順で走査され、一致するものが先に適用されます。
- 完全一致:
www.foo.com
- 後方一致:
*.foo.com
,*-bar.foo.com
- 前方一致:
foo.*
,foo-*
- ワイルドカード:
*
config.route.v3.Route
項目 | 型 | 説明 | required |
---|---|---|---|
name | string | ルーティング名 | x |
match | config.route.v3.RouteMatch | domains で一致したリクエストの内、さらにpathやheaderで一致するものを適用する。詳細は後述 |
o |
route | config.route.v3.RouteAction | リクエストをどのclusterに流すか、timeoutなど設定を行う。詳細は後述 | x |
config.route.v3.RouteMatch
どのルーティングに一致させるかの設定です。
項目 | 型 | 説明 | required |
---|---|---|---|
prefix | string | pathが前方一致するものを対象とする | x |
path | string | pahtが完全一致するものを対象とする | x |
headers | repeated config.route.v3.HeaderMatcher |
headerが一致するものを対象とする。複数ある場合は全て満たすものが対象となる。:method や:path のような予約語もあり、HTTP header以外も設定可能 |
x |
query_parameters | repeated config.route.v3.QueryParameterMatcher |
クエリパラメータが一致するものを対象とする。複数ある場合は全て満たすものが対象となる | x |
RouteMatchは以下の設定の少なくともどれか1つは必要です。
- prefix
- path
- safe_regex
- connect_matcher
- path_separated_prefix
- path_match_policy
通常はprefix
で/
と設定することですべてのリクエストを対象とするパターンを用います。
headers
やqueryparameters
を使うことでABテストを簡単に導入できます。
gRPCのpathを設定するには?
gRPCでは以下の文法で設定します。
/package{.subpackage}.ServiceName/RpcName
ref: https://github.com/grpc/grpc-web/issues/702#issuecomment-588121877
なので
syntax = "proto3"; package helloworld; service Greeter { rpc SayHello(HelloRequest) returns (HelloReply) {} rpc SayHi(HiRequest) returns (HiReply) {} }
といったproto定義であれば以下のようになります。
ケース | 設定方法 |
---|---|
パッケージのみ一致させたい | /helloworld |
gRPCサービス名まで指定したい | /helloworld.Greeter |
gRPCの特定メソッドだけ指定したい | /helloworld.Greeter/SayHello |
一部のメソッドだけretry policyを設定した、timeoutを変更したいといった場合に有用です。
config.route.v3.RouteAction
ルーティング先の設定です。
項目 | 型 | 説明 | required |
---|---|---|---|
cluster | string | clusterディレクティブで定義したcluster名 | x |
timeout | Duration | タイムアウト | x |
prefix_rewrite | string | pathのrewrite処理を適用できる | x |
weighted_clusters | config.route.v3.WeightedCluster | 重み付けした負荷分散が可能 | x |
retry_policy | config.route.v3.RetryPolicy | リトライ方針 | x |
演習
では最初の設定を元に解説を行います。
route_config: name: local_route virtual_hosts: - name: local_service domains: ["*"] routes: - name: get match: { prefix: "/get" } route: cluster: httpbin timeout: 30s - name: default match: { prefix: "/" } route: cluster: default_root timeout: 30s
- domainsはワイルドカードなので全てのincomming requestが一致する
- routesは2つあるので先に一致するものが適用される
/get
というpath prefixを持つものがあればhttpbin clusterに流す- 3以外のリクエストはdefault_root clusterに流す
と読み解けます。
先に一致したものが適用されるので、デフォルトルートは4のように最後に設定するようにしましょう。
サンプルコード
検証するためのサンプルコードです。
可視化のためのPrometheus & Grafanaも付いてます。
まとめ
EnvoyのVirtual Hostについて解説しました。