Open4
Cloud Run のサイドカー Envoy でリクエスト URL を操作したい

目的
Cloud Run の Sidecar 機能を使い、 リクエスト URL を Envoy で書き換えてからアプリケーションに渡したい

そもそも Envoy が分かっていないので ChatGPT に聞いてみた
Envoy とは?
Envoyは、高パフォーマンスなエッジおよびサービスプロキシであり、クラウドネイティブアプリケーションのために設計されています。簡単に言えば、Envoyはトラフィックを受け取り、何らかの基準やルールに基づいてそのトラフィックを別の場所にルーティングするソフトウェアです。
主な特長
- パフォーマンス: EnvoyはC++で書かれており、非常に高速です。
- 動的な設定: サービスディスカバリ、ロードバランシング設定、ルーティング設定など、多くの設定を動的に変更可能です。
- 多機能: リトライ、タイムアウト、回路ブレーカー、アクセスログ、トレーシングといった多くの機能が組み込まれています。
- オブザーバビリティ: 詳細な監視メトリクスやトレーシング情報を提供します。
- L7フィルタ: HTTPやgRPCなどのレイヤ7のプロトコルに対するフィルタリングや操作が可能です。
主な用途
- エッジプロキシ: 外部からのトラフィックを受け取るフロントエンドのプロキシとして機能します。
- サービスメッシュ: マイクロサービス間の通信を管理し、トラフィックをルーティング、バランシング、セキュアにする役割を果たします。例えば、IstioのデータプレーンとしてEnvoyが使用されています。
- API Gateway: 外部のクライアントが内部のサービスやAPIにアクセスする際の入り口として機能します。
基本的なコンセプト
- Listener: トラフィックを受け取るための設定。IPアドレスとポートを指定して、どのようなトラフィックを受け入れるかを定義します。
- Cluster: トラフィックを転送する先のサービスやバックエンドの集合です。これにはロードバランシングの設定やサービスディスカバリの方法などが含まれます。
- Route: どのようなトラフィックをどのClusterにルーティングするかを定義する設定です。
総合的に見ると、Envoyはマイクロサービスやクラウドネイティブアプリケーションのトラフィックを効果的にルーティングし、管理するための強力なツールとなっています。
公式ドキュメント も読んでみたが、雰囲気だけ理解した。
色々な機能があるようだが、今回のユースケースである「アプリケーションの前段で HTTP リクエストを受けてその URL を書き換える」リバースプロキシ的な処理は実現できそうなことはわかった。

Envoy の用語説明
- Host
- ネットワーク通信が可能なエンティティ
- いわゆるサーバーやアプリケーションのことっぽい
- Downstream
- Envoy に対してリクエストを送り、レスポンスを受け取る側
- Upstream
- Envoy からリクエストを受け取り、レスポンスを返す側
- Listener
- Downstream クライアントが接続可能なネットワークロケーション(?)
- port, unix domain socket 等
- Cluster
- Envoy が接続する Upstream ホストのグループ
- サービスディスカバリを通じて接続先を見つける

とりあえず /pr-1234/path/to/page
を /path/to/page
にリライトする Envoy 設定ファイルは書けた(もっと簡単に書けるかもだけど)
static_resources:
listeners:
- name: listener_0
address:
socket_address: { address: 0.0.0.0, port_value: 80 }
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match:
safe_regex:
google_re2: {}
regex: "^/pr-[0-9]+/(.*)"
route:
cluster: backend
regex_rewrite:
pattern:
google_re2: {}
regex: "^/pr-[0-9]+/(.*)"
substitution: '/\1'
- match:
safe_regex:
google_re2: {}
regex: "^/pr-[0-9]+(.*)"
route:
cluster: backend
regex_rewrite:
pattern:
google_re2: {}
regex: "^/pr-[0-9]+(.*)"
substitution: '/\1'
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: backend
connect_timeout: 0.25s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: backend
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address: { address: CONAINER_NAME, port_value: PORT_VALUE }