はじめに
ここ数年、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(検証)」のフェーズに介入します。
- Authentication / Authorization: まず「誰が権限があるか」がチェックされます。
- Mutation (Kyverno): リソースの内容を書き換えます(例:デフォルトのラベルを付与する、
imagePullPolicyを変更するなど)。 - Schema Validation: K8sの標準的な構文チェックが行われます。
- Validation (Kyverno): リソースの内容がポリシーに違反していないか検証します(例:特権コンテナになっていないか?など)。
- 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を自動配置する。
- 新しい Namespace が作成されたら、自動的に
💡 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 Resource | Existing Resource |
|---|---|---|
| Audit | Report | Report |
| Enforce | Pass only | Report |
インストールと基盤設定
ここまでで、Kyvernoについて理解できたと思いますので、ここからはKyvernoの具体的な設定に入っていきます。
Kyvernoのインストールには、便利な設定オプションを提供し、さまざまなカスタマイズに対応できるため、Helmが公式で推奨されています。また、本番環境の基盤として運用するならば、ArgoCDなどを用いた GitOps構成 で管理するほうが、望ましいでしょう。
本セクションでは、GKE Autopilot環境への導入を前提に、ArgoCDを用いた実践的なインストール手順と、実際に遭遇したハマりポイントについて解説します。
前提構成
今回の検証および構築に使用した環境は以下の通りです。
| コンポーネント | バージョン / 備考 |
|---|---|
| Kubernetes Cluster | GKE Autopilot (v1.34) |
| Kyverno | v1.16.0 |
| GitOps Tool | ArgoCD (v3.x系) |
| IaC Tool | Helm (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のsyncOptionsにServerSideApply=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チャート内部では、権限管理に使われるClusterRoleやAggregationRuleにおいて、リソースの特定にapp.kubernetes.io/instanceラベルの値を厳密に参照(matchLabels)している箇所がありました。
ArgoCDがラベルの値を書き換えてしまったことで、Kyverno内部のセレクタ不整合(ラベルが一致しない)が発生。 コントローラーが正しく権限を集約できず、「リソースは作成されたが一向に正常動作しない」 という状態に陥りました。 - 解決策
この問題を解決するために、ArgoCD側の追跡方法をlabelからannotationに変更しました。
- 発生した事象
運用で気をつけたポイント
インストールのセクションで少し書きましたが、運用で気をつけるポイントのいくつか紹介します。
- Namespaceの除外 (Exclusions):
Kyvernoがkube-systemなどの重要なシステムコンポーネントにまで干渉すると、予期せぬ副作用でクラスターが不安定になる可能性があります。- 対策:
values.yamlのresourceFilters設定などを使い、以下のNamespaceを明示的にポリシー適用対象外にしました。(今回はnamespaceを対象外とするため、resourceFiltersIncludeNamespacesで設定しました)kube-systemgke-*系 (GKE Autopilot等のマネージドコンポーネント)
- 対策:
- 既存リソースへの影響 (Background Scan):
Kyvernoには、ポリシー適用前に作成された既存リソースを定期的にチェックするBackground Scan機能があると説明しました。しかし、挙動で注意する点があります。- 課題:
デフォルト設定では、バックグラウンドスキャンの際、グローバルな除外設定(resourceFilters)がスキップされる仕様になっている場合があります。
これにより、本来除外したはずのkube-system内のリソースに対してもスキャンが走ってしまい、大量の「違反レポート」が作成されたり、コントローラーのログがエラーや警告で埋め尽くされたりしてしまいます。 - 解決策:
values.yamlでskipResourceFilters: falseを明示的に設定します。
「フィルターのスキップを無効にする(=フィルターを有効にする)」という二重否定のような設定ですが、これを設定することで除外設定が尊重され、無駄なスキャンとログ出力を抑制できます。
- 課題:
まとめ
本記事では、GKE Autopilot環境において、Kyvernoを用いたポリシー基盤をArgoCDで構築する際の実践的なノウハウを紹介しました。
Kyvernoの最大の魅力は、やはり 「Kubernetesネイティブである(YAMLで書ける)」 という点です。Regoのような独自の言語を習得する必要がなく、既存のKubernetesの知識だけで高度なガバナンスをコード化できる点は、運用チームにとって非常に大きなメリットとなります。
一方で、本番運用の「基盤」として導入するには、単にインストールするだけでなく、様々な考慮が必要です。
ポリシー基盤は「開発者を縛るもの」と捉えられがちですが、適切に設計・運用すれば、「開発者が安心してアクセルを踏めるようにするためのガードレール」 となります。 ぜひ、今回のハマりどころや推奨設定を参考に、セキュアで生産性の高いKubernetesプラットフォームを構築してみてください。