メッシュ導入マニフェストとサイドカーの解剖
目標
メッシュをインストールするときに実際に何がクラスターに入るのかを確認し、サイドカーが注入されたPodが元のPodとどう違うのかを、構造として説明できるようになります。
なぜ重要なのか
メッシュ導入の失敗の多くは、「何がインストールされたのかわからない状態」から始まります。istioctl installの1行で終わるように見えますが、その裏ではCRDが数十個、Webhook設定、ConfigMap、コントロールプレーンのワークロードが一度に入ります。そのため実務では、インストール前にmanifest generateでまず目で見てからリポジトリにコミットする方式を取ります。そうすればアップグレードのときにdiffを見られます。注入も同じです。注入はPodが作成されるときにWebhookがスペックを書き換える処理なので、ラベルだけ付けてロールアウトを実行しなければ、何も起こりません。この事実を手で確認しておけば、「ラベルを付けたのにメッシュに入らない」という質問に数秒で答えられます。
このラボ環境では本物のEnvoyがトラフィックを流しません。そのため採点はマニフェストと静的解析を見ます。その代わり、注入結果のマニフェストを解剖する訓練は、実際の環境でもそのまま役立ちます。
ステップ
istioctl versionの出力を/root/istio/out/version.txtに保存してください(バージョン番号が含まれている必要があります)。続けて、インストール前の点検(istioctl x precheck)を標準エラー出力も含めて/root/istio/out/precheck.txtに保存してください。istioctl manifest generateの結果を/root/istio/manifest.yamlとして保存してください。CustomResourceDefinitionとistiodが含まれていて、kind:で始まる行が10行以上ある必要があります。そのあと、種類別の個数の集計を/root/istio/out/manifest-kinds.txtに保存してください(集計にCustomResourceDefinitionが表示されている必要があります)。- マニフェストをクラスターに適用して、メッシュAPIタイプを登録してください。
virtualservices.networking.istio.io、destinationrules.networking.istio.io、gateways.networking.istio.io、peerauthentications.security.istio.io、authorizationpolicies.security.istio.ioの5つがすべて存在し、istio.ioグループのCRDが5個以上ある必要があります。 - ネームスペース
mesh-labを作成し、ラベルistio-injection=enabledを付けてください。ネームスペースlegacyも作成しますが、注入ラベルは付けないでください。そして/root/istio/out/injection-note.txtに、「ラベルを付けても既存のPodはそのままで、ロールアウトで再作成されて初めてサイドカーが入る」という内容を書いてください。 /opt/lab/fixtures/istio/inject-target.yamlに対してistioctl kube-injectを実行し、結果を/root/istio/injected.yamlとして保存してください。Deploymentのコンテナにpaymentsとistio-proxyが両方あり、初期化コンテナ(istio-initまたはistio-validation)があり、Podテンプレートにsidecar.istio.io/statusアノテーションがある必要があります。istioctl analyze -n mesh-labの結果を/root/istio/out/analyze.txtに保存してください(Error [が残っていてはいけません)。そして/root/istio/out/analyze-note.txtに、analyzeはトラフィックではなく設定を適用の前後に静的に検査する、という内容を2行で書いてください。/root/istio/out/sidecar.jsonを作成してください。キーは、containers(コンテナ名の配列、istio-proxyを含む)、init_containers(1個以上の配列)、container_count(注入後のコンテナ数)、proxy_image(injected.yamlのistio-proxyコンテナのイメージと文字列が完全に一致している必要があります)、interception(トラフィックをどのように横取りするかを1文で。iptablesという単語が入っている必要があります)の5つです。/root/istio/out/mesh-readiness.jsonを作成してください。istio_crds(クラスターのistio.ioグループCRDの実際の個数)、injection_namespaces(注入ラベルが付いたネームスペースの配列。mesh-labはあり、legacyはない必要があります)、analyze_errors(0)の3つのキーです。また、istioctl validate -f /root/istio/injected.yamlの結果を/root/istio/out/validate.txtに保存してください。
参考
- ステップ3:
yq 'select(.kind == "CustomResourceDefinition")' /root/istio/manifest.yaml | kubectl apply -f -でCRDだけを先に適用することもできます。ただし、マニフェストの全体を適用しておくほうが楽です。ステップ5で使う注入設定が、istio-systemのConfigMap2つ(istio-sidecar-injector、istio)に入っているためです。先にkubectl create ns istio-systemを実行してください。 - ステップ5: このラボ環境には本物のistiodのPodがありません。そのため
kube-injectをそのまま実行すると、istiodへのport-forwardを試みて失敗します。ステップ3で適用したConfigMapから、注入テンプレート(.data.config)・メッシュ設定(.data.mesh)・値(.data.values)をそれぞれファイルに取り出し、--injectConfigFile、--meshConfigFile、--valuesFileで渡してください。3つすべてを渡す必要があります。2つしか渡さないと、残りの1つを探して再びクラスターへ向かいます(istioctl kube-inject --helpの例に、この方法がそのまま載っています)。 - ステップ8のCRD数は、手で数えず、
kubectl get crd -o json | jq '[.items[] | select(.spec.group | test("istio.io"))] | length'で取り出してください。 istioctl validateは、通過したときに出力が短かったり空だったりすることがあります。空の場合は、結果を表す1行(검증 통과など。韓国語で「検証通過」を意味する語です)を追記して、ファイルが空にならないようにしてください。- よくある間違い1: ステップ7の
proxy_imageを記憶で書くこと。必ずinjected.yamlから取り出して入れてください。 - よくある間違い2: ステップ4で
legacyネームスペースをそもそも作らないこと。注入されない対照群があって初めて、ラベルの意味が証明されます。
istioctlのバージョンとインストール前点検
istioctl versionの出力を/root/istio/out/version.txtに保存してください(バージョン番号が含まれている必要があります)。続けて、インストール前の点検(istioctl x precheck)を標準エラー出力も含めて/root/istio/out/precheck.txtに保存してください。
istioctl versionはクライアントのバージョンを先に出力します。インストール前の点検はexperimentalのサブコマンドにあり、エラーメッセージも結果なので、標準エラー出力まで一緒に保存してください。
インストール用マニフェストの生成と内容の集計
istioctl manifest generateの結果を/root/istio/manifest.yamlとして保存してください。CustomResourceDefinitionとistiodが含まれていて、kind:で始まる行が10行以上ある必要があります。そのあと、種類別の個数の集計を/root/istio/out/manifest-kinds.txtに保存してください(集計にCustomResourceDefinitionが表示されている必要があります)。
istioctl manifest generateはクラスターに何も作らず、YAMLだけを出力します。何がいくつあるかは、kind:で始まる行を数えればわかります。
メッシュAPIタイプのクラスターへの登録
マニフェストをクラスターに適用して、メッシュAPIタイプを登録してください。virtualservices.networking.istio.io、destinationrules.networking.istio.io、gateways.networking.istio.io、peerauthentications.security.istio.io、authorizationpolicies.security.istio.ioの5つがすべて存在し、istio.ioグループのCRDが5個以上ある必要があります。
VirtualServiceのようなタイプは、CRDとして登録されて初めてkubectlが認識します。マニフェスト全体を適用するか、CustomResourceDefinitionだけを選んで適用してください。Established条件はAPIサーバーが付けてくれます。
注入対象ネームスペースと対照群の作成
ネームスペースmesh-labを作成し、ラベルistio-injection=enabledを付けてください。ネームスペースlegacyも作成しますが、注入ラベルは付けないでください。そして/root/istio/out/injection-note.txtに、「ラベルを付けても既存のPodはそのままで、ロールアウトで再作成されて初めてサイドカーが入る」という内容を書いてください。
ラベルの名前と値が正確でないと、WebhookのnamespaceSelectorに引っかかりません。対照群にはラベルを付けないでください。そして、ラベルがいつ効力を持つのかをメモに書いてください。
フィクスチャのワークロードへのサイドカー注入
/opt/lab/fixtures/istio/inject-target.yamlに対してistioctl kube-injectを実行し、結果を/root/istio/injected.yamlとして保存してください。Deploymentのコンテナにpaymentsとistio-proxyが両方あり、初期化コンテナ(istio-initまたはistio-validation)があり、Podテンプレートにsidecar.istio.io/statusアノテーションがある必要があります。
istioctl kube-injectはファイルを入力として受け取り、注入されたマニフェストを出力します。元のコンテナが消えてはいけませんし、初期化コンテナが1つ増えていれば正常です。
設定の静的分析
istioctl analyze -n mesh-labの結果を/root/istio/out/analyze.txtに保存してください(Error [が残っていてはいけません)。そして/root/istio/out/analyze-note.txtに、analyzeはトラフィックではなく設定を適用の前後に静的に検査する、という内容を2行で書いてください。
analyzeはクラスターの設定リソースを読み、互いに食い違っている箇所を探します。トラフィックを送るわけではないという点が核心で、結果にErrorが残っていてはいけません。
注入結果のJSONによる解剖
/root/istio/out/sidecar.jsonを作成してください。キーは、containers(コンテナ名の配列、istio-proxyを含む)、init_containers(1個以上の配列)、container_count(注入後のコンテナ数)、proxy_image(injected.yamlのistio-proxyコンテナのイメージと文字列が完全に一致している必要があります)、interception(トラフィックをどのように横取りするかを1文で。iptablesという単語が入っている必要があります)の5つです。
目で数えず、注入されたファイルから値を取り出して書いてください。イメージの文字列は、1文字違うだけでも実際の値と異なります。
メッシュ準備状態の要約作成
/root/istio/out/mesh-readiness.jsonを作成してください。istio_crds(クラスターのistio.ioグループCRDの実際の個数)、injection_namespaces(注入ラベルが付いたネームスペースの配列。mesh-labはあり、legacyはない必要があります)、analyze_errors(0)の3つのキーです。また、istioctl validate -f /root/istio/injected.yamlの結果を/root/istio/out/validate.txtに保存してください。
前のステップで作ったものを1つのファイルにまとめます。数値はクラスターで数え直して入れ、注入されないネームスペースが一覧に入ってはいけません。