こんにちは!MSA(マイクロサービスアーキテクチャ)環境でサービスを開発・運用されている方なら、一度は「セキュリティ」という巨大な山の前で途方に暮れた経験があるのではないでしょうか。特にサービス間の通信が複雑に絡み合う中で、「このリクエストは本当に安全なのか?🤨」「許可されたサービスだけが互いに通信できるようにできないか?」といった悩み、皆さん経験されたことでしょう?
この時、多くの方がサービスメッシュの代表格であるIstioを思い浮かべます。Istioは強力なトラフィック制御、可観測性、そして「セキュリティ」機能を提供しているからです。中でも、特定のサービス間の通信を許可したり遮断したりする認可(Authorization)機能は本当に魅力的です。
しかし、ここで多くの方が決定的な間違いを犯しています。それは…
「Istioの認可機能をどうやって『有効化』するのですか?」という質問です。
結論から言うと、その必要はありません!🤯

💡 真実:Istioの認可は「オンにする」機能ではありません
多くの方がIstioをインストールする際、IstioOperatorリソースを修正したり、インストールオプションとしてvalues.pilot.authorization.enabled=trueのような設定を探し回ったりします。まるで新しい機能を追加インストールするかのように。
しかし、Istioの認可機能は別途有効化する必要はなく、Istioをインストールした瞬間にすでに私たちのそばにあります。そばにいるけれど、私たちが呼び出さなかったから静かにしていただけなのです。
例えるなら、私たちの家にはすでに「ドアの鍵」が設置されている状態です。私たちはただ、誰に「鍵」を渡してドアを開けさせるか、あるいは鍵を渡さずに侵入させないかを決めるだけで良いのです。
- Istio認可機能:すでに設置されたドアの鍵 🚪
- AuthorizationPolicyリソース:誰に鍵を渡すかを決めるルール(ポリシー)🔑
つまり、認可機能自体はIstioのコアコンポーネントであるEnvoyプロキシに組み込まれており、常に待機しています。私たちがAuthorizationPolicyというポリシーリソースを作成してクラスターに適用した瞬間、この鍵がポリシーに従って動作を開始するのです。
🧐 では、実際にどのように動作するのでしょうか?(全体プロセスを詳しく見てみよう)
個別のポリシーを知ることも重要ですが、全体的な流れを理解するとずっと簡単になります。
- Istioのインストールとサイドカーの注入 🚀
- KubernetesクラスターにIstioをインストールします。
- 保護したいサービス(Pod)にIstioのEnvoyプロキシ(サイドカー)を注入します。これで、すべてのトラフィックはこのプロキシを経由するようになります。
- ポリシー未適用状態(デフォルト:すべて許可) ✅
- AuthorizationPolicyを何も作成しない場合、Istioはメッシュ内部のすべてのトラフィックを許可(ALLOW)します。セキュリティ機能はありますが、ルールがないため、すべての通信を通過させるのです。
- AuthorizationPolicyの作成と適用 📝
- 「AサービスはBサービスのGETリクエストのみを許可する」といったルールをYAMLファイルで作成します。これがAuthorizationPolicyです。
- kubectl applyコマンドでこのポリシーをクラスターに適用します。
- Istiodの役割(ポリシーの伝播) 📡
- コントロールプレーンであるIstiodがこのAuthorizationPolicyの作成を検知します。
- Istiodはこのポリシーを解釈し、該当ポリシーの影響を受けるEnvoyプロキシに新しいルールを伝播します。
- Envoyプロキシの役割(ポリシーの強制) 👮
- ポリシーを受け取ったEnvoyプロキシは、それ以降、出入りするすべてのトラフィックを検査します。
- ポリシーに明記されたルールと一致するトラフィックは許可(ALLOW)し、一致しないトラフィックは拒否(DENY)します。
この流れを理解すれば、私たちがすべきことは「望むルールをうまく作成して適用する」ことだけだとわかるでしょう。
🛠️ 実例で理解する:reviewsサービスを保護する
言葉だけではピンとこないですよね?実際のコードを通じて、reviewsサービスへのリクエストを制御するポリシーを作成してみましょう。
シナリオ: product-apiサービスのみがreviews:v1サービスの/reviews/{id}パスへのGETリクエストを送信できるように許可する。それ以外のすべてのリクエストは遮断する。
1. AuthorizationPolicyの定義 (allow-product-to-reviews.yaml)
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: allow-product-to-reviews
namespace: default
spec:
# このポリシーを適用するワークロードを選択します。
# app: reviews, version: v1 のラベルを持つPodに適用されます。
selector:
matchLabels:
app: reviews
version: v1
# このポリシーのデフォルトアクションは「ALLOW」です。
# 以下の「rules」に合致するリクエストを許可するという意味です。
action: ALLOW
# 許可するリクエストに関する詳細なルールを定義します。
rules:
- from:
# どの「送信元」からのリクエストを許可するか?
- source:
# リクエストを送信するワークロードのサービスアカウントを明示します。
# これが最も安全で推奨される方法です。
principals: ["cluster.local/ns/default/sa/product-api"]
to:
# どの「宛先」へのリクエストを許可するか?
- operation:
# 許可するHTTPメソッドを指定します。
methods: ["GET"]
# 許可するパスを指定します。
paths: ["/reviews/*"]
2. ポリシーの適用
ターミナルで以下のコマンドを実行して、ポリシーをクラスターに適用します。
kubectl apply -f allow-product-to-reviews.yaml
3. 結果の確認
さて、どうなるでしょうか?
- 許可されるリクエスト 👍
- product-apiサービスアカウントで実行中のPodがreviews:v1 Podの/reviews/123に送信するGETリクエスト
- 拒否されるリクエスト 👎
- product-apiがreviews:v1に送信するPOSTリクエスト(メソッドが異なるため拒否)
- unknown-serviceがreviews:v1に送信するGETリクエスト(サービスアカウントが異なるため拒否)
- product-apiがreviews:v2に送信するGETリクエスト(ポリシーのセレクターにversion: v1が指定されているため、v2にはポリシーが適用されません。もし他のDENYポリシーがなければ、このリクエストはデフォルトで許可されます)
⚠️ 重要:action: ALLOWポリシーを一つでも適用すると、該当セレクターに合致するワークロードは基本的に「暗黙的なDENY」状態になります。つまり、ALLOWルールに明記されていないすべてのリクエストは自動的に拒否されます。これがIstioの強力なゼロトラストセキュリティモデルの始まりです。
😫 よくある誤解、なぜ間違っているのでしょうか?
- 「IstioOperatorやHelmの値で認可機能を有効化する必要がある。」
- なぜ違うのか? 上で説明したように、認可機能はEnvoyプロキシの核となる機能であり、分離できない部分です。別途インストールや有効化のプロセスが必要ない組み込み機能(built-in)だからです。コントロールプレーン(Istiod)は、私たちが作成したポリシーをプロキシに伝達する役割を果たすだけです。
- 「Istioをインストールしたから、私のサービスはもう安全だ。」
- なぜ違うのか? Istioをインストールしただけの状態は、「セキュリティを適用できる能力」を備えたのであって、「セキュリティが適用された状態」ではありません。AuthorizationPolicyを適用するまではすべてのトラフィックが許可されるため、必ず明示的なポリシーを通じて望むセキュリティレベルを直接設定する必要があります。
✨ 結論:考え方を変えればIstioセキュリティは簡単になります
Istio認可ポリシーは「有効化」するのではなく、「ポリシーを適用して実行」するものです。
この簡単な事実一つを覚えておくだけで、Istioセキュリティへのアプローチがはるかに明確になります。もはや存在しない設定値を探し回る必要はなく、今すぐ皆さんのサービスに必要なアクセスルール(AuthorizationPolicy)を定義して適用してみてください。小さくても強力なYAMLファイル一つが、皆さんのMSA環境をはるかに安全にしてくれるでしょう。
コメントを残す