TT Lab
はじめる
学ぶ 学習パス コース

Envoyの内部構造

起動しない設定は配布の最中に現れる

TT Labで続きを見る

一言でいうと

Envoyは設定ファイル1枚を読み込んでプロセスになります。その1枚は管理ポート・身元・静的リソース・動的リソースの4つの塊で、残りはすべてその中の層です。この構造を指でたどれるようになれば、初めて見る設定でも道に迷いません。

なぜ必要なのか

プロキシの設定が間違っていると、たいてい2つのうちどちらかが起こります。1つはプロセスがそもそも起動しないこと、もう1つは起動はするものの、リクエストが見当違いの所へ行くことです。本番運用で怖いのは前者です。再起動は通常デプロイの最中に起こり、そのときはすでに古いプロセスが落ちた後だからです。@typeの1文字、インデントの1段が、そのまま障害になります。

Envoyはこの問題を知っていて、設定だけを検査するモードを別に用意しています。

envoy --mode validate -c boot.yaml

このコマンドは、設定を最後まで読んでスキーマまで確認したあと、ポートを1つも確保しないまま、終了コードだけを残して終わります。そのため、すでにEnvoyが動いているマシンでも実行でき、コンテナイメージをビルドするCIのステップにも組み込めます。設定を直したのにこのコマンドを実行していないなら、その設定が起動するかどうかは、まだ誰にもわかりません。

どう動くのか

ブートストラップの最上位のキーは、4つだけ覚えれば十分です。

キー 何か ないと
admin 管理ポート。統計・設定ダンプ・ログレベルの変更 のぞく窓がありません
node このプロキシのラベル(id、cluster) 静的設定だけなら問題ありません。xDSをつなぐと必須です
static_resources ファイルに書いておくリスナーとクラスター 何も待ち受けません
dynamic_resources 外から受け取る設定(xDS) 設定が固定されます

static_resourcesの中は、さらに5つの層に分かれています。listener → filter_chain → http_connection_manager → route_config → clusterで、リクエストが入ってくる順序とまったく同じです。アドレスとポートから始まり、どのフィルターチェーンが受けるかを選び、HTTPとして解釈し、ルート表で宛先クラスター名を得て、その名前のクラスターが実際のエンドポイントへ送ります。設定を読むときにこの順序を守れば、どの層が空なのかがすぐに見えます。

ブートストラップに書いたものが実際にそのまま適用されたかは、目で確認しません。管理ポートの/config_dumpの最初の節がBootstrapConfigDumpで、Envoyが読み取った値がそこにそのまま入っています。ファイルとダンプを並べて見る習慣が、「直したのに、なぜ変わらないのか」をなくします。

現場での姿

1台のマシンに2つ目のEnvoyを起動する瞬間。ポートはすべて避けたのに、2つ目のプロセスがunable to bind domain socket with base_id=0で終了します。Envoyは起動するときに共有メモリ領域を1つ確保し(ホットリスタートのときに統計を引き継ぐために使います)、その名前がbase idで決まり、デフォルト値が0だからです。--base-idで分けてやれば、両方とも起動します。同じノードにプロキシを2つ置く構成(1つはイングレス、もう1つはエグレス)では、必ずぶつかります。

管理ポートを外部に開けたままにした事故。admin.addressを便宜上0.0.0.0にしておく場合があります。しかしこのポートには認証がなく、/quitquitquitはプロセスを終了させ、/drain_listenersはトラフィックを切断します。統計を取るために開けた穴が、そのままサービスを落とすボタンになります。管理ポートはループバックにバインドし、必要ならその前に別のプロキシを立てて、読み取り経路だけを公開します。

--concurrencyを知らずに実験する場合。デフォルト値はコア数です。ワーカースレッドごとに負荷分散の状態が別々に動くため、リクエストを8回送ってエンドポイント3つに均等に行ったかを数えると、毎回違う数字が出ます。分配を数える実験は、--concurrency 1で行うと結果が毎回同じになります。

「直したのに変わりません」という場合。static_resourcesに書いたものは、プロセスが起動するときに一度だけ読み込まれます。ファイルを直しても、再起動するまでは何も起こりません。そのため本番運用では、ファイルと/config_dumpを並べて見る習慣が大切です。ダンプになければまだ反映されていないということで、ダンプにあるのに動作が違うなら、そこからは設定ではなく別の層を疑う番です。設定を外から受け取って、再起動せずに変更する方法がdynamic_resources(xDS)で、これはこのコースの最後のモジュールで扱います。

公式ドキュメント: Bootstrap configuration・Command line options・Administration interface

次のラボですること

ブートストラップを手で書いて--mode validateで通し、1文字間違えて拒否されるのを確認します。次に2つ目のEnvoyを起動して--base-idが必要になる場面を実際に体験し、最後に管理ポートでプロセスを終了させてから、もう一度起動します。