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

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

サイドカーの設定は二回に分けて入ってくる

TT Labで続きを見る

一言でいうと

サイドカーコンテナが起動するのはEnvoyではなくpilot-agentです。pilot-agentが、コンテナの引数・環境変数・メッシュ設定を集めて、ブートストラップを1枚書き、その1枚には、このプロキシは誰か(node)と、設定をどこから受け取るか(xds-grpc)の2つだけが入っています。残りはすべてistiodから受け取ります。

なぜ必要なのか

Envoyは設定ファイル1枚で起動します。しかし、メッシュのプロキシ数千個に、それぞれ違う設定ファイルを、あらかじめ焼いておくことはできません。Podごとに、IPも名前も違い、サービスが増えるたびに、すべてのファイルを書き直す必要があります。そのためIstioは、設定を2つに分けました。Podが起動するときに決まる小さなブートストラップと、起動した後でistiodから受け取る残りのすべてです。

こう分けると、新しい種類の故障が生まれます。ブートストラップが間違っていれば、プロキシがそもそも起動せず(CrashLoop)、ブートストラップは合っているのにistiodに届かなければ、プロキシは起動しているのに準備ができません(Ready 0/2)。2つの症状を見分けるには、ブートストラップがどこで何から作られるかを知る必要があります。

どう動くのか

注入の出力物のistio-proxyは、proxy sidecar --domain $(POD_NAMESPACE).svc.cluster.local …で始まります。$(POD_NAMESPACE)は、シェルの文法ではなく、kubeletが同じ名前の環境変数に置き換えて入れる、Kubernetesの文法です。環境変数は2種類です。CA_ADDR・TRUST_DOMAINのように、注入するときに決まっている値と、Podの名前・ネームスペース・サービスアカウントのように、Podが起動して初めてわかるので、fieldRefで受け取る値です。

pilot-agentは、これらを集めてブートストラップを作ります。

ブートストラップの場所 材料
node.id 役割(sidecar)・Pod IP・<파드이름>.<네임스페이스>・<네임스페이스>.svc.cluster.local(プレースホルダーはPod名とネームスペースです)の4つの欄を、チルダでつないだもの
node.cluster <워크로드>.<네임스페이스>(プレースホルダーはワークロード名とネームスペースです)
node.metadata ISTIO_META_*変数から、プレフィックスを取り除いたもの(CLUSTER_ID、MESH_ID、WORKLOAD_NAMEなど)
static_resources.clusters xds-grpc1つ。メッシュ設定のdiscoveryAddress(デフォルトはistiod.istio-system.svc:15012)
dynamic_resources ADSでCDS・LDSを受け取り、最初の応答まで無限に待つ(initial_fetch_timeout: 0s)

istiodは設定サーバーであり、同時に証明書の発行機関でもあります。そのため、デフォルトのインストールでは、CA_ADDRとdiscoveryAddressが、同じ15012を指します。身元の証明は、2つのボリュームから始まります。audienceがistio-caに絞られたプロジェクテッドサービスアカウントトークンが「私はこのサービスアカウントです」を証明し、istio-ca-root-certConfigMapのルート証明書が、相手が本物のistiodかを確認します。

現場での姿

サイドカーだけがCrashLoopBackOffになる場合。カスタムブートストラップ(sidecar.istio.io/bootstrapOverride)やEnvoyFilterでクラスター名を触って、よく遭遇します。ログの1行目がUnknown gRPC client clusterなら、ADSが指す名前と、静的クラスターの名前がずれています。この種類は、--mode validateで、デプロイ前に弾けます。

Podが1/2 Readyで止まる場合。プロキシは起動しているのに、15021が503を返します。EnvoyがPRE_INITIALIZINGにとどまっているなら、istiodから最初の設定を受け取れていません。ネットワークポリシーが15012を塞いでいる、トークンのaudienceが合わず証明書を受け取れない、istiodが落ちている、のいずれかです。管理ポートはこの状態でも開いているので、control_plane.connected_stateから見ます。

マルチクラスターで設定が混ざる場合。CLUSTER_IDが2つのクラスターで同じだと、istiodが2つのプロキシを区別できず、エンドポイントが入り混じります。ラベルは、設定を選ぶキーです。

公式ドキュメント: pilot-agent・Debugging Envoy and Istiod・Envoy bootstrap

次のラボですること

注入の出力物から引数・環境変数・ボリュームを取り出し、同じ形のブートストラップを手で書いて検査します。クラスター名を1つ間違えて、Envoyが起動する前に拒否されるのを見て、istiodのないPodで、プロキシが準備できないまま待つのを、管理ポートで確認します。