はじめに
Kubernetesは非常に柔軟なプラットフォームですが、その柔軟性ゆえに誤設定やセキュリティリスクも発生しやすくなります。
例えば、以下のようなリスクはありませんか?
- 特権コンテナ(privileged: true)がデプロイされている
- CPU / Memory制限が設定されていないPodが存在する
- latestタグのイメージが本番環境に適用されている
- Namespaceポリシーを無視したリソース作成
これらを自動的に防止する仕組みが、OPA GatekeeperによるAdmission制御です。
1. OPA Gatekeeperとは?
OPA Gatekeeperは、KubernetesのAdmission Controllerとして動作するポリシーエンジンです。
アーキテクチャ概要
kubectl apply ↓ Kubernetes API Server ↓ Admission Controller(Gatekeeper) ↓ Regoポリシー評価 ↓ 許可 or 拒否
PodやDeploymentの作成リクエストがAPIサーバーに届く前に、GatekeeperがRegoポリシーで検証し、違反していれば拒否します。
2. Gatekeeperの基本構成
Gatekeeperでは主に2つのリソースを定義します:
ConstraintTemplate:Regoポリシーの定義
Constraint:ポリシーの適用条件
3. 実践ポリシー例①:特権コンテナの禁止
ConstraintTemplate定義
apiVersion: templates.gatekeeper.sh/v1 kind: ConstraintTemplate metadata: name: k8sprivilegedcontainer spec: crd: spec: names: kind: K8sPrivilegedContainer targets: - target: admission.k8s.gatekeeper.sh rego: | package k8sprivilegedcontainer violation[{"msg": msg}] { container := input.review.object.spec.containers[_] container.securityContext.privileged == true msg := sprintf("特権コンテナは禁止されています: %v", [container.name]) }
Constraint定義
apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sPrivilegedContainer metadata: name: no-privileged-containers spec: match: kinds: - apiGroups: [""] kinds: ["Pod"]
これにより、privileged: true を持つPodは作成できなくなります。
4. 実践ポリシー例②:リソース制限(CPU/Memory)の必須化
package k8sresourcelimits violation[{"msg": msg}] { container := input.review.object.spec.containers[_] not container.resources.limits.cpu msg := sprintf("CPU制限が未設定です: %v", [container.name]) } violation[{"msg": msg}] { container := input.review.object.spec.containers[_] not container.resources.limits.memory msg := sprintf("Memory制限が未設定です: %v", [container.name]) }
これにより、リソース制限未指定のPodはAdmission段階で拒否されます。
5. 実践ポリシー例③:latestタグ禁止(本番環境向け)
package k8simagetag violation[{"msg": msg}] { container := input.review.object.spec.containers[_] endswith(container.image, ":latest") msg := sprintf("latestタグは禁止されています: %v", [container.image]) }
本番環境では常に明示的バージョンタグを使用させることが重要です。
6. Namespace単位でのポリシー制御(高度な例)
例:prod namespaceではNodePort禁止
package k8snodeport violation[{"msg": msg}] { input.review.object.kind == "Service" input.review.object.spec.type == "NodePort" input.review.object.metadata.namespace == "prod" msg := "prod環境ではNodePortは禁止されています" }
環境ごとに制限を変えることも可能です。
7. Audit機能による既存リソース監査
GatekeeperはAdmission制御だけでなく、既存リソースの監査(Audit)も可能です。
kubectl get constraint kubectl describe constraint no-privileged-containers
既に存在する違反リソースも一覧表示できます。
8. 実務ベストプラクティス
① ポリシーの段階導入
- まずはAuditモード
- 次にWarn(dry-run)
- 最後にEnforce(拒否)
② ポリシーのモジュール化
- security.rego
- cost.rego
- environment.rego
③ GitOps連携
ArgoCDやFluxと組み合わせることで、ポリシーとアプリを同時管理できます。
9. Sentinelとの使い分け
| 用途 | 推奨 |
|---|---|
| Terraform実行制御 | Sentinel |
| Kubernetes実行制御 | OPA Gatekeeper |
| CI/CD統合ポリシー | OPA |
実務では、TerraformはSentinel、KubernetesはGatekeeperというハイブリッド構成も一般的です。
まとめ
OPA Gatekeeperを導入することで、Kubernetesクラスタの安全性は飛躍的に向上します。
- 特権コンテナやlatestタグを禁止
- リソース制限を強制
- Namespace単位の高度な制御も可能
- Admission段階でリスクを遮断
IaC時代において、「作ってから直す」ではなく「作らせない」設計が重要です。