앞 강의에서 Admission Controller는 RBAC(인가) 이후에 요청을 한 번 더 검사/수정해서 “클러스터 정책”을 강제하는 단계라고 봤습니다. 이번 강의는 그 Admission Controller를 유형별로 정리하고, Kubernetes에 내장된 것만으로 부족할 때 Webhook으로 커스텀 Admission을 붙이는 방법을 설명합니다.
1) Admission Controller 두 가지 유형
1) Validating Admission Controller (유효성 검사)
- 요청을 검사해서 허용/거부만 합니다.
- 예:
NamespaceExists/NamespaceLifecycle- 존재하지 않는 네임스페이스로 오면 거부
kube-system같은 기본 네임스페이스 삭제 방지(라이프사이클 정책)
2) Mutating Admission Controller (변경/변형)
- 요청을 수정(mutate) 해서 기본값을 주입하거나 필드를 추가합니다.
- 예:
DefaultStorageClass- PVC 생성 요청에서
storageClassName이 비어 있으면 - 클러스터의 “기본 StorageClass”를 자동으로 추가한 뒤 계속 진행
- PVC 생성 요청에서
2) 호출 순서: 보통 Mutating → Validating
일반적으로 Kubernetes는 다음 흐름으로 처리합니다.
- Mutating Admission(요청 수정)
- Validating Admission(수정된 최종 요청을 검증)
이 순서가 중요한 이유:
- Mutating이 “네임스페이스 자동 생성” 같은 작업을 먼저 해두면,
- 이후 Validating이 “네임스페이스 존재 여부”를 검사할 때 통과할 수 있습니다.
반대로 순서가 바뀌면:
- Validating이 먼저 “없다”고 거부해버려
- Mutating이 실행될 기회가 없어집니다.
3) 내장 Admission만으로 부족하면? → Admission Webhook
강의의 핵심 결론:
쿠버네티스에 내장된 Admission Controller는 소스코드에 포함되어 같이 제공됩니다.
하지만 “내 조직 정책”처럼 커스텀 로직이 필요하면, 아래 두 플러그인을 통해 외부 서버(웹훅) 로 위임할 수 있습니다.
- MutatingAdmissionWebhook
- ValidatingAdmissionWebhook
동작 개념:
- 요청이 API Server에 도착
- 기본 내장 Admission들을 통과
- 설정된 Webhook이 있으면 API Server가 웹훅 서버를 호출
- 웹훅 서버는
AdmissionReviewJSON을 받고 allowed: true/false또는 JSONPatch(변경)로 응답- 그 결과에 따라 요청이 최종 허용/거부(또는 수정 후 허용)
4) Webhook이 받는 데이터: AdmissionReview
API Server가 웹훅 서버로 보내는 AdmissionReview에는 대략 이런 정보가 들어 있습니다.
- 요청한 사용자(누가)
- 어떤 동작인지(create/update/delete 등)
- 어떤 리소스인지(pods/deployments 등)
- 실제 오브젝트 스펙(생성하려는 Pod YAML 내용 등)
웹훅 서버는 이를 보고 정책을 적용합니다.
5) Webhook 서버가 하는 두 가지 일
1) Validating Webhook (거부/허용)
예시 정책:
- “오브젝트 이름과 사용자 이름이 같으면 거부”
- “:latest 태그 쓰면 거부”
- “runAsNonRoot 없으면 거부”
응답 핵심은:
allowed: true→ 통과allowed: false→ 거부(+ message로 이유 전달)
2) Mutating Webhook (수정)
예시 정책:
- “요청한 사용자 이름을 라벨로 자동 주입”
- “필수 라벨/어노테이션 누락 시 자동 추가”
- “imagePullPolicy를 Always로 강제 주입”
Mutating은 보통 JSONPatch를 반환합니다(강의에서 add/remove/replace 등 언급).
시험 관점에서 중요한 포인트는:
- 코드를 직접 작성하라고 나오진 않지만,
- “Webhook이 요청을 수정할 수 있다”는 개념과
- “JSONPatch로 필드 경로를 지정해서 수정한다” 정도는 이해해두면 좋습니다.
6) 구성 단계(시험/실무 모두 중요한 흐름)
Webhook을 붙이려면 크게 2단계입니다.
Step 1) Webhook 서버 배포
- 클러스터 내부에 Deployment로 올릴 수도 있고
- 클러스터 외부(사내 서버 등)에 둘 수도 있습니다.
- 클러스터 내부라면 보통 Service로 노출합니다.
Step 2) Webhook Configuration 오브젝트 생성
- Validating이면
ValidatingWebhookConfiguration - Mutating이면
MutatingWebhookConfiguration apiVersion: admissionregistration.k8s.io/v1
구성에 들어가는 핵심 요소는 3가지입니다.
- clientConfig: 웹훅 서버 위치
- 외부면
url: https://... - 내부면
service: { namespace, name, path, port }
- 외부면
- caBundle/TLS
- API Server ↔ Webhook 서버 통신은 TLS 기반이어야 합니다.
- 웹훅 서버 인증서 + 이를 검증할 CA 번들을 설정합니다.
- rules: 언제 호출할지(트리거 조건)
- 어떤 리소스에 대해(pods 등)
- 어떤 동작에 대해(create/update/delete)
- 어떤 API group/version에 대해
예: “Pod 생성(Create pods)일 때만 Validating Webhook 호출” 같은 식으로 범위를 좁히는 게 일반적입니다.
예시 1) 클러스터 내부 Service로 연결하는 ValidatingWebhookConfiguration (Pod 생성만 검사)
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: validate-pods.example.com
webhooks:
- name: validate-pods.example.com
admissionReviewVersions: ["v1"]
sideEffects: None
failurePolicy: Fail
clientConfig:
service:
namespace: webhook-ns
name: webhook-service
path: /validate
port: 443
caBundle: <BASE64_ENCODED_CA_CERT>
rules:
- operations: ["CREATE"]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
예시 2) 클러스터 내부 Service로 연결하는 MutatingWebhookConfiguration (Pod 생성 시 라벨 주입 등)
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: mutate-pods.example.com
webhooks:
- name: mutate-pods.example.com
admissionReviewVersions: ["v1"]
sideEffects: None
failurePolicy: Fail
clientConfig:
service:
namespace: webhook-ns
name: webhook-service
path: /mutate
port: 443
caBundle: <BASE64_ENCODED_CA_CERT>
rules:
- operations: ["CREATE"]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
예시 3) 클러스터 외부 URL로 연결하는 ValidatingWebhookConfiguration
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: validate-pods-external.example.com
webhooks:
- name: validate-pods-external.example.com
admissionReviewVersions: ["v1"]
sideEffects: None
failurePolicy: Fail
clientConfig:
url: https://webhook.example.com/validate
caBundle: <BASE64_ENCODED_CA_CERT>
rules:
- operations: ["CREATE"]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
참고:
apiGroups: [""]는 Pod가 core API group(v1)에 속하기 때문에 빈 문자열을 씁니다.
7) “PVC에 DefaultStorageClass가 붙는다”를 이 관점으로 다시 보면
- PVC 요청이 들어왔는데
storageClassName이 없음 - Mutating Admission(내장 플러그인)이 기본 StorageClass를 자동 주입
- 최종 PVC를
kubectl get pvc -o yaml로 보면, 내가 안 적었는데도storageClassName이 보이는 이유가 바로 이 흐름입니다.
'CKA' 카테고리의 다른 글
| Monitoring - Metric Server (0) | 2025.12.30 |
|---|---|
| Scheduling - 총 정리 (0) | 2025.12.30 |
| Scheduling - Admission Controller (0) | 2025.12.30 |
| Scheduling- Scheduler Profiles (0) | 2025.12.30 |
| Scheduling - Multiple Schedulers(Custom Scheduler) (0) | 2025.12.29 |