はじめに
こんにちは、株式会社LegalOn Technologies で SRE をしている加藤です。私たちのチームでは、主に GKE (Google Kubernetes Engine) 上でサービスを構築・運用しており、 日々 Kubernetes クラスターと向き合っています。
本記事では、私たちが利用している GKE 環境におけるセキュリティとガバナンスの強化を目的として、特定の Namespace における開発者の Pod 操作を制限したいという課題に対し、Kubernetes v1.30 で GA となった Validating Admission Policy を活用して解決した事例をご紹介します。具体的な設定方法から、それによってどのような効果が得られたかまでを解説します。
課題とその背景
私たちの GKE 環境では、 開発プロセスにおいて、アプリケーションが期待通りに動作するかを確認するために、本番環境に近いステージング環境などを利用することがあります。これにより、リリース前に潜在的な問題を特定できます。
しかし、特定の Namespace には、プロジェクトの性質上、機密性の高い情報を用いて学習された機械学習モデルなどがデプロイされるケースがあります。これらのモデルや関連データは、セキュリティ上の理由から厳密なアクセス管理下に置く必要があります。
通常の開発プロセスでは、開発者がこれらの機密性の高い機械学習モデルがデプロイされた Namespace で直接 Pod を作成したり、頻繁に設定を変更したりすることはありません。しかし、システムの全体的な動作確認やトラブルシューティングの文脈で、開発者が環境の状態を参照する可能性は残ります。
ここで課題となるのが、たとえ参照目的であっても、開発者が kubectl exec
などのコマンドを使って誤って Pod 内部にアクセスし、機密データに触れてしまうリスクです。また、意図せずともリソースの設定を変更してしまう可能性もゼロではありません。
このようなリスクを排除し、機密データがデプロイされた Namespace の安全性を確保するため、特に Google Cloud の IAM で管理されている開発者アカウントやグループからのアクセスを適切に制御する必要があったのです。これが、今回 Validating Admission Policy の導入を検討するに至った背景です。
課題の解決方法と結果
この課題を解決するために、Kubernetes の組み込み機能である Validating Admission Policy を採用しました。OPA Gatekeeper や Kyverno のような、より高機能なポリシーエンジンも存在しますが、今回の私たちの要件は Validating Admission Policy の機能範囲で十分に満たせると判断しました。Validating Admission Policy を選択した主な理由は、追加のコントローラーを導入・運用する必要がなく、導入や管理が比較的容易である点です。Kubernetes 標準の機能で要件を達成できるこのアプローチが、不要な複雑性を避け、本質的な課題解決に集中する上で最適だと考えました。
前提知識: Validating Admission Policy とは?
Validating Admission Policy は、Kubernetes の Admission Controller の一種です。kube-apiserver へのリクエストを検証し、カスタムルールに基づいてリクエストを許可または拒否します。
- 特徴:
- 外部の Webhook サーバを必要とせず、Kubernetes ネイティブで動作します。
- ポリシーのルールは CEL (Common Expression Language) という式言語で記述します。
- ポリシー定義 (
ValidatingAdmissionPolicy
) と、それを適用する対象 (ValidatingAdmissionPolicyBinding
) を分離して管理できます。
- 詳細: より詳しい情報については、Kubernetes の公式ドキュメントをご参照ください。
解決方法: ポリシーの定義と適用
私たちは、機密データを扱う可能性のある Namespace (例: sensitive-data=true
ラベルが付与された Namespace) に対して、特定の開発者グループ (your-developer-group@example.com
) に所属するユーザーによる以下の操作を拒否 (Deny) するポリシーを作成しました。
- Pod の作成 (CREATE) および 更新 (UPDATE)
- Pod に対する
exec
(コンテナ内でのコマンド実行) - Pod に対する
attach
(コンテナへの接続) - Pod に対する
port-forward
(ローカルポートからの転送接続) - Deployment, StatefulSet, ReplicaSet の作成 (CREATE) および 更新 (UPDATE)
以下が実際に適用したポリシーの定義 (ValidatingAdmissionPolicy
) と適用設定 (ValidatingAdmissionPolicyBinding
) の YAML です。
ValidatingAdmissionPolicy
(ポリシー定義):
apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicy metadata: name: "restrict-developer-pod-access" # ポリシー名 spec: failurePolicy: Fail # ポリシー評価エラー時はリクエストを失敗させる matchConstraints: resourceRules: # Pod の作成・更新 - apiGroups: [""] apiVersions: ["v1"] operations: ["CREATE", "UPDATE"] resources: ["pods"] # Pod の exec, attach (CONNECT 操作) - apiGroups: [""] apiVersions: ["v1"] operations: ["CONNECT"] resources: ["pods/exec", "pods/attach", "pods/portforward"] # Pod を管理するリソースの作成・更新 - apiGroups: ["apps"] apiVersions: ["v1"] operations: ["CREATE", "UPDATE"] resources: ["deployments", "statefulsets", "replicasets"] validations: # CEL 式: リクエストユーザーが指定グループに所属する場合に true # GKE では、IAM と Kubernetes RBAC の設定により、認証されたユーザーの Google Workspace グループ名などが request.userInfo.groups に連携されます。 - expression: "'your-developer-group@example.com' in request.userInfo.groups" # 違反時のメッセージ message: "Members of 'your-developer-group@example.com' are not allowed to create, update, exec, or attach to Pods in this namespace."
ValidatingAdmissionPolicyBinding
(ポリシー適用):
apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicyBinding metadata: name: "restrict-developer-pod-access-binding" # Binding 名 spec: policyName: "restrict-developer-pod-access" # 上記ポリシー名を指定 validationActions: [Deny] # 違反時は拒否 (Deny) matchResources: namespaceSelector: # 'sensitive-data=true' ラベルを持つ Namespace に適用 matchLabels: sensitive-data: "true"
この Binding によって、ポリシーがどのように適用されるのかを図で示します。以下の図では your-developer-group@example.com
グループのユーザーが Pod の manifest ファイルを適用する際に Validating Admission Policy が適用されている状態、されていない状態でどのような結果になるのかを示しています。
結果: 意図した操作制限の実現
このポリシーを適用した結果、sensitive-data=true
ラベルを持つ Namespace において、your-developer-group@example.com
に所属するユーザーが kubectl exec
や Pod 作成 (kubectl apply -f pod.yaml
など) を実行しようとすると、以下のようなエラーメッセージが表示され、操作が正しく拒否されるようになりました。
kubectl exec
実行時のエラー例:
Error from server: admission webhook "validation.policy.admission.k8s.io" denied the request: ValidatingAdmissionPolicy 'restrict-developer-pod-access' with binding 'restrict-developer-pod-access-binding' denied request: Members of 'your-developer-group@example.com' are not allowed to create, update, exec, or attach to Pods in this namespace.
kubectl apply
(Pod 作成)実行時のエラー例:
Error from server: error when creating "pod.yaml": admission webhook "validation.policy.admission.k8s.io" denied the request: ValidatingAdmissionPolicy 'restrict-developer-pod-access' with binding 'restrict-developer-pod-access-binding' denied request: Members of 'your-developer-group@example.com' are not allowed to create, update, exec, or attach to Pods in this namespace.
これにより、開発者の利便性をある程度維持しつつ、ステージング環境におけるセキュリティリスクを低減し、意図しない操作による影響を防ぐことができました。
まとめ
本記事では、Kubernetes の Validating Admission Policy を活用し、特定の Namespace における開発者の Pod 操作を制限することで、セキュリティとガバナンスを強化した事例を紹介しました。
Validating Admission Policy は、私たちの GKE 環境においても外部 Webhook サーバを用意する必要がなく、Kubernetes ネイティブな方法で柔軟なポリシー制御を実現できる強力な機能です。
今後は、他のセキュリティ要件やリソース標準化のルール(必須ラベルの強制など)にも Validating Admission Policy の適用を検討していきたいと考えています。
今回の取り組みを通じて、Validating Admission Policy の有効性を実感できました。今後も Kubernetes 環境のセキュリティ維持・向上のため、適切なツールや機能を活用していきます。
この記事が、Kubernetes 環境のセキュリティやガバナンス向上に取り組む方々の参考になれば幸いです。
謝辞
今回の取り組みを進めるにあたり、相談に乗ってくれたチームメンバーに感謝します。
仲間募集
私たちのチームでは、一緒に働く仲間を募集しています。ご興味がある方は、以下のサイトからぜひご応募ください。皆様のご応募をお待ちしております。