今回は「Try Envoy」の「File Based Dynamic Routing Configuration」を紹介する.今までの内容は envoy.yaml
に static な設定をしていたけど,設定を dynamic に反映できる Envoy の「ディスカバリサービス (xDS)」を学べる.また Envoy は xDS として「File Based(ファイル)」と「API Based(REST / gRPC)」をサポートしている.今回は「File Based」を試す.
File Based Dynamic Routing Configuration
手順は以下の「計8種類」ある.それでもなお「Estimated Time: 10 minutes」と書いてあって,雑すぎるでしょ!
- Step.1 「Envoy Dynamic Configuration」
- Step.2 「Cluster ID」
- Step.3 「EDS Configuration」
- Step.4 「EDS Configuration」
- Step.5 「Start Envoy」
- Step.6 「Apply Changes」
- Step.7 「CDS Configuration」
- Step.8 「CDS Apply Changes」
Step.1 「Envoy Dynamic Configuration」
Envoy には,今まで使ってきた static な設定以外に dynamic な設定があり,「ディスカバリサービス (xDS)」と言う.xDS と言われている通り,様々な種類がある.今回のコンテンツでは「EDS / CDS / LDS」を試す.
- EDS (Endpoint Discovery Service)
- CDS (Cluster Discovery Service)
- RDS (Route Discovery Service)
- LDS (Listener Discovery Service)
- SDS (Secret Discovery Service)
ドキュメントを読むと,コンテンツに載っている xDS 以外にも種類があった.例えば,以下など.
- VHDS (Virtual Host Discovery Service)
- SRDS (Scoped Route Discovery Service)
- RTDS (RunTime Discovery Service)
Step.2 「Cluster ID」
最初に envoy.yaml
に node
を設定する.この設定は今までのコンテンツには出てこなかった.xDS を使うときに Envoy 自体を識別する ID となり,今回は適当に id_1
とした.
node: id: id_1 cluster: test
Step.3 「EDS Configuration」
今までは envoy.yaml
の clusters
に転送するホストを static に設定していたけど,今回は EDS (Endpoint Discovery Service) を使うため eds_config
に eds.conf
を指定する.ファイル自体は Step.4 で作成する.
clusters: - name: targetCluster connect_timeout: 0.25s lb_policy: ROUND_ROBIN type: EDS eds_cluster_config: service_name: localservices eds_config: path: '/etc/envoy/eds.conf'
今回は「File Based」なので path
を指定した.もし api_config_source
を指定すると「API Based」になる.
Step.4 「EDS Configuration」
次に eds.conf
を作成する.まず,エンドポイントを1個にして,IP アドレスを 172.18.0.3
にする.
{ "version_info": "0", "resources": [{ "@type": "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment", "cluster_name": "localservices", "endpoints": [{ "lb_endpoints": [{ "endpoint": { "address": { "socket_address": { "address": "172.18.0.3", "port_value": 80 } } } }] }] }] }
Step.5 「Start Envoy」
実際に Envoy と katacoda/docker-http-server
を起動し,以下の構成図のようになる.
$ docker run --name=proxy-eds-filebased -d \ -p 9901:9901 \ -p 80:10000 \ -v /root/:/etc/envoy \ envoyproxy/envoy:latest $ docker run -d katacoda/docker-http-server $ docker run -d katacoda/docker-http-server
eds.conf
にエンドポイントを1個しか設定していないため,何度リクエストを送っても,特定のコンテナに転送される.
$ curl localhost <h1>This request was processed by host: c9d6a2229f32</h1> $ curl localhost <h1>This request was processed by host: c9d6a2229f32</h1> $ curl localhost <h1>This request was processed by host: c9d6a2229f32</h1>
Step.6 「Apply Changes」
eds.conf
を修正し,エンドポイントを2個にする.以下の構成図のようになる.
{ "version_info": "0", "resources": [{ "@type": "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment", "cluster_name": "localservices", "endpoints": [{ "lb_endpoints": [{ "endpoint": { "address": { "socket_address": { "address": "172.18.0.3", "port_value": 80 } } } }, { "endpoint": { "address": { "socket_address": { "address": "172.18.0.4", "port_value": 80 } } } }] }] }] }
修正した eds.conf
を Envoy に自動的に反映するために mv
コマンドを使ってファイルを差し替える.ドキュメントにも記載がある通り,Envoy はファイルの mv
を監視している.
# Envoy will only watch the file path for moves. $ mv eds.conf tmp; mv tmp eds.conf
直後に Envoy にリクエストを送ると,Envoy コンテナを再起動せずに eds.conf
を反映できた.
$ curl localhost <h1>This request was processed by host: c9d6a2229f32</h1> $ curl localhost <h1>This request was processed by host: edd664e9d604</h1> $ curl localhost <h1>This request was processed by host: c9d6a2229f32</h1> $ curl localhost <h1>This request was processed by host: edd664e9d604</h1>
Step.7 「CDS Configuration」
最後 2 Steps は CDS (Cluster Discovery Service) と LDS (Listener Discovery Service) を試す.まず,CDS の設定となる cds.conf
を作成する.既に作成した EDS と連携している.
{ "version_info": "0", "resources": [{ "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "targetCluster", "connect_timeout": "0.25s", "lb_policy": "ROUND_ROBIN", "type": "EDS", "eds_cluster_config": { "service_name": "localservices", "eds_config": { "path": "/etc/envoy/eds.conf" } } }] }
次に LDS の設定をする lds.conf
を作成する.今まで envoy.yaml
に設定していた filters
を LDS に移したイメージとなる.
{ "version_info": "0", "resources": [{ "@type": "type.googleapis.com/envoy.api.v2.Listener", "name": "listener_0", "address": { "socket_address": { "address": "0.0.0.0", "port_value": 10000 } }, "filter_chains": [{ "filters": [{ "name": "envoy.http_connection_manager", "config": { "stat_prefix": "ingress_http", "codec_type": "AUTO", "route_config": { "name": "local_route", "virtual_hosts": [{ "name": "local_service", "domains": [ "*" ], "routes": [{ "match": { "prefix": "/" }, "route": { "cluster": "targetCluster" } }] }] }, "http_filters": [{ "name": "envoy.router" }] } }] }] }] }
最後に新しく envoy1.yaml
を作成し,cds.conf
と lds.conf
を設定している.全てを dynamic_resources
の中に設定したため,とてもシンプルになった.おおおー!
node: id: id_1 cluster: test dynamic_resources: cds_config: path: "/etc/envoy/cds.conf" lds_config: path: "/etc/envoy/lds.conf"
既に Envoy を起動しているため,今回は 81 Port で新しい Envoy を起動する.特に挙動は変わらないけど,以下の構成図のようになる.
docker run --name=proxy-eds-cds-lds-filebased -d \ -p 9902:9901 \ -p 81:10000 \ -v /root/:/etc/envoy \ -v /root/envoy1.yaml:/etc/envoy/envoy.yaml \ envoyproxy/envoy:latest $ curl localhost:81 <h1>This request was processed by host: c9d6a2229f32</h1> $ curl localhost:81 <h1>This request was processed by host: edd664e9d604</h1> $ curl localhost:81 <h1>This request was processed by host: c9d6a2229f32</h1> $ curl localhost:81 <h1>This request was processed by host: edd664e9d604</h1>
Step.8 「CDS Apply Changes」
最後は cds.conf
と lds.conf
を修正して Envoy に反映する.まず,新しく cds.conf
に Cluster newTargetCluster
を追加する.
{ "version_info": "0", "resources": [{ "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "targetCluster", "connect_timeout": "0.25s", "lb_policy": "ROUND_ROBIN", "type": "EDS", "eds_cluster_config": { "service_name": "localservices", "eds_config": { "path": "/etc/envoy/eds.conf" } } }, { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "newTargetCluster", "connect_timeout": "0.25s", "lb_policy": "ROUND_ROBIN", "type": "EDS", "eds_cluster_config": { "service_name": "localservices", "eds_config": { "path": "/etc/envoy/eds1.conf" } } } ] }
Cluster newTargetCluster
から転送されるエンドポイントも新しく eds1.conf
として設定する.
{ "version_info": "0", "resources": [{ "@type": "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment", "cluster_name": "localservices", "endpoints": [{ "lb_endpoints": [{ "endpoint": { "address": { "socket_address": { "address": "172.18.0.6", "port_value": 80 } } } }, { "endpoint": { "address": { "socket_address": { "address": "172.18.0.7", "port_value": 80 } } } } ] }] }] }
lds.conf
は Cluster を newTargetCluster
に変更しておく.
"route": { "cluster": "newTargetCluster" }
修正した cds.conf
と lds.conf
を mv
コマンドを使って差し替える.すると,自動的に新しく起動した katacoda/docker-http-server
に接続できるようになった.
$ docker run -d katacoda/docker-http-server $ docker run -d katacoda/docker-http-server $ mv cds.conf tmp; mv tmp cds.conf; mv lds.conf tmp; mv tmp lds.conf $ curl localhost:81 <h1>This request was processed by host: beac7d8bc5d3</h1> $ curl localhost:81 <h1>This request was processed by host: 8d90f60e8a19</h1> $ curl localhost:81 <h1>This request was processed by host: beac7d8bc5d3</h1> $ curl localhost:81 <h1>This request was processed by host: 8d90f60e8a19</h1>
最終的に構成図は以下のようになる.
まとめ
- 「Try Envoy」のコンテンツ「File Based Dynamic Routing Configuration」を試した
- Envoy でサポートされている「ディスカバリサービス (xDS)」の一部を学べた
- EDS (Endpoint Discovery Service)
- CDS (Cluster Discovery Service)
- LDS (Listener Discovery Service)
- 次は 「API Based」な xDS を試すために「API Based Dynamic Routing Configuration」をまとめる!
プルリクエスト
試しながら気付いた誤りを修正してプルリクエストを送っておいた!