[{"data":1,"prerenderedAt":539},["ShallowReactive",2],{"blog-ja-k3s-mutatingadmissionpolicy-webhook-sidecar-injection":3,"blog-related-ja-k3s-mutatingadmissionpolicy-webhook-sidecar-injection":487,"blog-ja-k3s-mutatingadmissionpolicy-webhook-sidecar-injection-alt":476},{"id":4,"title":5,"author":6,"body":7,"date":470,"description":471,"extension":472,"image":473,"locale":474,"meta":475,"navigation":476,"path":477,"seo":478,"stem":479,"tags":480,"__hash__":486},"blog\u002Fblog\u002Fja\u002Fk3s-mutatingadmissionpolicy-webhook-sidecar-injection.md","Webhookの証明書管理、もう要らない。MutatingAdmissionPolicyがK3sのサイドカー注入を変える","Kubo Team",{"type":8,"value":9,"toc":462},"minimark",[10,15,23,31,42,48,52,58,74,89,92,96,102,117,125,146,149,274,283,286,290,296,299,304,319,322,327,338,347,364,368,374,388,398,406,420,424,427,443,458],[11,12,14],"h2",{"id":13},"_1-リソースがetcdに書き込まれる前の最後の関門-admission-controlとは何か","1. リソースがetcdに書き込まれる前の最後の関門 — admission controlとは何か",[16,17,18],"p",{},[19,20],"img",{"alt":21,"src":22},"section01","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fja\u002Fk3s-mutatingadmissionpolicy-webhook-sidecar-injection\u002Fsection01.webp",[16,24,25,26,30],{},"Kubernetes v1.36でGAした",[27,28,29],"strong",{},"MutatingAdmissionPolicy","は、この「受け入れる状態を決める層」の仕組みを変える機能だ。Kubernetesの中核には、望ましい状態と実際の状態を常に比較し続け、差分があれば自動的に修正するという単純な仕組みがある。デプロイメントに「10個のPodを動かしてほしい」と伝えれば、Kubernetesはそれを実現し続ける。しかし、この仕組みが機能する前提には、「そもそも何を望ましい状態として受け入れるか」を決める層が存在する。それが admission control だ。",[16,32,33,34,41],{},"Podがetcdに書き込まれる直前、APIサーバーは2段階のチェックを行う。まずMutating admissionでリソースを変更し、次にValidating admissionで内容を検証する。この順序と仕組みは",[35,36,40],"a",{"href":37,"rel":38},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Freference\u002Faccess-authn-authz\u002Fextensible-admission-controllers\u002F",[39],"nofollow","Kubernetes公式ドキュメント","に明記されている。ラベルの自動付与、デフォルト値の設定、サイドカーコンテナの注入といった処理は、すべてこのMutating admissionの段階で行われる。",[16,43,44,45,47],{},"長らく、この段階をカスタマイズする唯一の方法はMutating Admission Webhookだった。そして2026年、この前提を変える機能がKubernetes本体に入った。",[27,46,29],{},"だ。",[11,49,51],{"id":50},"_2-mutating-webhookの運用コスト-証明書ネットワークホップ可用性","2. Mutating Webhookの運用コスト — 証明書・ネットワークホップ・可用性",[16,53,54],{},[19,55],{"alt":56,"src":57},"section02","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fja\u002Fk3s-mutatingadmissionpolicy-webhook-sidecar-injection\u002Fsection02.webp",[16,59,60,61,64,65,69,70,73],{},"Mutating Webhookを自前で運用したことがあるチームなら、その運用コストに心当たりがあるはずだ。",[35,62,40],{"href":37,"rel":63},[39],"によると、WebhookConfigurationにはPEM形式でBase64エンコードされたCA証明書（",[66,67,68],"code",{},"caBundle","）が必須で、サーバー証明書は",[66,71,72],{},"\u003Csvc_name>.\u003Csvc_namespace>.svc","形式で有効でなければならない。証明書が期限切れになれば、Webhook自体が機能を失う。",[16,75,76,77,80,81,84,85,88],{},"さらに、Webhookサーバーをクラスタ内にDeploymentとして動かす場合、そのPod自体の可用性もチームが担保しなければならない。タイムアウト設定（デフォルト10秒）と",[66,78,79],{},"failurePolicy","（",[66,82,83],{},"Fail","か",[66,86,87],{},"Ignore","か）の組み合わせ次第では、Webhookサーバーの障害がPodの作成そのものを止めてしまう。公式ドキュメントも「Admission webhookは本質的にクラスタコントロールプレーンの一部であり、本番環境では細心の注意を払って構築・デプロイする必要がある」と明記している。",[16,90,91],{},"要するに、Mutating Webhookは「証明書管理」「ネットワークホップ」「可用性確保」という3つの運用負債を常に抱え続ける仕組みだった。",[11,93,95],{"id":94},"_3-mutatingadmissionpolicyは何を変えるのか-celでapiサーバー内蔵のミューテーション","3. MutatingAdmissionPolicyは何を変えるのか — CELでAPIサーバー内蔵のミューテーション",[16,97,98],{},[19,99],{"alt":100,"src":101},"section03","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fja\u002Fk3s-mutatingadmissionpolicy-webhook-sidecar-injection\u002Fsection03.webp",[16,103,104,105,110,111,116],{},"MutatingAdmissionPolicyは、",[35,106,109],{"href":107,"rel":108},"https:\u002F\u002Fwww.kubernetes.dev\u002Fresources\u002Fkeps\u002F3962\u002F",[39],"KEP-3962","として提案され、v1.32でalpha、v1.34でbetaを経て、**v1.36でGA（安定版）**に到達した。",[35,112,115],{"href":113,"rel":114},"https:\u002F\u002Fkubernetes.io\u002Fblog\u002F2026\u002F04\u002F22\u002Fkubernetes-v1-36-release\u002F",[39],"Kubernetes v1.36の公式リリース記事","でも、ValidatingAdmissionPolicyとMutatingAdmissionPolicyがデフォルト有効になったことが明記されている。",[16,118,119,120,124],{},"仕組みはシンプルだ。",[35,121,40],{"href":122,"rel":123},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Freference\u002Faccess-authn-authz\u002Fmutating-admission-policy\u002F",[39],"によれば、MutatingAdmissionPolicyは3つのリソースで構成される。",[126,127,128,134,140],"ul",{},[129,130,131,133],"li",{},[27,132,29],{},": ミューテーションの抽象ロジックをCEL式で定義する",[129,135,136,139],{},[27,137,138],{},"パラメータリソース","（任意）: ConfigMapやCRDなどで設定値を渡す",[129,141,142,145],{},[27,143,144],{},"MutatingAdmissionPolicyBinding",": ポリシーとパラメータを紐づけ、適用スコープ（対象リソース種別など）を指定する",[16,147,148],{},"例えばサイドカー注入は、以下のようなCEL式で表現できる。",[150,151,156],"pre",{"className":152,"code":153,"language":154,"meta":155,"style":155},"language-yaml shiki shiki-themes tokyo-night","mutations:\n  - patchType: \"ApplyConfiguration\"\n    applyConfiguration:\n      expression: >\n        Object{\n          spec: Object.spec{\n            initContainers: [\n              Object.spec.initContainers{\n                name: \"mesh-proxy\",\n                image: \"mesh\u002Fproxy:v1.0.0\"\n              }\n            ]\n          }\n        }\n","yaml","",[66,157,158,171,194,202,214,220,226,232,238,244,250,256,262,268],{"__ignoreMap":155},[159,160,163,167],"span",{"class":161,"line":162},"line",1,[159,164,166],{"class":165},"s0U2E","mutations",[159,168,170],{"class":169},"sAklC",":\n",[159,172,174,178,181,184,187,191],{"class":161,"line":173},2,[159,175,177],{"class":176},"sgJMe","  -",[159,179,180],{"class":165}," patchType",[159,182,183],{"class":169},":",[159,185,186],{"class":169}," \"",[159,188,190],{"class":189},"sPY7s","ApplyConfiguration",[159,192,193],{"class":169},"\"\n",[159,195,197,200],{"class":161,"line":196},3,[159,198,199],{"class":165},"    applyConfiguration",[159,201,170],{"class":169},[159,203,205,208,210],{"class":161,"line":204},4,[159,206,207],{"class":165},"      expression",[159,209,183],{"class":169},[159,211,213],{"class":212},"sEsAJ"," >\n",[159,215,217],{"class":161,"line":216},5,[159,218,219],{"class":189},"        Object{\n",[159,221,223],{"class":161,"line":222},6,[159,224,225],{"class":189},"          spec: Object.spec{\n",[159,227,229],{"class":161,"line":228},7,[159,230,231],{"class":189},"            initContainers: [\n",[159,233,235],{"class":161,"line":234},8,[159,236,237],{"class":189},"              Object.spec.initContainers{\n",[159,239,241],{"class":161,"line":240},9,[159,242,243],{"class":189},"                name: \"mesh-proxy\",\n",[159,245,247],{"class":161,"line":246},10,[159,248,249],{"class":189},"                image: \"mesh\u002Fproxy:v1.0.0\"\n",[159,251,253],{"class":161,"line":252},11,[159,254,255],{"class":189},"              }\n",[159,257,259],{"class":161,"line":258},12,[159,260,261],{"class":189},"            ]\n",[159,263,265],{"class":161,"line":264},13,[159,266,267],{"class":189},"          }\n",[159,269,271],{"class":161,"line":270},14,[159,272,273],{"class":189},"        }\n",[16,275,276,277,282],{},"外部サービスも証明書も登場しない。CEL式はAPIサーバー内で直接評価され、ネットワークホップそのものが消える。",[35,278,281],{"href":279,"rel":280},"https:\u002F\u002Fwww.cncf.io\u002Fblog\u002F2025\u002F01\u002F13\u002Fcel-ebrating-simplicity-mastering-kubernetes-policy-enforcement-with-cel",[39],"CNCFブログ","も「外部ツールがネットワーク呼び出しに依存するのに対し、CELはAPIサーバーに直接埋め込まれているため遅延が削減され信頼性が向上する」と指摘している。CEL式はループや再帰を持たないため線形時間で実行され、v1.32以降はコスト推定器によってAPIサーバーの過負荷も防がれる。",[16,284,285],{},"既存のMutating Webhookから移行する場合も、ApplyConfiguration戦略に加えてJSON Patch戦略が用意されており、既存のWebhookロジックをそのまま移植しやすい設計になっている。",[11,287,289],{"id":288},"_4-どこまでcelに置き換えられるか-判断基準","4. どこまでCELに置き換えられるか — 判断基準",[16,291,292],{},[19,293],{"alt":294,"src":295},"section04","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fja\u002Fk3s-mutatingadmissionpolicy-webhook-sidecar-injection\u002Fsection04.webp",[16,297,298],{},"ここで誤解してはいけないのは、MutatingAdmissionPolicyはWebhookの「全廃」ではなく「代替」だという点だ。判断基準は次の2軸で整理できる。",[16,300,301],{},[27,302,303],{},"CELに置き換えるべきケース",[126,305,306,309,312],{},[129,307,308],{},"固定ラベル・アノテーションの付与",[129,310,311],{},"フィールドのデフォルト値設定",[129,313,314,315,318],{},"既存コンテナの有無をチェックしたうえでのサイドカー追加（",[66,316,317],{},"matchConditions","で重複注入を防げる）",[16,320,321],{},"これらは宣言的に表現でき、外部の状態を参照する必要がない。",[16,323,324],{},[27,325,326],{},"Webhookのまま残すべきケース",[126,328,329,332,335],{},[129,330,331],{},"外部データベースやAPIへの問い合わせが必要なミューテーション",[129,333,334],{},"複数の外部システムとの整合性チェックを伴う複雑なロジック",[129,336,337],{},"CELの式では表現しきれない手続き的な処理",[16,339,340,341,346],{},"なお、こうした新機能は標準Kubernetes API上で動く機能であるため、",[35,342,345],{"href":343,"rel":344},"https:\u002F\u002Fkubo.hexabase.io\u002F",[39],"K3sベースのKubo","のような環境であれば、ディストリビューション側の対応を待つ必要がなく素のKubernetesとして利用できる。",[16,348,349,350,355,356,359,360,363],{},"実際、Kyverno自身もこの境界線を踏まえた移行を進めている。",[35,351,354],{"href":352,"rel":353},"https:\u002F\u002Fnirmata.com\u002F2026\u002F07\u002F26\u002Fkyverno-policy-migration-to-cel-based-policies\u002F",[39],"Nirmataのブログ","によると、Kyvernoは旧来のパターンベースの",[66,357,358],{},"ClusterPolicy","を段階的に廃止し（v1.17で非推奨、v1.20での削除を予定）、",[66,361,362],{},"MutatingPolicy","を含む5つのCELベースの新しいAPIタイプへ移行している。記事は「CELはKubernetes自身がValidatingAdmissionPolicyで使っているのと同じ式言語であり、CELを学ぶことはKubernetesガバナンスツール全体に通用するスキルを身につけることだ」と述べている。",[11,365,367],{"id":366},"_5-k3s運用での移行判断と実践ステップ","5. K3s運用での移行判断と実践ステップ",[16,369,370],{},[19,371],{"alt":372,"src":373},"section05","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fja\u002Fk3s-mutatingadmissionpolicy-webhook-sidecar-injection\u002Fsection05.webp",[16,375,376,381,382,387],{},[35,377,380],{"href":378,"rel":379},"https:\u002F\u002Fk3s.io\u002F",[39],"K3s公式サイト","が謳う通り、K3sは「IoT & Edge computingのための認定Kubernetesディストリビューション」であり、70MB未満の単一バイナリに標準的なKubernetes APIをそのまま内包している。",[35,383,386],{"href":384,"rel":385},"https:\u002F\u002Fdocs.k3s.io\u002Frelease-notes\u002Fv1.36.X",[39],"K3sのリリースノート","が示す通り、K3s v1.36系はKubernetes v1.36をベースにしており、MutatingAdmissionPolicyはK3s上でも素のKubernetes機能としてそのまま利用できる。ベンダー独自の制限や追加設定は必要ない。",[16,389,390,391,393,394,397],{},"移行の進め方としては、まず既存のMutating Webhookを棚卸しし、「固定ラベル付与」「デフォルト値設定」「単純なサイドカー注入」といった宣言的に表現できるものと、「外部状態に依存する複雑なロジック」を分類する。前者から段階的にMutatingAdmissionPolicyへ移行し、",[66,392,317],{},"で対象スコープを絞り込んだうえで、まずは",[66,395,396],{},"failurePolicy: Ignore","のdry-run的な設定で既存リソースへの影響を確認してから本番適用するのが安全だ。",[16,399,400,401,405],{},"K3sベースの",[35,402,404],{"href":343,"rel":403},[39],"Kubo","のように標準Kubernetes APIをそのまま使える環境であれば、こうした新機能も特別な対応なしに利用できる。EKSやAKSのような独自レイヤーを挟まないぶん、本体の進化をそのまま享受できるのはK3sベース基盤の利点のひとつだ。",[16,407,408,409,413,414,419],{},"Mutating Webhookの運用で証明書の期限切れやPodの可用性に悩まされてきたチームにとって、棚卸しと段階移行そのものが手間に感じられるかもしれない。",[35,410,412],{"href":343,"rel":411},[39],"Kubo Cloud","のCaptain UIを使えば、どのリソースにどのadmission policyが適用され、どんな変更が加えられているかを可視化しながら移行を進められる。ブラックボックスのまま本番にポリシーを適用するリスクを避けたい場合は、",[35,415,418],{"href":416,"rel":417},"https:\u002F\u002Fwww.hexabase.com\u002Fcontact-us\u002F",[39],"お問い合わせ","から相談してみてほしい。",[11,421,423],{"id":422},"_6-まとめ","6. まとめ",[16,425,426],{},"MutatingAdmissionPolicyは、Mutating Webhookが抱えてきた証明書管理・ネットワークホップ・可用性確保という3つの運用負債を、CELという宣言的な表現に置き換えることで解消する。ただしそれは全廃ではなく、単純な宣言的変更をCELへ、外部状態に依存する複雑なミューテーションはWebhookへ、という役割分担だ。",[16,428,429,430,434,435,438,439,442],{},"K3sは標準Kubernetesのディストリビューションであるため、v1.36以降であればこの機能をそのまま利用できる。",[35,431,433],{"href":122,"rel":432},[39],"MutatingAdmissionPolicyの詳細仕様","は公式ドキュメントにまとまっているので、移行前に一読しておくとよい。まずは手元のMutating Webhookを棚卸しし、どこまでをCELに置き換えられるかを見極めることから始めてみてほしい。運用負荷を減らしながら本格的なKubernetesの機能を使い続けたいなら、",[35,436,345],{"href":343,"rel":437},[39],"がその選択肢のひとつになる。EKS\u002FAKSのパワーをそのままに、Vercelのような手軽さでクラスタを運用できる環境を目指すなら、",[35,440,404],{"href":343,"rel":441},[39],"を検討してみる価値がある。",[16,444,445,446,451,452,457],{},"関連する admission control の深掘りとしては、",[35,447,450],{"href":448,"rel":449},"https:\u002F\u002Fkubo.hexabase.io\u002Fblog\u002Fja\u002Fkyverno-validatingadmissionpolicy-cel-migration-silent-bypass",[39],"ValidatingAdmissionPolicyへの移行で何が起きたか","や、",[35,453,456],{"href":454,"rel":455},"https:\u002F\u002Fkubo.hexabase.io\u002Fblog\u002Fja\u002Fkyverno-opa-gatekeeper-k3s-wildcard-policy-overhead",[39],"KyvernoとOPA Gatekeeperの比較","も合わせて読んでほしい。",[459,460,461],"style",{},"html pre.shiki code .s0U2E, html code.shiki .s0U2E{--shiki-default:#F7768E}html pre.shiki code .sAklC, html code.shiki .sAklC{--shiki-default:#89DDFF}html pre.shiki code .sgJMe, html code.shiki .sgJMe{--shiki-default:#9ABDF5}html pre.shiki code .sPY7s, html code.shiki .sPY7s{--shiki-default:#9ECE6A}html pre.shiki code .sEsAJ, html code.shiki .sEsAJ{--shiki-default:#BB9AF7;--shiki-default-font-style:italic}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":155,"searchDepth":173,"depth":173,"links":463},[464,465,466,467,468,469],{"id":13,"depth":173,"text":14},{"id":50,"depth":173,"text":51},{"id":94,"depth":173,"text":95},{"id":288,"depth":173,"text":289},{"id":366,"depth":173,"text":367},{"id":422,"depth":173,"text":423},"2026-11-01","MutatingAdmissionPolicyがKubernetes v1.36でGAした。ラベル付与やサイドカー注入のための自作Mutating Webhookは、どこまでCELに置き換えられ、どこから先はWebhookのまま残すべきか。K3s運用での判断基準を整理する。","md","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fja\u002Fk3s-mutatingadmissionpolicy-webhook-sidecar-injection\u002Ftitle.webp","ja",{},true,"\u002Fblog\u002Fja\u002Fk3s-mutatingadmissionpolicy-webhook-sidecar-injection",{"title":5,"description":471},"blog\u002Fja\u002Fk3s-mutatingadmissionpolicy-webhook-sidecar-injection",[481,482,483,484,485],"k3s","kubernetes","mutatingadmissionpolicy","cel","admission-control","Lj2VKFJ0afbRCQyeOvzSwmV86KqcYNA40xD_JmBDAIw",[488,496,504,513,521,530],{"path":489,"title":490,"description":491,"date":492,"tags":493},"\u002Fblog\u002Fja\u002Fkyverno-validatingadmissionpolicy-cel-migration-silent-bypass","CELに書き換えたポリシーは、本当に同じ意味なのか。KyvernoからValidatingAdmissionPolicyへの移行で\"黙って素通り\"したリソースの正体","KyvernoのClusterPolicyが廃止へ向かう中、ValidatingAdmissionPolicy（CEL）に移行したら一部リソースだけ検証が素通りしていた。原因のCELランタイムエラーとfailurePolicyの罠、安全な移行手順を解説する。","2026-10-18",[481,482,494,495,484,485],"validatingadmissionpolicy","kyverno",{"path":497,"title":498,"description":499,"date":500,"tags":501},"\u002Fblog\u002Fja\u002Fkyverno-opa-gatekeeper-k3s-wildcard-policy-overhead","KyvernoとOPA Gatekeeper、K3sの本番で本当に差が出たのはワイルドカードポリシーだった","KyvernoとOPA GatekeeperはK3sの本番運用でどちらを選ぶべきか。ワイルドカードポリシーが招く負荷急増とレプリカ構成別のp99レイテンシ実測データから、K3s特有の判断基準を整理する。","2026-10-11",[481,482,495,502,485,503],"opa-gatekeeper","policy-as-code",{"path":505,"title":506,"description":507,"date":508,"tags":509},"\u002Fblog\u002Fja\u002Fcicd-pipeline-devsecops-gate-design-four-layers","そのCI\u002FCDパイプライン、セキュリティチェックをどこに置くか決めずに継ぎ足していないか。DevSecOpsゲート設計の4層モデル","SASTもDASTもコンテナスキャンも導入した。それでも本番で事故は起きる。CI\u002FCDパイプラインのセキュリティを『4つの層』で設計し直すDevSecOpsゲート設計の考え方を、K3s\u002FKubernetes運用の観点から解説する。","2026-08-28",[481,482,510,511,485,512],"ci-cd","devsecops","gitops",{"path":514,"title":515,"description":516,"date":517,"tags":518},"\u002Fblog\u002Fja\u002Fshadow-ai-kubernetes-admission-control-governance","野良デプロイが会社を壊す。KubernetesクラスターのシャドーAI問題とAdmission Controlという処方箋","SaaSの無断導入だけがシャドーAIではない。Kubernetesクラスター内で誰が何をデプロイしているか分からない状態が生むリスクと、Admission Controlによるガバナンス実装を解説する。","2026-07-17",[482,481,519,485,495,520],"shadow-ai","security",{"path":522,"title":523,"description":524,"date":525,"tags":526},"\u002Fblog\u002Fja\u002Fk3s-opencost-onprem-gcp-default-pricing","K3sのオンプレ環境にOpenCostを入れたら、コストは最初からGCPの値段で計算されていた","K3sのオンプレ・ベアメタル環境にOpenCostを導入しても、デフォルト設定のままではノードのCPU・RAMコストがGCP us-central1のクラウド料金で計算されてしまう。K3s環境で実際のハードウェアコストを正しく可視化するために必要なカスタム価格設定の手順と、見落としやすい理由を解説する。","2026-11-04",[481,482,527,528,529],"opencost","finops","cost-optimization",{"path":531,"title":532,"description":533,"date":534,"tags":535},"\u002Fblog\u002Fja\u002Fk3s-prometheus-agent-mode-stale-marker-edge-monitoring","K3sエッジのPrometheusをAgent modeにしたら、ターゲットが消えた瞬間にメトリクスも消えていた","K3sエッジクラスタでPrometheus Agent modeを使うと、ターゲット消失時のstale marker処理次第で中央監視に古い値が残り続けることがある。K3s edge環境の監視設計とつまずきポイントを解説する。","2026-11-03",[481,482,536,537,538],"prometheus","edge-computing","observability",1793798693386]