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

Istioサービスメッシュ

プロキシをポッドから外すと — アンビエントの構成要素と二つの層

TT Labで続きを見る

目標

アンビエントプロファイルをレンダリングして、サイドカーモードと構成要素を見比べ、ネームスペースのラベルでデータプレーンを選ぶ方法と、2つのラベルを重ねたときにアナライザーが何を検出するかを確認します。waypointマニフェストを生成してフィールドを読み、このクラスターで適用がなぜ失敗するのかまで、直接見ます。最後に、ネームスペースをモード別に数える点検表を作ります。

なぜ重要なのか

アンビエントは、プロキシをPodから切り離して、ノードに移す設計です。得られるものは明確です。Podごとにプロキシがないのでリソースが減り、ワークロードを再起動せずに、メッシュに入れたり外したりできます。その代わり、機能が2つの層に分かれます。ノードのL4プロキシだけでできるのは、相互認証とL4認可までで、HTTPパスに基づくルーティングや、メソッド単位の認可のように、リクエストの内容を見る必要がある作業には、waypointという別のL7プロキシが必要です。そのため、移行計画は「サイドカーをオフにしよう」ではなく、「このネームスペースが使っている機能のうち、L7が必要なものは何か」から始まります。そして、切り替えの最中は、2つのモードが1つのクラスターに共存するので、どのネームスペースがどのモードなのかを、機械が読める形で数えておくことが、人の記憶よりもはるかに信頼できます。

ステップ

  1. /root/ist-ambientを作成して、istioctl manifest generate --set profile=ambientの出力を/root/ist-ambient/ambient.yamlに保存してください。その中のDeploymentとDaemonSetをすべて取り出して、/root/ist-ambient/ambient-workloads.tsvに、<kind>|<이름>の形式で(プレースホルダーは種類名と名前です)ソートして書いてください。
  2. defaultプロファイルもレンダリングして/root/ist-ambient/default.yamlに保存し、2つのレンダリングのServiceAccount名を見比べて、/root/ist-ambient/sa-diff.tsvに、only-ambient\t<이름>とonly-default\t<이름>の行で(プレースホルダーは名前です)ソートして書いてください(両方にあるものは書きません)。
  3. ステップ1のレンダリングから、名前がistioのConfigMapのdata.meshだけを取り出して、/root/ist-ambient/ambient-mesh.yamlに保存してください。そして、そのレンダリングに含まれるConfigMap名をすべて、/root/ist-ambient/ambient-configmaps.txtに1行ずつソートして書いてください。
  4. ネームスペースを2つ作成してください。shop-sidecarにはistio-injection=enabledラベルを、shop-ambientにはistio.io/dataplane-mode=ambientラベルを付けます。そして、2つのネームスペースのラベルをクラスターから読み取って、/root/ist-ambient/ns-labels.tsvに、<네임스페이스>\t<라벨키>=<값>の形式で(プレースホルダーはネームスペースとラベルキーと値です)ソートして書いてください。
  5. ネームスペースshop-bothを作成して、istio-injection=enabledとistio.io/dataplane-mode=ambientを両方付けてください。istioctl analyze -n shop-both -o jsonの出力を/root/ist-ambient/analyze-conflict.jsonに保存してください。IST0123が出る必要があります。そのあと、サイドカー側のラベルだけを削除して、同じコマンドの出力を/root/ist-ambient/analyze-fixed.jsonに保存してください。今度はIST0123がない必要があります。
  6. istioctl waypoint generate --for service -n shop-ambient --name shop-waypointの出力を/root/ist-ambient/waypoint.yamlに保存してください。そして、そこから読み取った4つを、/root/ist-ambient/waypoint-fields.tsvにapiVersion・gatewayClassName・port・protocolの4行で書いてください。
  7. --for workloadでも一度生成して/root/ist-ambient/waypoint-workload.yamlに保存し、2つのファイルのmetadata.labels."istio.io/waypoint-for"の値を、/root/ist-ambient/waypoint-for.tsvにserviceとworkloadの2行で、<파일이름>\t<값>の形式で書いてください(プレースホルダーはファイル名と値です。名前はshop-waypoint-wlにします)。そのあと、ステップ6のwaypoint.yamlを実際に適用してみて、その結果を/root/ist-ambient/waypoint-apply.txtに保存してください。
  8. /root/ist-ambient/mode-report.shを作成して、クラスターのすべてのネームスペースを<네임스페이스>\t<모드>の形式で名前順に、標準出力にだけ出力するようにしてください(プレースホルダーはネームスペースとモードです)。モードは、2つのラベルが両方あればconflict、アンビエントのラベルだけがあればambient、istio-injectionがenabledならsidecar、それ以外はnoneです。出力を/root/ist-ambient/mode-report.txtに保存してください。

参考

アンビエントプロファイルが何を起動するのかを数える

/root/ist-ambientを作成して、istioctl manifest generate --set profile=ambientの出力を/root/ist-ambient/ambient.yamlに保存してください。その中のDeploymentとDaemonSetをすべて取り出して、/root/ist-ambient/ambient-workloads.tsvに、<kind>|<이름>の形式で(プレースホルダーは種類名と名前です)ソートして書いてください。

アンビエントは、Podごとにプロキシを入れる代わりに、ノードごとに2つを敷きます。トラフィックを横取りするほうと、L4プロキシの役割を果たすほうです。どちらもDaemonSetとして出力されます。レンダリングから取り出すときは、yq -N e 'select(.kind=="DaemonSet") | .metadata.name'のように、種類で絞り込めば済みます。

サイドカーモードと見比べると、身元が2つ増えて1つ減る

defaultプロファイルもレンダリングして/root/ist-ambient/default.yamlに保存し、2つのレンダリングのServiceAccount名を見比べて、/root/ist-ambient/sa-diff.tsvに、only-ambient\t<이름>とonly-default\t<이름>の行で(プレースホルダーは名前です)ソートして書いてください(両方にあるものは書きません)。

構成要素が増えたり減ったりすると、その構成要素が使うサービスアカウントも一緒に動きます。2つのリストをそれぞれソートして、commで比較すれば、片方にだけある名前が出ます。アンビエントには、ゲートウェイが既定でないという点も、ここで見えてきます。

アンビエントのメッシュ設定には、何が追加で有効になっているか

ステップ1のレンダリングから、名前がistioのConfigMapのdata.meshだけを取り出して、/root/ist-ambient/ambient-mesh.yamlに保存してください。そして、そのレンダリングに含まれるConfigMap名をすべて、/root/ist-ambient/ambient-configmaps.txtに1行ずつソートして書いてください。

アンビエントでは、Pod間のトラフィックが、ノードのL4プロキシを通って、トンネルで渡されます。そのトンネルを有効にする値が、プロキシのメタデータに入っているので、defaultConfig.proxyMetadataの下を見てください。ConfigMapの一覧には、サイドカープロファイルになかったものが、もう1つあります。

ネームスペースのラベル1行が、データプレーンを選ぶ

ネームスペースを2つ作成してください。shop-sidecarにはistio-injection=enabledラベルを、shop-ambientにはistio.io/dataplane-mode=ambientラベルを付けます。そして、2つのネームスペースのラベルをクラスターから読み取って、/root/ist-ambient/ns-labels.tsvに、<네임스페이스>\t<라벨키>=<값>の形式で(プレースホルダーはネームスペースとラベルキーと値です)ソートして書いてください。

2つのモードは、別々のラベルキーを使います。サイドカー側は、注入Webhookが見るラベルで、アンビエント側は、ノードのCNIが見るラベルです。kubectl get ns -o jsonにjqを付ければ、ラベルをそのまま取り出せます。

2つのラベルを一緒に付けると、動作が定義されない

ネームスペースshop-bothを作成して、istio-injection=enabledとistio.io/dataplane-mode=ambientを両方付けてください。istioctl analyze -n shop-both -o jsonの出力を/root/ist-ambient/analyze-conflict.jsonに保存してください。IST0123が出る必要があります。そのあと、サイドカー側のラベルだけを削除して、同じコマンドの出力を/root/ist-ambient/analyze-fixed.jsonに保存してください。今度はIST0123がない必要があります。

2つのラベルは、別々の構成要素が読みます。1つは注入Webhook、もう1つはノードのCNIです。両方付くと、そのPodがどちらのデータプレーンを使うのかが決まりません。ラベルを削除するときは、キーの後ろにマイナス記号を付けます。

L7が必要なら、waypointを別に立てる

istioctl waypoint generate --for service -n shop-ambient --name shop-waypointの出力を/root/ist-ambient/waypoint.yamlに保存してください。そして、そこから読み取った4つを、/root/ist-ambient/waypoint-fields.tsvにapiVersion・gatewayClassName・port・protocolの4行で書いてください。

waypointは、Istio専用のオブジェクトではなく、Gateway APIのGatewayとして表現されます。どのゲートウェイクラスなのかが、これをwaypointにします。リスナーのポートとプロトコルは、アンビエントがPod間で使うトンネルそのものです。

何のためのwaypointなのか、そして、なぜここでは適用されないのか

--for workloadでも一度生成して/root/ist-ambient/waypoint-workload.yamlに保存し、2つのファイルのmetadata.labels."istio.io/waypoint-for"の値を、/root/ist-ambient/waypoint-for.tsvにserviceとworkloadの2行で、<파일이름>\t<값>の形式で書いてください(プレースホルダーはファイル名と値です。名前はshop-waypoint-wlにします)。そのあと、ステップ6のwaypoint.yamlを実際に適用してみて、その結果を/root/ist-ambient/waypoint-apply.txtに保存してください。

waypointは、サービスの前に立てることも、ワークロードの前に立てることもできます。ラベル1つが、その範囲を語ります。適用は、このクラスターでは成功しません。なぜそうなるのかは、エラー文がそのまま語ってくれます。

クラスターのネームスペースを、モード別に数える点検表

/root/ist-ambient/mode-report.shを作成して、クラスターのすべてのネームスペースを<네임스페이스>\t<모드>の形式で名前順に、標準出力にだけ出力するようにしてください(プレースホルダーはネームスペースとモードです)。モードは、2つのラベルが両方あればconflict、アンビエントのラベルだけがあればambient、istio-injectionがenabledならsidecar、それ以外はnoneです。出力を/root/ist-ambient/mode-report.txtに保存してください。

kubectl get ns -o jsonを1回実行すれば、すべてのラベルを受け取れるので、jqで振り分けます。ラベルのキーにはドットとスラッシュが混ざっているので、jqでは、角括弧と引用符で取り出すほうが安全です。istio-injectionは、値がdisabledの場合もあるので、有効なものだけを数える必要があります。