Kyvernoで構築するKubernetesポリシー基盤

Kose Ryota

2026.2.12

はじめに

ここ数年、Kubernetesを活用したプラットフォーム運用が進むにつれて、各企業で必ず直面するのが「ガバナンス」の課題です。開発者には自由にリソースを作ってもらいたい一方で、セキュリティ基準を満たさない設定や、過大なリソース要求によるクラスタへの影響は防がなければなりません。

Kubernetesのポリシー管理といえば OPA/Gatekeeper が有名ですが、独自の「Rego」言語の学習コストが導入のハードルになりがちです。
「K8sのマニフェストと同じYAMLでポリシーが書けたらいいのに……」そう思ったことはないでしょうか?

それを実現するのが Kyverno です。

KyvernoはKubernetesネイティブに設計されており、既存のYAML知識だけで柔軟なポリシー(Validation/Mutation/Generation)を定義できます。本記事では、Kyvernoをプロダクション環境へ導入するためのインストール手順から、実際に運用してわかった「設定のハマりどころ」までをご紹介します。

Kyvernoの仕組み(Architecture)

Kyvernoの具体的な設定に入る前に、その裏側で動いている仕組みを理解しておきましょう。KyvernoはKubernetesクラスター内で Dynamic Admission Controller として動作します。 本セクションでは、KubernetesのAdmission処理の流れ(APIリクエストから保存まで)、Kyvernoの内部コンポーネント、そして重要な「ポリシーの種類」と「ポリシー適用モード」について解説します。

Kubernetes Admission Controller の処理フロー

私たちが kubectl apply などでリソースを作成しようとした時、そのリクエストは以下の順序で処理されます。Kyvernoはこの中の「Mutation(書き換え)」と「Validation(検証)」のフェーズに介入します。

  1. Authentication / Authorization: まず「誰が権限があるか」がチェックされます。
  2. Mutation (Kyverno): リソースの内容を書き換えます(例:デフォルトのラベルを付与する、imagePullPolicy を変更するなど)。
  3. Schema Validation: K8sの標準的な構文チェックが行われます。
  4. Validation (Kyverno): リソースの内容がポリシーに違反していないか検証します(例:特権コンテナになっていないか?など)。
  5. Persist to etcd: 全てのチェックをパスした場合のみ、設定が保存され、実際にPodなどが作成されます。

公式ページから抜粋:https://kyverno.io/docs/introduction/admission-controllers/

💡ポイント:
Kyvernoは Webhook として K8s API Server から呼び出されます。つまり、Kyvernoがダウンしていたり応答が遅かったりすると、クラスタ全体の操作に影響が出る可能性があります。このリスクを回避するための設定(HA構成やFailurePolicy)を検討します。

Kyvernoの主要コンポーネント

Kyvernoは単なるWebhookだけでなく、役割の異なる複数のコンポーネントが連携して動作しています。

公式ページから抜粋:https://kyverno.io/docs/introduction/how-kyverno-works/

1. Admission Controller

  • Kubernetes API Server から送られてくる Admission Review(リソース作成・更新の依頼)を受け取る受付窓口です。
  • 受け取ったリクエストを「Engine」に渡します。

2. Engine

  • Kyvernoの中核となる処理エンジンです。
  • 定義された Policies(ポリシー)や PolicyExceptions(除外設定)と照らし合わせ、リクエストを許可するかブロックするかを判断します。
  • Enforceモードの場合、違反があればここで即座にブロック判定を下します。

3. Report Controllers

  • エンジンの判定結果を受け取り、非同期で Policy Reports(レポート)を作成・更新します。
  • Auditモードの場合、リクエスト自体は通しますが、このコントローラーが「違反があった」という記録を別途作成する役割を担います。

4. Background Controller

  • 主に「Generate(リソース生成)」ポリシーや、既存リソースの定期スキャンなどを担当します。
  • APIリクエストの応答速度に影響を与えないよう、重い処理はここで行われます(図中の Update Requests などを処理)。

5. Webhook Controller

  • Kyverno自身をKubernetesに「Admission Controller」として登録・管理する役割です。
  • 図左側の Webhook Configuration を自動的に更新し、K8s API Server との通信経路を維持します。

Kyvernoで扱える3つの主要なポリシー

Kyvernoのポリシーは大きく分けて以下の3つの機能を持っています。

Validation:リソースの設定を確認する。

最も基本的な機能で、リソースの設定値がルールに適合しているかをチェックします。

  • ユースケース:
    • privileged: true(特権コンテナ)を禁止する。
    • 必須のラベル(team, cost-center など)が付いているか確認する。
    • CPU/Memoryのリクエスト値が設定されているか強制する。

Mutation:リソース設定を変更する

リソースが作成される前に、自動的に内容を書き換えます。

  • ユースケース:
    • imagePullPolicy が未指定なら Always を挿入する。
    • 特定のNamespaceのPodに、監視用のサイドカーコンテナを自動注入する。
    • Podに「コストセンター」情報をラベルとして自動付与する。

Generation:新しいリソースを作成し、必要に応じて同期を保つ

リソースの作成・更新をトリガーにして、別の新しいリソースを作成します。

  • ユースケース:
    • 新しい Namespace が作成されたら、自動的に NetworkPolicy(通信制限)や ResourceQuota を作成する。
    • Namespaceごとにアクセス用の RoleBinding を自動配置する。

💡 Note:
この他にも、コンテナイメージの署名を検証する Verify Images RulesやKubernetesリソースを削除する Cleanup Rulesがあります。 他にも多くのRulesを定義できるので、興味があれば公式ページをご覧ください

ポリシーの適用モード:Audit と Enforce

すでに、説明の中にも出てきましたが、Kyvernoの大きな特徴として、ポリシーごとに「違反時の動作」を2種類から選ぶことができます。運用フェーズに合わせて適切に使い分けることが重要です。

設定モードリソース作成Policy Report への記録用途・特徴
Audit (監査)許可 (Allowed)記録される (Fail)既存環境への影響を確認したり、アラートのみを出したい場合に使用。
Enforce (強制)ブロック (Blocked)記録されない
(リソースが作成されないため)
セキュリティ要件を厳格に適用する場合に使用。
kubectl 実行時に即座にエラーが返る。

💡Note:
Enforce モードであっても、すでに存在している(過去に作られた)リソースを勝手に削除することはありません。それらは Background Controller によってスキャンされ、「違反あり(Fail)」としてレポートに記録されます。

background: true となっている時の挙動は以下の動作になります。

設定モードNew ResourceExisting Resource
AuditReportReport
EnforcePass onlyReport

インストールと基盤設定

ここまでで、Kyvernoについて理解できたと思いますので、ここからはKyvernoの具体的な設定に入っていきます。

Kyvernoのインストールには、便利な設定オプションを提供し、さまざまなカスタマイズに対応できるため、Helmが公式で推奨されています。また、本番環境の基盤として運用するならば、ArgoCDなどを用いた GitOps構成 で管理するほうが、望ましいでしょう。

本セクションでは、GKE Autopilot環境への導入を前提に、ArgoCDを用いた実践的なインストール手順と、実際に遭遇したハマりポイントについて解説します。

前提構成

今回の検証および構築に使用した環境は以下の通りです。

コンポーネントバージョン / 備考
Kubernetes ClusterGKE Autopilot (v1.34)
Kyvernov1.16.0
GitOps ToolArgoCD (v3.x系)
IaC ToolHelm (v3.19.1)

本番運用のための利用した設定(values.yaml)

GKE Autopilotで安定稼働させるため、以下の設定を行いました。

  • 本番運用のため「冗長(HA)構成」で導入するのと 「GKE管理Namespaceの除外」 を意識しています。(除外しないと、GKEが自動管理するリソースに対してKyvernoが過剰に反応し、予期せぬエラーログが出続ける場合がありました。)
  • また、skipResourceFiltersをfalseに設定しました。(後述で説明します。)
config:
  resourceFiltersIncludeNamespaces:
    - 'kube-system'
    - 'gke-gmp-system'
    - 'gke-managed-system'
    - 'gke-managed-cim'

# Features configuration
features:
  backgroundScan:
    enabled: true
    skipResourceFilters: false

admissionController:
  autoscaling:
    enabled: true
    minReplicas: 3
    maxReplicas: 10

# Background controller configuration
backgroundController:
  enabled: true
  replicas: 3

# Cleanup controller configuration
cleanupController:
  enabled: true
  replicas: 3

reportsController:
  enabled: true
  replicas: 3

ArgoCD Applicationマニフェスト例

上記 values.yaml を含めた、ArgoCDのApplication定義は以下のようになります。

  • ここで重要なのが syncOptions の設定です。公式でも推奨されてますが、ServerSideApply=true を利用したほうが良いでしょう(理由は後述記載します)。また、いずれの方法を使用する場合でも、Kyvernoは常に専用のNamespace(本記事では kyverno とします)にインストールする必要があります。
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: kyverno
  namespace: argocd
  annotations:
    argocd.argoproj.io/compare-options: ServerSideDiff=true,IncludeMutationWebhook=true
spec:
  project: default
  destination:
    server: 'https://kubernetes.default.svc'
    namespace: kyverno
  sources:
    - repoURL: "https://kyverno.github.io/kyverno/"
      chart: kyverno
      targetRevision: 3.6.0
      helm:
        releaseName: kyverno
        valueFiles:
          - $repo/kyverno/helm/values.yaml
    - repoURL: https://github.com/user/repository.git
      targetRevision: main
      ref: repo
  syncPolicy:
    syncOptions:
      - CreateNamespace=true
      - ServerSideApply=true

ArgoCD導入時のハマったポイント

ArgoCDを用いた導入は推奨される構成ですが、ArgoCDのデフォルト挙動と衝突するケースがありました。私たちが実際に直面し、解決した2つの事象を紹介します。

  • CRDサイズ制限と ServerSideApply
    KyvernoのCRD(Custom Resource Definition)は定義ファイルが非常に巨大です。
    • 発生した事象
      ArgoCD(およびkubectl)のデフォルトである「Client-Side Apply」を使用すると、リソース定義を kubectl.kubernetes.io/last-applied-configuration というアノテーションに保存しようとします。しかし、アノテーションには 256KB というサイズ制限があります。
      KyvernoのCRDはこの制限を軽く超えてしまうため、Sync時に以下のようなエラーが発生します。
      ⛔ Error: to long: must have at most 262144 bytes
    • 解決策
      これを回避するために、ArgoCDの syncOptionsServerSideApply=true を設定します。 これにより、クライアント側でアノテーションを付与せず、サーバーサイド(API Server)で差分計算を行う方式に切り替わるため、サイズ制限の影響を受けずにApplyできるようになります。
  • trackingMethod とラベルの競合
    もう一つ、運用初期(ArgoCD v2系利用時)に大きくハマったのが、ArgoCDがリソースを管理・追跡するための設定 trackingMethod にまつわるトラブルです。
    • 発生した事象
      導入当初、ArgoCD v2のデフォルト設定である trackingMethod: label を使用していました。この設定では、ArgoCDは管理対象リソースに app.kubernetes.io/instance というラベルを付与(上書き)して追跡を行います。
      しかし、ArgoCDのProject機能などを利用していると、このラベルの値が <project-name>_<app-name> のように書き換えられてしまう挙動があります。
      一方で、KyvernoのHelmチャート内部では、権限管理に使われる ClusterRoleAggregationRule において、リソースの特定に app.kubernetes.io/instance ラベルの値を厳密に参照(matchLabels)している箇所がありました。
      ArgoCDがラベルの値を書き換えてしまったことで、Kyverno内部のセレクタ不整合(ラベルが一致しない)が発生。 コントローラーが正しく権限を集約できず、「リソースは作成されたが一向に正常動作しない」 という状態に陥りました。
    • 解決策
      この問題を解決するために、ArgoCD側の追跡方法を label から annotation に変更しました。

運用で気をつけたポイント

インストールのセクションで少し書きましたが、運用で気をつけるポイントのいくつか紹介します。

  • Namespaceの除外 (Exclusions):
    Kyvernoが kube-system などの重要なシステムコンポーネントにまで干渉すると、予期せぬ副作用でクラスターが不安定になる可能性があります。
    • 対策:
      values.yamlresourceFilters 設定などを使い、以下のNamespaceを明示的にポリシー適用対象外にしました。(今回はnamespaceを対象外とするため、resourceFiltersIncludeNamespacesで設定しました)
      • kube-system
      • gke-* 系 (GKE Autopilot等のマネージドコンポーネント)
  • 既存リソースへの影響 (Background Scan):
    Kyvernoには、ポリシー適用前に作成された既存リソースを定期的にチェックする Background Scan 機能があると説明しました。しかし、挙動で注意する点があります。
    • 課題:
      デフォルト設定では、バックグラウンドスキャンの際、グローバルな除外設定(resourceFilters)がスキップされる仕様になっている場合があります。
      これにより、本来除外したはずの kube-system 内のリソースに対してもスキャンが走ってしまい、大量の「違反レポート」が作成されたり、コントローラーのログがエラーや警告で埋め尽くされたりしてしまいます。
    • 解決策:
      values.yamlskipResourceFilters: false を明示的に設定します。
      「フィルターのスキップを無効にする(=フィルターを有効にする)」という二重否定のような設定ですが、これを設定することで除外設定が尊重され、無駄なスキャンとログ出力を抑制できます。

まとめ

本記事では、GKE Autopilot環境において、Kyvernoを用いたポリシー基盤をArgoCDで構築する際の実践的なノウハウを紹介しました。

Kyvernoの最大の魅力は、やはり 「Kubernetesネイティブである(YAMLで書ける)」 という点です。Regoのような独自の言語を習得する必要がなく、既存のKubernetesの知識だけで高度なガバナンスをコード化できる点は、運用チームにとって非常に大きなメリットとなります。

一方で、本番運用の「基盤」として導入するには、単にインストールするだけでなく、様々な考慮が必要です。

ポリシー基盤は「開発者を縛るもの」と捉えられがちですが、適切に設計・運用すれば、「開発者が安心してアクセルを踏めるようにするためのガードレール」 となります。 ぜひ、今回のハマりどころや推奨設定を参考に、セキュアで生産性の高いKubernetesプラットフォームを構築してみてください。

参考

ブログ一覧へ戻る

お気軽にお問い合わせください

SREの設計・技術支援から、
SRE運用で使用する
ツールの導入など、
SRE全般についてご支援しています。

資料請求・お問い合わせ