Kubernetes에서 Mutating vs Validating Webhooks
Source: Dev.to
Admission Controller란 무엇인가?
Admission Controller는 Kubernetes API 서버에 대한 요청을 인증 및 인가가 끝난 후, 객체가 etcd에 영구 저장되기 전에 가로채는 코드입니다.
쉽게 말해, Kubernetes API의 미들웨어라고 할 수 있습니다.
다음 명령을 실행하면:
kubectl apply -f deployment.yaml
요청 흐름은 다음과 같습니다:
Request → Authentication → Authorization → Mutating Admission → Schema Validation → Validating Admission → etcd
Admission Controller는 이 파이프라인의 바로 중간에 위치합니다.
Admission Controllers의 두 가지 주요 유형
Mutating Admission Controllers
이들은 저장되기 전에 들어오는 요청을 수정할 수 있습니다.
일반적인 예시:
- 기본 라벨 추가
- 사이드카 컨테이너 주입 (예: Istio)
- 기본 리소스 제한 추가
- 누락된 필드 오버라이드
Mutating 컨트롤러는 먼저 실행됩니다. 원본 객체를 받아서 변경할 수 있습니다.
Validating Admission Controllers
이들은 요청을 수정할 수 없으며 다음만 결정합니다:
- 허용 ✅
- 거부 ❌
예시:
- 특권 컨테이너 차단
- 이미지 레지스트리 정책 적용
- 필수 라벨 검증
- 네이밍 표준 강제
Validating 컨트롤러는 변경 후에 실행되므로 객체의 최종 버전을 확인합니다. 이 순서는 중요합니다.
정적 vs. 동적 어드미션 컨트롤러
정적 (내장)
이들은 Kubernetes에 기본으로 포함되어 있으며 API‑server 플래그를 통해 활성화됩니다:
--enable-admission-plugins
일반적인 내장 플러그인:
NamespaceLifecycleLimitRangerResourceQuotaServiceAccount
예를 들어, NamespaceLifecycle은 종료 중인 네임스페이스에서 새로운 리소스를 생성하는 것을 방지합니다. 많은 사람들이 “핵심 Kubernetes 동작”이라고 생각하는 기능들은 실제로 이러한 내장 어드미션 컨트롤러를 사용해 구현됩니다.
동적 (Webhook‑기반)
이들은 훨씬 유연하며 다음을 포함합니다:
MutatingAdmissionWebhookValidatingAdmissionWebhook
API 서버에 로직을 직접 삽입하는 대신, Kubernetes는 외부 HTTPS 서비스(웹훅)를 호출하여 다음을 묻습니다:
- “이 요청이 괜찮은가요?”
- “무언가를 변경하고 싶나요?”
HTTPS를 제공할 수 있는 어떤 언어든(Go, Python, Node 등) 사용해 맞춤 로직을 구현할 수 있습니다. 여기서 강력함이 발휘됩니다.
왜 Admission Controllers가 중요한가
보안
Admission Controllers는 클러스터 전반에 보안 기준선을 적용할 수 있습니다.
예시:
- 루트 권한으로 실행되는 컨테이너 차단
- 신뢰할 수 있는 레지스트리에서만 이미지 허용
- 루트 파일시스템을 읽기 전용으로 강제
hostPath사용 방지
예를 들어, 다음과 같은 내용이 포함된 배포를 거부할 수 있습니다:
securityContext:
privileged: true
이것만으로도 심각한 보안 위험을 방지할 수 있습니다.
거버넌스 및 컴플라이언스
조직 표준을 적용하는 데에도 도움이 됩니다:
- 명명 규칙
- 필수 라벨
- 리소스 제한
- 레플리카 제한
예를 들어, 모든 배포에 다음이 포함되도록 강제할 수 있습니다:
labels:
environment: production
라벨이 없나요? 배포 불가. 간단하고 효과적입니다.
실제 예시: Ingress 컨트롤러
F5 NGINX Ingress Controller와 같은 인그레스 컨트롤러를 설치하면 다음과 같은 리소스를 생성한다는 것을 알 수 있다:
MutatingWebhookConfigurationValidatingWebhookConfiguration
왜일까? 쿠버네티스는 NGINX‑특정 설정 로직을 이해하지 못하기 때문이다.
웹훅은:
- 인그레스 어노테이션을 검증한다
- 잘못된 설정을 방지한다
- 깨진 NGINX 재로드를 차단한다
- 프로덕션 트래픽을 보호한다
이 레이어가 없으면 잘못된 Ingress 정의가 잘못된 NGINX 설정을 생성해 실시간 트래픽에 영향을 줄 수 있다. 웹훅은 여러분의 안전망이다.
변이와 검증이 함께 작동하는 방식
다음과 같이 Deployment를 만든다고 가정해 보세요:
replicas: 1
일어날 수 있는 일:
- mutating 웹훅이
replicas를3으로 변경합니다. - validating 웹훅이
replicas가5보다 크지 않은지 확인합니다.- 유효하면 → 객체가 etcd에 저장됩니다.
이러한 계층적 접근 방식은 다음을 보장합니다:
- 기본값이 적용됨
- 정책이 강제됨
- 잘못된 구성은 클러스터 상태에 도달하지 않음
Admission 컨트롤러 활성화
API 서버에서 다음과 같이 활성화합니다:
--enable-admission-plugins=MutatingAdmissionWebhook,ValidatingAdmissionWebhook
웹훅 지원을 확인하려면:
kubectl api-versions | grep admissionregistration.k8s.io
다음과 같이 표시되면:
admissionregistration.k8s.io/v1
바로 사용할 수 있습니다.
Writing Your Own Admission Controller
만약 직접 구현하고 싶다면, 전체 흐름은 다음과 같습니다:
- HTTPS 서비스 구축
AdmissionReview객체 수신- 응답 반환
allowed: true/false- 선택 사항: JSON 패치 (변형을 위한)
- 다음 중 하나를 사용해 등록
MutatingWebhookConfiguration또는ValidatingWebhookConfiguration
웹훅은 다음 조건을 만족해야 합니다:
- TLS 사용
- 클러스터 내부에서 접근 가능
- 구성에 CA 번들 포함
구성이 완료되면, 매칭되는 리소스가 생성, 업데이트 또는 삭제될 때마다 Kubernetes가 해당 서비스를 호출합니다.
최종 생각
Admission Controllers는 Kubernetes에서 가장 강력하면서도 — 종종 간과되는 — 기능 중 하나입니다.
API 서버 내부에 프로그래밍 가능한 제어 레이어를 제공합니다.
프로덕션 환경에서 Kubernetes를 운영하면서 Admission Controllers를 활용하지 않는다면, 개발자들이 “제대로 행동”하도록 전적으로 의존하게 되는 것입니다. 그리고 그 결과가 보통 어떻게 되는지는 우리 모두 알고 있습니다.
현명하게 사용하세요 — 클러스터가 훨씬 더 안전하고 예측 가능해집니다.
