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

Envoyの内部構造

コントロールプレーンが死ぬと何が止まるのか

TT Labで続きを見る

一言でいうと

xDSは、プロキシが設定を外から受け取る経路です。リスナーを渡すならLDS、クラスターを渡すならCDS、エンドポイントだけを渡すならEDSと呼びます。核心となる性質は2つあります。再起動なしで差し替えられること、そして誤った更新は拒否して、古い設定をそのまま使うということです。

なぜ必要なのか

ここまでの設定はすべて、ファイルに書いてプロセスを起動し直す方式でした。サーバーが数台なら耐えられます。しかしKubernetesでは、Podが1日に何百回も起動したり停止したりします。エンドポイントのリストが変わるたびにプロキシを再起動すると、再起動している間のリクエストはどうなるのか、再起動が再起動を呼ぶ状況をどう防ぐのか。

そこで方向を逆にしました。プロキシはそのままにして、設定だけを送り込みます。プロキシは起動するときに、「私はこういうプロキシです(node)」と自己紹介して、必要なリソースを購読します。コントロールプレーンはクラスターの状態を見ていて、変わったものをそのプロキシへ送ります。これがサービスメッシュのデータプレーンとコントロールプレーンが分かれる場所であり、Ingressコントローラーがしていることのすべてでもあります。

どう動くのか

何を渡すかで名前が分かれます。

名前 渡すもの いつ変わるか
LDS リスナー ポートやフィルターチェーンが変わるとき
CDS クラスター サービスが増減するとき
EDS エンドポイントだけ Podが起動・停止するとき(最も頻繁)
RDS ルート表 ルーティング規則が変わるとき
SDS 証明書 証明書が更新されるとき

エンドポイントが別にある理由は、最も頻繁に変わるからです。Pod1つが起動するたびに、クラスター定義全体を送り直すのは無駄です。

受け取る方法は3つあります。gRPCでストリームを開いておく方式が実際のメッシュが使うもので、RESTで定期的に問い合わせる方式もあり、ファイルを購読する方式もあります。最後のものは実験とテストに使われますが、プロトコルの本質(購読・更新・拒否・バージョン)は3つとも同じです。

更新はアトミックで、失敗したら元に戻します。これがxDSで最も重要な性質です。受け取った設定がスキーマに合わない、または解釈できない場合、プロキシはその更新全体を拒否し、最後に成功した設定をそのまま使います。トラフィックは途切れません。そのため、「コントロールプレーンが死んだらメッシュが死ぬ」という言い方は正確ではありません。新しい設定を受け取れないだけで、現在の設定では動き続けます。

その代わり、誰も知らせてくれません。そのため、監視する数字が決まっています。

cluster_manager.cds.update_success     갱신이 도착해 반영된 횟수
cluster_manager.cds.update_rejected    도착했지만 거절된 횟수
listener_manager.lds.update_success    리스너 쪽 같은 숫자

update_successが止まっていれば、設定が来ていないということで、update_rejectedが上がっていれば、来てはいるのに受け入れられないということです。この2つはまったく別の問題で、直す場所も違います。

届いたかを確認する場所も別にあります。/config_dumpは、静的リソースと動的リソースを分けて見せます(static_clustersとdynamic_active_clusters)。「自分が送った設定が届いたか」を見るときは、動的なほうを見ます。

現場での姿

「設定を変えたのに反映されません」という場合は、2つに分かれます。動的側のダンプになければ届いていないということで(購読・接続の問題)、あるのに動作が違うなら、設定そのものが意図と違うのです。この2つを先に分ければ、探す範囲が半分に減ります。

「コントロールプレーンを再起動したら、何も起きませんでした」。正常です。プロキシは最後の設定を持ったまま動き続けます。問題は、その状態が長く続くと、新しく起動したPodがメッシュに参加できないことです。いま問題ないという事実と、まもなく問題になるという事実が、両方とも真です。

拒否が静かに積もる場合。コントロールプレーンが作った設定に問題が生じても、トラフィックは流れるので誰も気づきません。数週間後に「このサービスだけ古いルーティングで行きます」として表に出ます。update_rejectedにアラートを設定しておくのが答えです。

公式ドキュメント: xDS REST and gRPC protocol・Bootstrap configuration・Administration interface

次のラボですること

静的設定がファイルを直しても変わらないことを最初に確認した後、同じプロキシをファイル購読方式に変えます。クラスターのリソースからエンドポイントを外して、再起動なしで反映されるのを数え、リスナーのリソースも無停止で差し替え、最後にわざと壊した設定を送って、拒否されてもトラフィックが流れ続けるのを自分で確認します。そして、その出来事がどの数字に残るかを確認します。

このラボ環境には、本物のgRPCコントロールプレーンがないため、ファイル購読で代用します。送る内容の形とプロキシの処理方式は同じですが、接続が切れたときの再購読のような、トランスポート層の動作は、ここでは見られません。