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

Istio深化 — なぜそう流れるのか

proxy-config の数百行を表として読む方法

TT Labで続きを見る

一言でいうと

サイドカーのクラスター名は、방향|포트|서브셋|호스트(プレースホルダーは方向、ポート、サブセット、ホストです)の4つの欄で、規則どおりに作られます。DestinationRuleのサブセット1つがクラスター1つになり、統計もエラーメッセージも、すべてこの名前を付けて出てきます。名前を読めれば、proxy-configの出力数百行が、表に見えてきます。

なぜ必要なのか

istioctl proxy-config clusters <파드>(プレースホルダーはPod名です)を初めて開くと、こんな行が延々と出てきます。

outbound|9080||reviews.default.svc.cluster.local
outbound|9080|v1|reviews.default.svc.cluster.local
outbound|9080|v2|reviews.default.svc.cluster.local
inbound|9080||

この名前を読めないと、2つのことができません。1つ目は、「v2へ行くリクエストが、なぜ503なのか」を見るときに、v2サブセットのクラスターがそもそもあるのか、エンドポイントがいくつあるのかを確認できないことです。2つ目は、ダッシュボードのcluster.outbound|9080|v2|…upstream_rq_503のようなメトリクスが、どのサービスの何なのか、わからないことです。Istioは、数千のクラスターを人の手なしで作らなければならないので、名前を規則で決め、その規則がそのまま読み方になります。

どう動くのか

欄 値 空になる場合
方向 outbound(このPodが他を呼ぶとき) / inbound(他がこのPodを呼ぶとき) なし
ポート サービスポート(9080) なし
サブセット DestinationRuleのsubsets[].name サブセットを選ばないデフォルトのクラスター
ホスト サービスのFQDN 入ってくる側(自分のアプリへ送るから)

istiodは、メッシュのサービス・ポートごとに、サブセットのないクラスターを常に作り、DestinationRuleにサブセットがあれば、サブセットごとにもう1つずつ作ります。サブセットクラスターのエンドポイントは、同じサービスのエンドポイントのうち、ラベルが合うものだけを絞り込んだ部分集合です。そのため、ラベルのないPodは、どのサブセットクラスターにも入りません。

VirtualServiceのdestination: {host: reviews, subset: v1}は、ルートがoutbound|9080|v1|reviews…クラスターを指す形に変換されます。ここで、よくある事故が出ます。DestinationRuleにないサブセットを指すと、istiodは、存在しないクラスターを指すルートを送り込みます。Envoyは、動的に受け取ったルートのクラスターを事前に確認しないので(validate_clustersのデフォルトがfalse)、設定は受け入れられ、リクエストが来たときに503が出て、アクセスログにNC(no cluster)が出力されます。ファイルで書いた静的設定は、デフォルトがtrueなので、同じ設定を起動時に拒否します。同じミスが、どこで表に出るかが違うのです。

統計は、cluster.<이름>.<지표>(プレースホルダーはクラスター名とメトリクスです)として積まれます。|の入った名前は、Prometheusのラベルに移すときに面倒なので、メッシュ設定のoutboundClusterStatNameにパターンを与えると、istiodが各クラスターにalt_stat_nameを付けます。ルーティングは元の名前で行い、統計名だけが変わります。

現場での姿

カナリアを設定したら、v2へ行くリクエストだけがすべて503。VirtualServiceを先にデプロイし、DestinationRuleを後でデプロイした場合です。その間の数秒から数分、v2サブセットのクラスターがありません。proxy-config clustersにv2の行があるかを、まず見ます。そのため、順序は常にDestinationRuleが先、VirtualServiceが後です。

サブセットクラスターのエンドポイントが0個。名前はあるのに、proxy-config endpointsが空なら、サブセットのラベルとPodのラベルがずれています(version: v2対version: 2.0)。このとき、レスポンスフラグはNCではなくUH(健全なアップストリームなし)なので、フラグの2文字だけで、「クラスターがない」のか「クラスターはあるが空」なのかを見分けられます。

ダッシュボードが突然空になった。誰かがメッシュ設定のoutboundClusterStatNameを変えると、統計名がまるごと変わって、古い名前で組んだクエリがすべて空になります。ルーティングは問題ないので、ずいぶん後になって見つかります。

公式ドキュメント: Debugging Envoy and Istiod・DestinationRule

次のラボですること

DestinationRuleを書き、規則でクラスター名を4つ導出して、その名前のままEnvoyを立て、サブセットごとにリクエストを分けてみます。統計名をalt_stat_nameで変え、ないサブセットを指して503とno_clusterを作り、サブセットが同じエンドポイントの部分集合であることを、/clustersで数えます。