<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Kyverno on AI2CORE - AI技術ブログ</title>
    <link>https://www.ai2core.com/tags/kyverno/</link>
    <description>Recent content in Kyverno on AI2CORE - AI技術ブログ</description>
    <generator>Hugo -- 0.146.4</generator>
    <language>ja</language>
    <lastBuildDate>Fri, 06 Mar 2026 09:05:00 +0900</lastBuildDate>
    <atom:link href="https://www.ai2core.com/tags/kyverno/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Kyvernoで始めるKubernetes Admission Policy実践: 事故を減らすポリシー設計プレイブック</title>
      <link>https://www.ai2core.com/posts/2026-03-06-kubernetes-admission-policy-kyverno-playbook/</link>
      <pubDate>Fri, 06 Mar 2026 09:05:00 +0900</pubDate>
      <guid>https://www.ai2core.com/posts/2026-03-06-kubernetes-admission-policy-kyverno-playbook/</guid>
      <description>KubernetesでKyvernoを使い、現場で運用可能なAdmission Policyを段階導入するための実装手順とトラブル対応を具体例付きで解説。</description>
      <content:encoded><![CDATA[<h1 id="kyvernoで始めるkubernetes-admission-policy実践-事故を減らすポリシー設計プレイブック">Kyvernoで始めるKubernetes Admission Policy実践: 事故を減らすポリシー設計プレイブック</h1>
<p>Kubernetes運用で一番つらい事故は、クラスタが壊れるよりも「本来防げたはずのミスがそのまま本番へ入る」ことです。たとえば、<code>latest</code> タグのイメージが本番に入り再現不能になる、<code>resources</code> 未設定でノードが詰まる、<code>privileged</code> コンテナが混入する。これらは人の注意力だけに依存すると必ず再発します。</p>
<p>そこで有効なのが Admission Policy（入場制御）です。本記事では <strong>Kyverno</strong> を使って、現場で本当に運用できるポリシー群を段階導入する手順をまとめます。単なる「denyの例」ではなく、監査→警告→強制の移行、例外管理、CI連携まで含めて解説します。</p>
<h2 id="1-なぜkyvernoなのか">1. なぜKyvernoなのか</h2>
<p>OPA Gatekeeper も強力ですが、Kyvernoは以下の特徴があり、初期導入が比較的スムーズです。</p>
<ul>
<li>YAML中心で書ける（Rego学習コストを後回しにしやすい）</li>
<li>validate / mutate / generate / verifyImages を一貫して扱える</li>
<li>PolicyReportにより違反可視化がしやすい</li>
<li>Pod SecurityやSupply Chain対策との相性が良い</li>
</ul>
<p>「まずルールを回し始める」目的なら、Kyvernoは現実的な選択肢です。</p>
<h2 id="2-先に決めるべき設計原則">2. 先に決めるべき設計原則</h2>
<p>導入前に、以下だけは先に決めておきます。</p>
<ol>
<li><strong>導入フェーズ</strong>: <code>Audit</code> → <code>Enforce</code> を基本にする</li>
<li><strong>責任分界</strong>: プラットフォームチームが共通ポリシー、各チームがアプリ固有例外</li>
<li><strong>例外の期限</strong>: 永久例外は禁止。期限付きで必ず棚卸し</li>
<li><strong>観測性</strong>: 違反数・対象Namespace・上位違反ルールをダッシュボード化</li>
</ol>
<p>この原則なしにルールだけ増やすと、運用が破綻します。</p>
<h2 id="3-最小導入手順3060分">3. 最小導入手順（30〜60分）</h2>
<h3 id="31-kyvernoのインストール">3.1 Kyvernoのインストール</h3>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">9
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>helm repo add kyverno https://kyverno.github.io/kyverno/
</span></span><span style="display:flex;"><span>helm repo update
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>helm upgrade --install kyverno kyverno/kyverno <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  -n kyverno --create-namespace <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  --set admissionController.replicas<span style="color:#f92672">=</span><span style="color:#ae81ff">2</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  --set backgroundController.replicas<span style="color:#f92672">=</span><span style="color:#ae81ff">2</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  --set cleanupController.replicas<span style="color:#f92672">=</span><span style="color:#ae81ff">1</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  --set reportsController.replicas<span style="color:#f92672">=</span><span style="color:#ae81ff">1</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>本番では可用性のため、admission/backgroundは最低2レプリカ推奨です。</p>
<h3 id="32-まずはauditモードで3ルール">3.2 まずはAuditモードで3ルール</h3>
<p>最初に効くルールは、次の3つです。</p>
<ul>
<li>イメージタグに <code>latest</code> を禁止</li>
<li>CPU/Memory requests/limits必須</li>
<li><code>privileged: true</code> を禁止</li>
</ul>
<p>例: <code>latest</code> タグ禁止</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">apiVersion</span>: <span style="color:#ae81ff">kyverno.io/v1</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">kind</span>: <span style="color:#ae81ff">ClusterPolicy</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">metadata</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">name</span>: <span style="color:#ae81ff">disallow-latest-tag</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">spec</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">validationFailureAction</span>: <span style="color:#ae81ff">Audit</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">background</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">rules</span>:
</span></span><span style="display:flex;"><span>    - <span style="color:#f92672">name</span>: <span style="color:#ae81ff">validate-image-tag</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">match</span>:
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">any</span>:
</span></span><span style="display:flex;"><span>          - <span style="color:#f92672">resources</span>:
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">kinds</span>:
</span></span><span style="display:flex;"><span>                - <span style="color:#ae81ff">Pod</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">validate</span>:
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">message</span>: <span style="color:#e6db74">&#34;latestタグは禁止です。固定タグまたはdigestを使用してください。&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">foreach</span>:
</span></span><span style="display:flex;"><span>          - <span style="color:#f92672">list</span>: <span style="color:#e6db74">&#34;request.object.spec.containers&#34;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">deny</span>:
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">conditions</span>:
</span></span><span style="display:flex;"><span>                <span style="color:#f92672">any</span>:
</span></span><span style="display:flex;"><span>                  - <span style="color:#f92672">key</span>: <span style="color:#e6db74">&#34;{{ element.image }}&#34;</span>
</span></span><span style="display:flex;"><span>                    <span style="color:#f92672">operator</span>: <span style="color:#ae81ff">Matches</span>
</span></span><span style="display:flex;"><span>                    <span style="color:#f92672">value</span>: <span style="color:#e6db74">&#34;.*:latest$&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="33-レポートで現状把握">3.3 レポートで現状把握</h3>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>kubectl get policyreport -A
</span></span><span style="display:flex;"><span>kubectl get clusterpolicy
</span></span><span style="display:flex;"><span>kubectl describe clusterpolicy disallow-latest-tag
</span></span></code></pre></td></tr></table>
</div>
</div><p>導入直後は違反が大量に出るのが普通です。ここで「Kyvernoが厳しすぎる」と判断しないでください。違反は“見えていなかった負債”です。</p>
<h2 id="4-実務で効くルールセット具体例">4. 実務で効くルールセット（具体例）</h2>
<h3 id="41-リソース未設定防止">4.1 リソース未設定防止</h3>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">apiVersion</span>: <span style="color:#ae81ff">kyverno.io/v1</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">kind</span>: <span style="color:#ae81ff">ClusterPolicy</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">metadata</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">name</span>: <span style="color:#ae81ff">require-resources</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">spec</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">validationFailureAction</span>: <span style="color:#ae81ff">Audit</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">rules</span>:
</span></span><span style="display:flex;"><span>    - <span style="color:#f92672">name</span>: <span style="color:#ae81ff">check-resources</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">match</span>:
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">any</span>:
</span></span><span style="display:flex;"><span>          - <span style="color:#f92672">resources</span>:
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">kinds</span>: [<span style="color:#e6db74">&#34;Pod&#34;</span>]
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">validate</span>:
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">message</span>: <span style="color:#e6db74">&#34;全コンテナにrequests/limitsを設定してください。&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">pattern</span>:
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">spec</span>:
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">containers</span>:
</span></span><span style="display:flex;"><span>              - <span style="color:#f92672">resources</span>:
</span></span><span style="display:flex;"><span>                  <span style="color:#f92672">requests</span>:
</span></span><span style="display:flex;"><span>                    <span style="color:#f92672">cpu</span>: <span style="color:#e6db74">&#34;?*&#34;</span>
</span></span><span style="display:flex;"><span>                    <span style="color:#f92672">memory</span>: <span style="color:#e6db74">&#34;?*&#34;</span>
</span></span><span style="display:flex;"><span>                  <span style="color:#f92672">limits</span>:
</span></span><span style="display:flex;"><span>                    <span style="color:#f92672">cpu</span>: <span style="color:#e6db74">&#34;?*&#34;</span>
</span></span><span style="display:flex;"><span>                    <span style="color:#f92672">memory</span>: <span style="color:#e6db74">&#34;?*&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="42-特権設定防止">4.2 特権設定防止</h3>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">apiVersion</span>: <span style="color:#ae81ff">kyverno.io/v1</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">kind</span>: <span style="color:#ae81ff">ClusterPolicy</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">metadata</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">name</span>: <span style="color:#ae81ff">disallow-privileged</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">spec</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">validationFailureAction</span>: <span style="color:#ae81ff">Enforce</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">rules</span>:
</span></span><span style="display:flex;"><span>    - <span style="color:#f92672">name</span>: <span style="color:#66d9ef">no</span>-<span style="color:#ae81ff">privileged</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">match</span>:
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">any</span>:
</span></span><span style="display:flex;"><span>          - <span style="color:#f92672">resources</span>:
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">kinds</span>: [<span style="color:#e6db74">&#34;Pod&#34;</span>]
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">validate</span>:
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">message</span>: <span style="color:#e6db74">&#34;privilegedコンテナは禁止です。&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">pattern</span>:
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">spec</span>:
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">containers</span>:
</span></span><span style="display:flex;"><span>              - <span style="color:#f92672">securityContext</span>:
</span></span><span style="display:flex;"><span>                  <span style="color:#f92672">=(privileged)</span>: <span style="color:#e6db74">&#34;false&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="43-digest固定の推奨supply-chain">4.3 Digest固定の推奨（Supply Chain）</h3>
<p>本来は digest 固定が理想です。移行期は <code>Audit</code> で始め、違反率が下がってから <code>Enforce</code> に切り替えます。</p>
<h2 id="5-auditからenforceへ移行する基準">5. AuditからEnforceへ移行する基準</h2>
<p>「何となく」で切り替えると炎上します。次の客観指標を使うと安全です。</p>
<ul>
<li>直近14日で対象ポリシー違反率が5%未満</li>
<li>主要Namespace（prod/stg/shared）で違反ゼロ</li>
<li>例外申請フロー（Issue/PRテンプレート）が整備済み</li>
<li>当番がトラブル時に切り戻し手順を理解している</li>
</ul>
<p><code>validationFailureAction</code> を一括で上げるのではなく、ルール単位・Namespace単位で段階化するのがポイントです。</p>
<h2 id="6-例外運用のテンプレート">6. 例外運用のテンプレート</h2>
<p>ポリシー導入で最も壊れるのは「例外管理」です。おすすめは以下。</p>
<ul>
<li>例外は <code>PolicyException</code> で明示</li>
<li>期限（例: 14日）を必須にする</li>
<li>チケット番号をannotationで必須化</li>
<li>期限切れを毎日バッチで通知</li>
</ul>
<p>例外YAMLに <code>expires</code> と <code>owner</code> を必須化すると、放置率が一気に下がります。</p>
<h2 id="7-ciに組み込んで本番前に落とす">7. CIに組み込んで“本番前に落とす”</h2>
<p>クラスタ投入時に拒否されるより、PR段階で検知される方が開発体験は良いです。<code>kyverno-cli</code> をCIで実行します。</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>kyverno apply policies/ -r manifests/ --audit-warn
</span></span></code></pre></td></tr></table>
</div>
</div><p>GitHub Actions例:</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">4
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span>- <span style="color:#f92672">name</span>: <span style="color:#ae81ff">Validate manifests with Kyverno</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">run</span>: |<span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    kyverno version
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    kyverno apply ./policies -r ./k8s --audit-warn</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>これで「マージ後に初めて失敗する」パターンを減らせます。</p>
<h2 id="8-よくある障害と対処">8. よくある障害と対処</h2>
<h3 id="症状1-正常なpodまで拒否される">症状1: 正常なPodまで拒否される</h3>
<ul>
<li>match条件が広すぎる可能性</li>
<li><code>exclude</code> で <code>kube-system</code> や監視系を一時除外</li>
<li>まずAuditで影響範囲を確認してからEnforceへ</li>
</ul>
<h3 id="症状2-admission-timeoutでデプロイ遅延">症状2: Admission timeoutでデプロイ遅延</h3>
<ul>
<li>Kyvernoコンポーネントのリソース不足を確認</li>
<li>policy数が多い場合、ルール統合とmatch最適化</li>
<li>API Serverとのネットワーク遅延確認</li>
</ul>
<h3 id="症状3-レポートは出るが改善が進まない">症状3: レポートは出るが改善が進まない</h3>
<ul>
<li>違反上位3ルールに絞ってKPI化</li>
<li>チーム別に違反件数を見える化</li>
<li>例外を期限付きに強制</li>
</ul>
<h2 id="9-運用を続けるためのダッシュボード指標">9. 運用を続けるためのダッシュボード指標</h2>
<p>最低限、以下を可視化してください。</p>
<ul>
<li>ルール別違反件数（7日移動平均）</li>
<li>Namespace別違反件数</li>
<li><code>Audit</code> と <code>Enforce</code> の比率</li>
<li>期限切れ例外の件数</li>
<li>deploy失敗要因のうちpolicy起因の割合</li>
</ul>
<p>これを見ないと、ポリシーは「導入しただけ」で止まります。</p>
<h2 id="10-実践ロードマップ最初の4週間">10. 実践ロードマップ（最初の4週間）</h2>
<ul>
<li><strong>Week 1</strong>: Kyverno導入、3ルールをAuditで開始</li>
<li><strong>Week 2</strong>: 違反上位を改善、例外テンプレート導入</li>
<li><strong>Week 3</strong>: 一部NamespaceでEnforce化</li>
<li><strong>Week 4</strong>: CI連携完了、SLOに違反率を組み込み</li>
</ul>
<p>4週間で「人頼みのレビュー文化」から「仕組みで防ぐ文化」へ移行できます。</p>
<h2 id="まとめ">まとめ</h2>
<p>Kyverno導入の本質は、Kubernetesを縛ることではなく、<strong>再発するミスを設計で減らすこと</strong>です。</p>
<ul>
<li>最初はAuditで可視化</li>
<li>指標を持って段階的にEnforce</li>
<li>例外は期限付きで管理</li>
<li>CIに前倒し検知を組み込む</li>
</ul>
<p>この4点を守れば、ポリシーは“開発を止める壁”ではなく“事故を減らすガードレール”になります。まずは <code>latest</code> 禁止とリソース必須の2ルールから始めて、違反データを見ながら育てていきましょう。</p>
]]></content:encoded>
      <category>Tech</category>
      <category>Kubernetes</category>
      <category>Kyverno</category>
      <category>Security</category>
      <category>Platform Engineering</category>
      <category>Policy as Code</category>
    </item>
  </channel>
</rss>
