---
title: "Kubernetes v1.36: Admission Policies That Can't Be Deleted"
description: "If you've ever tried to enforce a security policy across a fleet of Kubernetes clusters, you've probably run into a frustrating chicken-and-egg proble"
tags: ["Kubernetes", "AI", "보안", "Rust"]
created: "2026-05-07"
---

# Kubernetes v1.36: Admission Policies That Can't Be Deleted

> 레이아웃 확인용으로 생성한 실시간 IT 뉴스 기반 샘플 문서입니다. 원문 RSS의 제목과 요약, 링크를 바탕으로 한국어 해설 형식의 본문을 구성했습니다.

## 원문 정보

- 출처: Kubernetes Blog
- 게시 시각: Mon, 04 May 2026 10:35:00 -0800
- 원문 링크: [https://kubernetes.io/blog/2026/05/04/kubernetes-v1-36-manifest-based-admission-control/](https://kubernetes.io/blog/2026/05/04/kubernetes-v1-36-manifest-based-admission-control/)

## 빠른 요약

If you've ever tried to enforce a security policy across a fleet of Kubernetes clusters, you've probably run into a frustrating chicken-and-egg problem. Your admission policies are API objects, which means they don't exist until someone creates them, and they can be deleted by anyone with the right permissions. There's always a window during cluster bootstrap where your policies aren't active yet, and there's no way to prevent a privileged user from removing them. Kubernetes v1.36 introduces an alpha feature that addresses this: manifest-based admission control . It lets you define admission webhooks and CEL -based policies as files on disk, loaded by the API server at startup, before it serves any requests. The gap we're closing Most Kubernetes policy enforcement today works through the API. You create a ValidatingAdmissionPolicy or a webhook configuration as an API object, and the admission controller picks it up. This works well in steady state, but it has some fundamental limitations. During cluster bootstrap, there's a gap between when the API server starts serving requests and when your policies are created and active. If you're restoring from a backup or recovering from an etcd failure, that gap can be significant. There's also a self-protection problem. Admission webhooks and policies can't intercept operations on their own configuration resources. Kubernetes skips invoking webhooks on types like ValidatingWebhookConfiguration to avoid circular dependencies. That means a sufficiently privileged user can delete your critical admission policies, and there's nothing in the admission chain to stop them. We - Kubernetes SIG API Machinery - wanted a way to say "these policies are always on, full stop." How it works You add a staticManifestsDir field to the AdmissionConfiguration file that you already pass to the API server via --admission-control-config-file . Point it at a directory, drop your policy YAML files in there, and the API server loads them before it starts serving. apiVersion : apiserver.config.k8s.io/v1 kind : AdmissionConfiguration plugins : - name : ValidatingAdmissionPolicy configuration : apiVersion : apiserver.config.k8s.io/v1 kind : ValidatingAdmissionPolicyConfiguration staticManifestsDir : "/etc/kubernetes/admission/validating-policies/" The manifest files are standard Kubernetes resource definitions. The only requirement is that all the objects that these manifests define must have names ending in .static.k8s.io . This reserved suffix prevents collisions with API-based configurations and makes it easy to tell where an admission decision came from when you're looking at metrics or audit logs. Here's a complete example that denies privileged containers outside kube-system: apiVersion : admissionregistration.k8s.io/v1 kind : ValidatingAdmissionPolicy metadata : name : "deny-privileged.static.k8s.io" annotations : kubernetes.io/description : "Deny launching privileged pods, anywhere this policy is applied" spec : failurePolicy : Fail matchConstraints : resourceRules : - apiGroups : [ "" ] apiVersions : [ "v1" ] operations : [ "CREATE" , "UPDATE" ] resources : [ "pods" ] variables : - name : allContainers expression : >- object.spec.containers + (has(object.spec.initContainers) ? object.spec.initContainers : []) + (has(object.spec.ephemeralContainers) ? object.spec.ephemeralContainers : []) validations : - expression : >- !variables.allContainers.exists(c, has(c.securityContext) && has(c.securityContext.privileged) && c.securityContext.privileged == true) message : "Privileged containers are not allowed" --- apiVersion : admissionregistration.k8s.io/v1 kind : ValidatingAdmissionPolicyBinding metadata : name : "deny-privileged-binding.static.k8s.io" annotations : kubernetes.io/description : "Bind deny-privileged policy to all namespaces except kube-system" spec : policyName : "deny-privileged.static.k8s.io" validationActions : - Deny matchResources : namespaceSelector : matchExpressions : - key : "kubernetes.io/metadata.name" operator : NotIn values : [ "kube-system" ] Protecting what couldn't be protected before The part we're most excited about is the ability to intercept operations on admission configuration resources themselves. With API-based admission, webhooks and policies are never invoked on types like ValidatingAdmissionPolicy or ValidatingWebhookConfiguration. That restriction exists for good reason: if a webhook could reject changes to its own configuration, you could end up locked out with no way to fix it through the API. Manifest-based policies don't have that problem. If a bad policy is blocking something it shouldn't, you fix the file on disk and the API server picks up the change. There's no circular dependency because the recovery path doesn't go through the API. This means you can write a manifest-based policy that prevents deletion of your critical API-based admission policies. For platform teams managing shared clusters, this is a significant improvement. You can now guarantee that your baseline security policies can't be removed by a cluster admin, accidentally or otherwise. Here's what that looks like in practice. This policy prevents any modification or deletion of admission resources that carry the platform.example.com/protected: "true" label: apiVersion : admissionregistration.k8s.io/v1 kind : ValidatingAdmissionPolicy metadata : name : "protect-policies.static.k8s.io" annotations : kubernetes.io/description : "Prevent modification or deletion of protected admission resources" spec : failurePolicy : Fail matchConstraints : resourceRules : - apiGroups : [ "admissionregistration.k8s.io" ] apiVersions : [ "*" ] operations : [ "DELETE" , "UPDATE" ] resources : - "validatingadmissionpolicies" - "validatingadmissionpolicybindings" - "validatingwebhookconfigurations" - "mutatingwebhookconfigurations" validations : - expression : >- !has(oldObject.metadata.labels) || !('platform.example.com/protected' in oldObject.metadata.labels) || oldObject.metadata.labels['platform.example.com/protected'] != 'true' message : "Protected admission resources cannot be modified or deleted" --- apiVersion : admissionregistration.k8s.io/v1 kind : ValidatingAdmissionPolicyBinding metadata : name : "protect-policies-binding.static.k8s.io" annotations : kubernetes.io/description : "Bind protect-policies policy to all admission resources" spec : policyName : "protect-policies.static.k8s.io" validationActions : - Deny With this in place, any API-based admission policy or webhook configuration labeled platform.example.com/protected: "true" is shielded from tampering. The protection itself lives on disk and can't be removed through the API. A few things to know Manifest-based configurations are intentionally self-contained. They can't reference API resources, which means no paramKind for policies, no Service references for admission webhooks (instead they are URL-only), and bindings may only reference policies in the same manifest set. These restrictions exist because the configurations need to work without any cluster state, including at startup before etcd is available. If you run multiple API server instances, each one loads its own manifest files independently. There's no cross-server synchronization built in. This is the same model as other file-based API server configurations like encryption at rest. When this feature is enabled, Kubernetes exposes a configuration hash as a label on relevant metrics, so you can detect drift. Files are watched for changes at runtime, so you don't need to restart the API server to update policies. If you update a manifest file, the API server validates the new configuration and swaps it in atomically. If validation fails, it keeps the previous good configuration and logs the error. This means you can roll out policy changes across your fleet using standard configuration management tools (Ansible, Puppet, or even mounted ConfigMaps) without any API server downtime. The initial load at startup is stricter: if any manifest is invalid, the API server won't start. This is intentional. At startup, failing fast is safer than running without your expected policies. Try it out To try this in Kubernetes v1.36: Enable the ManifestBasedAdmissionControlConfig feature gate for each kube-apiserver. Create a directory with your static manifest files. If you need to mount that in to the Pod where the API server runs, do that too. Read-only is fine. Configure staticManifestsDir in your AdmissionConfiguration with the directory path. Start the API server with --admission-control-config-file pointing to your AdmissionConfiguration file. The full documentation is at Manifest-Based Admission Control , and you can follow KEP-5793 for ongoing progress. We'd love to hear your feedback. Reach out on the #sig-api-machinery channel on Kubernetes Slack (for an invitation, visit https://slack.k8s.io/ ). How to get involved If you're interested in contributing to this feature or other SIG API Machinery projects, join us on #sig-api-machinery on Kubernetes Slack. You're also welcome to attend the SIG API Machinery meetings , held every other Wednesday.

이 항목은 `문서/Kubernetes` 카테고리에 배치했습니다. 실제 운영에서는 Hermes가 뉴스 후보를 수집한 뒤, 제목·요약·출처·태그·관련 내부 문서를 함께 정리하는 방식으로 확장할 수 있습니다. 지금은 화면 확인을 위해 의도적으로 본문을 어느 정도 길게 구성했습니다.

## 왜 볼 만한가

첫째, 이 소식은 단순한 제품 발표나 링크 모음으로 끝나지 않고 개발자 경험, 인프라 운영, 보안 정책, 클라우드 비용, AI 도구 활용 방식 중 하나와 연결될 가능성이 있습니다. 기술 뉴스 사이트를 운영할 때 중요한 점은 “무슨 일이 있었다”보다 “내 운영 환경이나 학습 경로에 어떤 의미가 있는가”를 정리하는 것입니다.

둘째, 이 문서는 카테고리와 태그가 실제 화면에서 어떻게 보이는지 확인하기 위한 샘플입니다. 좌측 문서 트리에는 디렉토리 구조가 그대로 나타나고, 홈 화면의 최신 문서 카드에는 제목과 설명이 표시됩니다. 검색 페이지에서는 제목, 요약, 본문 일부가 SQLite FTS5 인덱스에 들어가므로 실제 검색 결과의 밀도도 확인할 수 있습니다.

## 운영자 관점의 해설

Hermes 기반 자동 게시 시스템에서는 이런 글을 주기적으로 생성하되, 원문을 단순 번역하지 않는 것이 중요합니다. 원문 링크를 남기고, 한국어 독자가 바로 판단할 수 있도록 맥락과 적용 포인트를 붙이는 편이 좋습니다. 예를 들어 보안 관련 뉴스라면 “패치 여부”, “영향받는 구성”, “내 서버에서 확인할 명령”이 필요하고, AI 도구 뉴스라면 “실제 워크플로우 변화”, “비용 구조”, “자동화 가능성”을 정리하는 것이 유용합니다.

## 사이트 레이아웃 확인 포인트

- 긴 제목이 카드와 본문에서 줄바꿈될 때 어색하지 않은지 확인합니다.
- 태그가 많을 때 좌측 사이드바와 문서 헤더가 지나치게 복잡해지지 않는지 봅니다.
- 원문 링크가 본문 폭을 깨뜨리지 않는지 확인합니다.
- 우측 목차가 H2 섹션을 잘 잡는지 확인합니다.
- 모바일 화면에서 본문, 문서 트리, 검색창이 자연스럽게 접히는지 확인합니다.

## 후속으로 확장할 수 있는 글

이 뉴스가 중요하다고 판단되면 별도의 심층 문서로 확장할 수 있습니다. 예를 들어 `Kubernetes` 주제의 개념 정리, 실습 가이드, 운영 체크리스트, 관련 도구 비교 문서로 이어갈 수 있습니다. 장기적으로는 이런 뉴스성 문서가 쌓이고, 그중 일부가 책이나 지식베이스 챕터로 승격되는 흐름을 만들 수 있습니다.
