IPベースのセキュリティの脆弱性を克服する
従来のネットワークセキュリティは、通常「境界型セキュリティ(城と堀)」戦略に依存しています。ファイアウォールで高い壁を築き、境界の内側にあるものはすべて安全であると仮定します。しかし、現代のKubernetes環境において、IPアドレスは一時的なものに過ぎません。単一のクラスターで1日に5,000個ものPodが入れ替わることもあります。このような環境でIPベースのアクセス制御リスト(ACL)に頼ることは、運用担当者の疲弊とセキュリティホールの原因となります。
ゼロトラストは、場所を無視して「アイデンティティ(身元)」に焦点を当てることで、この問題を解決します。SPIFFE(Secure Production Identity Framework for Everyone)は、そのアイデンティティの形式を定義します。そしてSPIRE(SPIFFE Runtime Environment)は、実際にそれらのアイデンティティを配布するエンジンです。この構成を半年間本番環境で運用した結果、相互TLS(mTLS)のためだけにIstioのような重量級のサービスメッシュを管理するよりも、はるかに信頼性が高いことがわかりました。
KubernetesでのSPIREのセットアップ
アイデンティティを発行するには、強固な基盤が必要です。Kubernetesにおいては、認証局(CA)としてのSPIRE Server stumblingと、各ノードにDaemonSetとしてデプロイされるSPIRE Agentを配置することを意味します。
前提条件
- Kubernetesクラスター(v1.22以上を推奨)
- デプロイ用のHelm v3
- KubernetesのServiceAccountの仕組みに関する基礎知識
デプロイ手順
公式のHelmチャートを使用するのが最も確実な方法です。ServiceAccountやロールの設定、そして重要なWorkload APIのボリュームマウントなど、複雑な作業を処理してくれます。まずはリポジトリを追加しましょう。
helm repo add spiffe https://spiffe.github.io/helm-charts-hardened/
helm repo update
セキュリティインフラを隔離することはベストプラクティスです。私は常に、これらのコンポーネントを専用のネームスペースにデプロイし、一般的なアプリケーションのトラフィックから遠ざけるようにしています。
kubectl create namespace spire
# 中規模クラスターでは通常、サーバーに2Giのメモリを割り当てます
helm install spire spiffe/spire -n spire \
--set spire-server.ca_key_type=rsa-2048 \
--set spire-agent.trust_domain=prod.itfromzero.com
苦労して得た教訓を一つ:trust_domainは慎重に選んでください。後でexample.orgからinternal.netに変更しようとすると、フリート内のすべてのアイデンティティを再発行する必要があり、大規模な同期のトラブルに見舞われることになります。
アイデンティティ의 オーケストレーション:設定
エージェントが起動すると、SPIRE Serverと通信してホストノードのアイデンティティを証明します。しかし、特定のPodがどのようにして固有のIDを取得するのでしょうか?これは「ワークロード証明(Workload Attestation)」を通じて行われます。
信頼ドメイン(Trust Domain)の定義
信頼ドメインは、prod.itfromzero.comのような信頼のルート(Root of Trust)と考えてください。すべてのアイデンティティは、spiffe://trust-domain/path/to/workloadというSPIFFE ID形式に従います。これはクリーンで階層的であり、監査も容易です。
ワークロードの登録
アイデンティティの自動化は、手動作業よりも優れています。SPIRE Controller Managerは新しいPodを監視し、ラベルに基づいて自動的に登録エントリを作成します。ただし、テストのために手動エントリがどのようになるか見てみましょう。
# 決済サービス用の手動登録
kubectl exec -n spire spire-server-0 -- \
/opt/spire/bin/spire-server entry create \
-spiffeID spiffe://prod.itfromzero.com/ns/payments/sa/processor \
-parentID spiffe://prod.itfromzero.com/spire/agent/k8s_psat/my-cluster/node-name \
-selector k8s:ns:payments \
-selector k8s:sa:processor
本番環境では、手動コマンドはリスクとなります。SPIRE Kubernetes Workload Registrarの使用を強くお勧めします。これはアイデンティティをPodに自動的にマッピングするため、CI/CDパイプラインはSPIREの存在を意識する必要さえありません。
mTLSの自動化
本当のメリットは、自動化されたmTLSにあります。SPIRE はSVID(SPIFFE Verifiable Identity Document)をX.509証明書として発行します。SPIRE Agentはこれらを数時間ごとに自動でローテーションします。重要なのは、秘密鍵がノードのメモリ内に保持され、Kubernetes Secretや永続ディスクに書き込まれることがない点です。
実環境でのパフォーマンスとモニタリング
6ヶ月運用して最大の収穫は、静的な認証情報管理が完全に不要になったことです。20個以上のシークレットを手動でローテーションしていた状態から、ゼロになりました。システムは、1日あたり1,000回以上のアイデンティティ・ローテーションを、一度の手動介入もなく処理しました。
アイデンティティの検証
Podが実際に証明書を持っているか確認する必要があります。私はアプリケーションコンテナ内からWorkload APIの状態を確認するために、シンプルなチェックを行っています。
# アプリコンテナ内からアイデンティティを確認
/opt/spire/bin/spire-agent api fetch x509 -socketPath /run/spire/sockets/agent.sock
取得に成功すると、SPIFFE IDと証明書の有効期限が返されます。もし “permission denied” エラーが発生した場合は、セレクターを確認してください。通常、Podが登録したものとは異なるService Accountで実行されていることが原因です。
モニタリングとログ
ゼロトラストの基盤は、その可視性にかかっています。私はGrafanaダッシュボードで以下の3つのメトリクスに注目しています。
- 登録率(Registration Rate): ここでのスパイクは、デプロイループやスケーリングの問題を示唆している可能性があります。
- 証明レイテンシ(Attestation Latency): 200ms未満を目指しています。これが上昇する場合、SPIRE ServerのCPUがスロットリングされている可能性があります。
- SVID有効期限: アイデンティティの有効期間が残り20%を切った場合にアラートを飛ばします。
SPIREエージェントはSVIDをローカルにキャッシュすることを覚えておいてください。SPIRE Serverが10分間ダウンしたとしても、サービスがすぐに停止することはありません。キャッシュされた証明書が期限切れになるまで使い続けます。
本番運用6ヶ月からの教訓
技術は機能しますが、マインドセットの切り替えが本当の挑戦です。開発者はもはや内部エンドポイントを単に “curl” することはできず、Workload APIから提供されるアイデンティティを使用する必要があります。go-spiffeライブラリやEnvoyサイドカーのようなツールを使えば、この移行はスムーズになります。基本的なファイアウォールルールを超えて、クラスターを真に堅牢にしたいのであれば、SPIREによるアイデンティティベースのセキュリティこそが、最も強力な進むべき道です。

