テックカリキュラム

OPA GatekeeperでのKubernetes Admission制御 ── クラスタを守るPolicy as Code実践

OPA GatekeeperでのKubernetes Admission制御 ── クラスタを守るPolicy as Code実践

はじめに

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時代において、「作ってから直す」ではなく「作らせない」設計が重要です。