본 문서의 2.1(Mutating Admission Policy GA)과 3.9(갈래 B)를 실제 EKS 1.36에서 검증한 기록입니다. 예시 ①의 컨트롤러가 런타임 자동 resize를 담당한다면, MAP는 그 전제조건인
resizePolicy를 생성 시점에 webhook 없이 자동 주입합니다. 아래 매니페스트로 그대로 재현 가능합니다.
resizePolicy 를 MutatingAdmissionPolicy(GA)로 생성 시점에 자동 주입 — webhook 서버 제거.
resizePolicy 가 있어야 하고, 갈래 A에선 작성자가 직접 써야 했습니다.resize.example.com/enabled=true 인 Pod 에 resizePolicy 를 CEL JSONPatch 로 자동 주입 → 작성자는 annotation만 달면 됩니다. webhook 서버·인증서·HA 운영 부담이 사라집니다.Pod CREATE 요청
→ MAP matchConstraints: pods/CREATE 대상
→ matchConditions: resize.example.com/enabled == "true" 일 때만
→ mutations(JSONPatch, CEL): 각 컨테이너에 resizePolicy add
→ API Server 내부 처리 (webhook 네트워크 왕복 제거)
→ 주입된 spec 으로 Pod 생성
왜 JSONPatch 인가:
resizePolicy는 스키마상 atomic 리스트라 ApplyConfiguration(구조적 SSA 병합)으로는 바꿀 수 없습니다(may not mutate atomic arrays). 이 경우 JSONPatch patchType 을 씁니다.
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingAdmissionPolicy
metadata: { name: inject-resizepolicy }
spec:
failurePolicy: Fail
reinvocationPolicy: Never
matchConstraints:
resourceRules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE"]
resources: ["pods"]
matchConditions:
- name: only-resize-enabled
expression: >-
has(object.metadata.annotations) &&
("resize.example.com/enabled" in object.metadata.annotations) &&
object.metadata.annotations["resize.example.com/enabled"] == "true"
mutations:
# resizePolicy 는 atomic 리스트 → JSONPatch 로 add (indexOf 로 다중 컨테이너 일반화)
- patchType: JSONPatch
jsonPatch:
expression: >-
object.spec.containers.map(c, JSONPatch{
op: "add",
path: "/spec/containers/" + string(object.spec.containers.indexOf(c)) + "/resizePolicy",
value: [
{"resourceName": "cpu", "restartPolicy": "NotRequired"},
{"resourceName": "memory", "restartPolicy": "RestartContainer"}
]
})
---
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingAdmissionPolicyBinding
metadata: { name: inject-resizepolicy-binding }
spec:
policyName: inject-resizepolicy
matchResources:
namespaceSelector:
matchLabels: { map-demo: "true" } # ← 이 라벨 네임스페이스에만 적용 (전역 차단)
⚠️ 안전 — 반드시 범위 제한: MAP
matchConstraints는 기본 클러스터 전역입니다. Binding 의matchResources.namespaceSelector로 대상 네임스페이스를 한정하지 않으면 클러스터 모든 Pod 생성에 개입합니다.failurePolicy: Fail은 범위를 좁힌 뒤에만 안전합니다.
# 양성: annotation 有, resizePolicy 無 → MAP 가 주입
apiVersion: v1
kind: Pod
metadata:
name: with-annotation
namespace: map-demo
annotations: { resize.example.com/enabled: "true" }
spec:
containers:
- name: app
image: public.ecr.aws/docker/library/busybox:1.36
command: ["sh","-c","sleep 3600"]
resources:
requests: { cpu: 100m, memory: 32Mi } # req==limit → Guaranteed
limits: { cpu: 100m, memory: 32Mi }
# 음성(대조군): annotation 無 → 주입 안 됨 (동일 spec, annotation만 제거)
환경: EKS 1.36.1 노드, MutatingAdmissionPolicy 가 admissionregistration.k8s.io/v1(GA)로 서빙.