メッシュが実際に強制するものを見る
このラボは本物のIstio上で動きます
VMの中でk3s + Istioが実際に動いています。サイドカーが本当に注入され、 mTLSが本当に強制され、VirtualServiceが本当にトラフィックを振り分けます。
ICAコースのほかのラボは、CRDだけが読み込まれた偽物のクラスターで動きます。そこでは、
kubectl applyが通るだけで、何も起こりません。
最初に起動するまで2–3分かかります。
目標
サイドカーがどこに注入されるかを確認し、mTLSと認可ポリシーが実際に 何を防ぐのかを、応答コードで区別します。
なぜ重要なのか
サービスメッシュの価値は、「設定を書いた」ことではなく、「その設定が強制される」ことです。 ところが、強制されない状態が正常に見えることが、このテーマの落とし穴です。
最もよくあるのが、サイドカーの未注入です。ネームスペースにラベルを付ける前に
作ったPodには、サイドカーがありません。PodはRunningで、サービスも応答します。
ところが、トラフィックがメッシュを通過しないので、mTLSも認可ポリシーもルーティングも、
何も適用されません。セキュリティポリシーをすべて書いておいて、何も守られていない
状態になります。
そして最近は、確認の方法自体が変わりました。Istioは、いまではKubernetesの
ネイティブサイドカーを使います。istio-proxyがspec.containersではなく
spec.initContainersに入ります(restartPolicy: Alwaysで)。そのため、
kubectl get pod -o jsonpath='{.spec.containers[*].name}'で確認していた習慣は、
いまではサイドカーがあるのに、ないと答えてしまいます。
ステップ
istioctl versionと注入ラベルを確認して記録してください(保存先:/root/ica/install.txt)。webというPod(nginx)を作成し、istio-proxyがどこに入ったかを確認して記録してください(保存先:/root/ica/sidecar.txt)。spec.containersとspec.initContainersを両方とも出力する必要があります。- PeerAuthentication(名前:
strict)でmTLSをSTRICTにし、メッシュの内側と外側からそれぞれリクエストして記録してください(保存先:/root/ica/mtls.txt)。 - VirtualService(名前:
web-vs)で、/teapotパスだけに418を返させ、結果を記録してください(保存先:/root/ica/routing.txt)。 - AuthorizationPolicy(名前:
web-authz)で、特定のServiceAccountだけを許可し、許可された側とそうでない側を試して記録してください(保存先:/root/ica/authz.txt)。 - ワークロードのSPIFFEアイデンティティを確認して記録してください(保存先:
/root/ica/identity.txt)。 - メッシュの外のワークロード(
nomeshネームスペース)を置き、STRICTに一度で切り替えるとなぜ危険なのかを書いてください(保存先:/root/ica/outside.txt)。 sidecar_location=、authz_denied_code=、mesh_identity=の3行と説明を書いてください(保存先:/root/ica/report.md)。
参考
- ラベルを付けたあとに作ったPodだけが注入されます。すでにあったPodは、
kubectl rollout restartか再作成が必要です。 - サイドカーのあるPodに
kubectl execするときは、-c <앱컨테이너>を付けるほうが安全です(プレースホルダーはアプリのコンテナ名です)。付けないと、デフォルトのコンテナが何かによって結果が変わります。 - Istioの認可の拒否は403です(
RBAC: access denied)。mTLSの未充足は、接続自体がリセットされて応答コードがありません(curlが000やexit 56)。この2つを区別することが、診断の核心です。 - SPIFFEアイデンティティは、
spiffe://cluster.local/ns/<네임스페이스>/sa/<서비스어카운트>の形式です(プレースホルダーはネームスペースとServiceAccountです)。istioctl proxy-config secret <파드>で証明書を見られます(プレースホルダーはPod名です)。 - よくある間違い1: VirtualServiceの
httpリストの順序です。上から最初に合ったルールを使うので、包括的なルールを上に置くと、下のルールがいつまでもマッチしません。 - よくある間違い2: ラベルを付ける前に作ったPodをそのままにして、「ポリシーが効かない」と言うことです。サイドカーがなければ、何も適用されません。
何が動いているか
istioctl versionと注入ラベルを確認して記録してください(保存先: /root/ica/install.txt)。
istioctl versionで、コントロールプレーンとデータプレーンのバージョンを一緒に見ます。そして、defaultネームスペースのistio-injectionラベルを確認してください。
サイドカーはどこに入るか
webというPod(nginx)を作成し、istio-proxyがどこに入ったかを確認して記録してください(保存先: /root/ica/sidecar.txt)。spec.containersとspec.initContainersを両方とも出力する必要があります。
.spec.containersと.spec.initContainersを両方とも出力してみてください。最近のIstioは、ネイティブサイドカーを使います。
STRICTは実際に防ぐ
PeerAuthentication(名前: strict)でmTLSをSTRICTにし、メッシュの内側と外側からそれぞれリクエストして記録してください(保存先: /root/ica/mtls.txt)。
メッシュの内側(サイドカーのあるPod)と、メッシュの外側(サイドカーのないネームスペース)から、それぞれリクエストしてみてください。外側からは、応答コードすら返ってきません。
ルールの順序が結果を変える
VirtualService(名前: web-vs)で、/teapotパスだけに418を返させ、結果を記録してください(保存先: /root/ica/routing.txt)。
httpリストは、上から最初に合ったものを使います。具体的なルールを上に、包括的なルールを下に置いてください。
アイデンティティで許可する
AuthorizationPolicy(名前: web-authz)で、特定のServiceAccountだけを許可し、許可された側とそうでない側を試して記録してください(保存先: /root/ica/authz.txt)。
principalsに、SPIFFE形式のServiceAccountを書きます。拒否は403です。
アイデンティティはどこに入っているか
ワークロードのSPIFFEアイデンティティを確認して記録してください(保存先: /root/ica/identity.txt)。
istioctl proxy-config secret <파드>で、サイドカーが持っている証明書を見ます(プレースホルダーはPod名です)。SANにSPIFFE URIが入っています。
STRICTに一度で切り替えてはいけない理由
メッシュの外のワークロード(nomeshネームスペース)を置き、STRICTに一度で切り替えるとなぜ危険なのかを書いてください(保存先: /root/ica/outside.txt)。
メッシュの外のワークロードが1つでも残っていると、STRICTはその通信をただちに切断します。PERMISSIVEで段階を分ける理由を書いてください。
何を学んだか
sidecar_location=、authz_denied_code=、mesh_identity=の3行と説明を書いてください(保存先: /root/ica/report.md)。
sidecar_location=、authz_denied_code=、mesh_identity=の3行と一緒に、2種類の「動かない」をどう区別するかを書いてください。