デプロイする前に間違いを見つける
目標
Istioの設定は、文法が合っていても動かない場合がほとんどです。名前が互いを指す構造なので、片方の名前だけが変わっても、静かに切れます。
このラボは、クラスターなしで、デプロイする前に、そうしたものを見つけます。
2つのツールの違い
| 見るもの | 捕まえるもの | |
|---|---|---|
istioctl validate |
1つのファイルの文法 | タイプミス、知らないフィールド |
istioctl analyze |
リソース間の参照 | ないsubset・ゲートウェイ、ホストの衝突 |
Kubernetesは、どちらも捕まえてくれません。CRDスキーマにない知らないフィールドは、静かに捨てられるので、kubectl applyは成功し、トラフィックだけが流れません。
使い方
istioctl validate -f vs.yaml
istioctl analyze --use-kube=false vs.yaml dr.yaml
echo $? # 0 이면 깨끗, 79 면 문제 있음
--use-kube=falseは、クラスターを見ずにファイルだけを見るという意味です。
ステップ
- タイプミス →
01-validate.txt - 参照が壊れたもの →
02-analyze.txt - 直して通す →
vs.yaml、dr.yaml - ホストの衝突 →
04-conflict.txt - ないゲートウェイ →
05-gateway.txt - サイドカーの注入 →
06-inject.txt - analyzeが捕まえられないもの →
07-blind.txt - 整理 →
08-notes.md
参考
ステップ7は、何も問題が出ないのが正解です。静的解析の限界を、自分で見ることが目的です。
タイプミスを捕まえる
フィールド名が間違ったVirtualServiceを作り、istioctl validateで捕まえて、01-validate.txtに残してください。
http:の下をroute:ではなくrout:と書いてみてください。istioctl validate -f x.yamlがunknown field "rout"と教えてくれます。Kubernetesは、これを捕まえてくれません。CRDスキーマにない知らないフィールドは、静かに捨てられるので、applyは成功し、トラフィックだけが流れません。
スキーマは合っているのに、動作は間違っているもの
subset: v1へ送るVirtualServiceだけを作り(DestinationRuleなしで)、istioctl analyzeに捕まえさせて、02-analyze.txtに残してください。
istioctl analyze --use-kube=false vs.yaml。IST0101 Referenced host+subset in destinationrule not foundが出ます。validateは通るのに、analyzeは捕まえます。前者は文法を、後者は参照関係を見ます。Istioで「設定は入れたのに503」になる、1番目の原因です。
直して通す
subsetを定義したDestinationRuleを追加して、istioctl analyzeが終了コード0で終わるようにしてください。ファイル名は、vs.yamlとdr.yamlにします。
DestinationRuleのhostは、VirtualServiceのdestination.hostと同じで、subsets[].nameがdestination.subsetと同じである必要があります。確認: istioctl analyze --use-kube=false vs.yaml dr.yaml; echo $?。0である必要があります(問題があれば79)。
同じホストを2つが握ると
同じホストを指すVirtualServiceをもう1つ作って衝突を起こし、04-conflict.txtに残してください。
IST0109が出ます。「define the same host ... which can lead to undefined behavior」です。どちらが勝つかは、決まっていません。チームが2つに分かれて、それぞれVirtualServiceを作ると、こうなります。解決は、1つにまとめることです。
存在しないゲートウェイを指すと
存在しないゲートウェイを参照するVirtualServiceを作り、05-gateway.txtに残してください。2種類の診断が出る必要があります。
gateways: [nope-gw]。IST0101 Referenced gateway not foundとIST0132(ホストがゲートウェイにない)が一緒に出ます。両方を残してください。
サイドカーが実際にどう作られるか
Deployment1つにサイドカーを注入し、注入後のコンテナ一覧を06-inject.txtに残してください。
このPodには本物のistiodがないので、設定をファイルで渡します。3つがすべて必要です。2つだけ渡すと、istioctlが残りの1つを探して、クラスターへ出ていきます。
istioctl kube-inject -f dep.yaml \
--injectConfigFile /opt/istio/inject-config.yaml \
--meshConfigFile /opt/istio/mesh-config.yaml \
--valuesFile /opt/istio/values-config.yaml
istio-proxyコンテナと、istio-init初期化コンテナが付きます。istio-initは、iptablesを書き換えて、すべてのトラフィックがプロキシを通るようにするほうです。
analyzeが捕まえられないもの
PeerAuthenticationをSTRICTに、同じサービスのDestinationRuleをtls.mode: DISABLEにして、istioctl analyzeを実行し、何も問題が出ないことを07-blind.txtに残してください。なぜ危険かも、1行書いてください。
analyzeはきれいだと言いますが、実際にはサーバーはmTLSを要求するのに、クライアントは平文で接続して、すべて失敗します。静的解析が万能ではないという意味です。ファイルだけを見てもわからず、クラスターの状態と一緒に見る必要があるものがあります。そのため、実務ではistioctl analyzeをクラスターにつないで(--use-kubeのデフォルト)実行します。
3つのことを整理する
08-notes.mdに3行以上書いてください。validateとanalyzeの違い、同じホストの衝突が危険な理由、静的解析が捕まえられないもの1つです。
本文に참조、충돌、mTLSが含まれている必要があります(最初の2つは、韓国語で順に「参照」「衝突」を意味する語です)。