Kyvernoで始めるKubernetes Admission Policy実践: 事故を減らすポリシー設計プレイブック

Kubernetes運用で一番つらい事故は、クラスタが壊れるよりも「本来防げたはずのミスがそのまま本番へ入る」ことです。たとえば、latest タグのイメージが本番に入り再現不能になる、resources 未設定でノードが詰まる、privileged コンテナが混入する。これらは人の注意力だけに依存すると必ず再発します。

そこで有効なのが Admission Policy(入場制御)です。本記事では Kyverno を使って、現場で本当に運用できるポリシー群を段階導入する手順をまとめます。単なる「denyの例」ではなく、監査→警告→強制の移行、例外管理、CI連携まで含めて解説します。

1. なぜKyvernoなのか

OPA Gatekeeper も強力ですが、Kyvernoは以下の特徴があり、初期導入が比較的スムーズです。

  • YAML中心で書ける(Rego学習コストを後回しにしやすい)
  • validate / mutate / generate / verifyImages を一貫して扱える
  • PolicyReportにより違反可視化がしやすい
  • Pod SecurityやSupply Chain対策との相性が良い

「まずルールを回し始める」目的なら、Kyvernoは現実的な選択肢です。

2. 先に決めるべき設計原則

導入前に、以下だけは先に決めておきます。

  1. 導入フェーズ: AuditEnforce を基本にする
  2. 責任分界: プラットフォームチームが共通ポリシー、各チームがアプリ固有例外
  3. 例外の期限: 永久例外は禁止。期限付きで必ず棚卸し
  4. 観測性: 違反数・対象Namespace・上位違反ルールをダッシュボード化

この原則なしにルールだけ増やすと、運用が破綻します。

3. 最小導入手順(30〜60分)

3.1 Kyvernoのインストール

1
2
3
4
5
6
7
8
9
helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update

helm upgrade --install kyverno kyverno/kyverno \
  -n kyverno --create-namespace \
  --set admissionController.replicas=2 \
  --set backgroundController.replicas=2 \
  --set cleanupController.replicas=1 \
  --set reportsController.replicas=1

本番では可用性のため、admission/backgroundは最低2レプリカ推奨です。

3.2 まずはAuditモードで3ルール

最初に効くルールは、次の3つです。

  • イメージタグに latest を禁止
  • CPU/Memory requests/limits必須
  • privileged: true を禁止

例: latest タグ禁止

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-latest-tag
spec:
  validationFailureAction: Audit
  background: true
  rules:
    - name: validate-image-tag
      match:
        any:
          - resources:
              kinds:
                - Pod
      validate:
        message: "latestタグは禁止です。固定タグまたはdigestを使用してください。"
        foreach:
          - list: "request.object.spec.containers"
            deny:
              conditions:
                any:
                  - key: "{{ element.image }}"
                    operator: Matches
                    value: ".*:latest$"

3.3 レポートで現状把握

1
2
3
kubectl get policyreport -A
kubectl get clusterpolicy
kubectl describe clusterpolicy disallow-latest-tag

導入直後は違反が大量に出るのが普通です。ここで「Kyvernoが厳しすぎる」と判断しないでください。違反は“見えていなかった負債”です。

4. 実務で効くルールセット(具体例)

4.1 リソース未設定防止

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-resources
spec:
  validationFailureAction: Audit
  rules:
    - name: check-resources
      match:
        any:
          - resources:
              kinds: ["Pod"]
      validate:
        message: "全コンテナにrequests/limitsを設定してください。"
        pattern:
          spec:
            containers:
              - resources:
                  requests:
                    cpu: "?*"
                    memory: "?*"
                  limits:
                    cpu: "?*"
                    memory: "?*"

4.2 特権設定防止

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-privileged
spec:
  validationFailureAction: Enforce
  rules:
    - name: no-privileged
      match:
        any:
          - resources:
              kinds: ["Pod"]
      validate:
        message: "privilegedコンテナは禁止です。"
        pattern:
          spec:
            containers:
              - securityContext:
                  =(privileged): "false"

4.3 Digest固定の推奨(Supply Chain)

本来は digest 固定が理想です。移行期は Audit で始め、違反率が下がってから Enforce に切り替えます。

5. AuditからEnforceへ移行する基準

「何となく」で切り替えると炎上します。次の客観指標を使うと安全です。

  • 直近14日で対象ポリシー違反率が5%未満
  • 主要Namespace(prod/stg/shared)で違反ゼロ
  • 例外申請フロー(Issue/PRテンプレート)が整備済み
  • 当番がトラブル時に切り戻し手順を理解している

validationFailureAction を一括で上げるのではなく、ルール単位・Namespace単位で段階化するのがポイントです。

6. 例外運用のテンプレート

ポリシー導入で最も壊れるのは「例外管理」です。おすすめは以下。

  • 例外は PolicyException で明示
  • 期限(例: 14日)を必須にする
  • チケット番号をannotationで必須化
  • 期限切れを毎日バッチで通知

例外YAMLに expiresowner を必須化すると、放置率が一気に下がります。

7. CIに組み込んで“本番前に落とす”

クラスタ投入時に拒否されるより、PR段階で検知される方が開発体験は良いです。kyverno-cli をCIで実行します。

1
kyverno apply policies/ -r manifests/ --audit-warn

GitHub Actions例:

1
2
3
4
- name: Validate manifests with Kyverno
  run: |
    kyverno version
    kyverno apply ./policies -r ./k8s --audit-warn

これで「マージ後に初めて失敗する」パターンを減らせます。

8. よくある障害と対処

症状1: 正常なPodまで拒否される

  • match条件が広すぎる可能性
  • excludekube-system や監視系を一時除外
  • まずAuditで影響範囲を確認してからEnforceへ

症状2: Admission timeoutでデプロイ遅延

  • Kyvernoコンポーネントのリソース不足を確認
  • policy数が多い場合、ルール統合とmatch最適化
  • API Serverとのネットワーク遅延確認

症状3: レポートは出るが改善が進まない

  • 違反上位3ルールに絞ってKPI化
  • チーム別に違反件数を見える化
  • 例外を期限付きに強制

9. 運用を続けるためのダッシュボード指標

最低限、以下を可視化してください。

  • ルール別違反件数(7日移動平均)
  • Namespace別違反件数
  • AuditEnforce の比率
  • 期限切れ例外の件数
  • deploy失敗要因のうちpolicy起因の割合

これを見ないと、ポリシーは「導入しただけ」で止まります。

10. 実践ロードマップ(最初の4週間)

  • Week 1: Kyverno導入、3ルールをAuditで開始
  • Week 2: 違反上位を改善、例外テンプレート導入
  • Week 3: 一部NamespaceでEnforce化
  • Week 4: CI連携完了、SLOに違反率を組み込み

4週間で「人頼みのレビュー文化」から「仕組みで防ぐ文化」へ移行できます。

まとめ

Kyverno導入の本質は、Kubernetesを縛ることではなく、再発するミスを設計で減らすことです。

  • 最初はAuditで可視化
  • 指標を持って段階的にEnforce
  • 例外は期限付きで管理
  • CIに前倒し検知を組み込む

この4点を守れば、ポリシーは“開発を止める壁”ではなく“事故を減らすガードレール”になります。まずは latest 禁止とリソース必須の2ルールから始めて、違反データを見ながら育てていきましょう。