Scheduling - Admission Controller 심화(Custom Webhook)

2025. 12. 30. 00:50·CKA

앞 강의에서 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”를 자동으로 추가한 뒤 계속 진행

2) 호출 순서: 보통 Mutating → Validating

일반적으로 Kubernetes는 다음 흐름으로 처리합니다.

  1. Mutating Admission(요청 수정)
  2. Validating Admission(수정된 최종 요청을 검증)

이 순서가 중요한 이유:

  • Mutating이 “네임스페이스 자동 생성” 같은 작업을 먼저 해두면,
  • 이후 Validating이 “네임스페이스 존재 여부”를 검사할 때 통과할 수 있습니다.

반대로 순서가 바뀌면:

  • Validating이 먼저 “없다”고 거부해버려
  • Mutating이 실행될 기회가 없어집니다.

3) 내장 Admission만으로 부족하면? → Admission Webhook

강의의 핵심 결론:

쿠버네티스에 내장된 Admission Controller는 소스코드에 포함되어 같이 제공됩니다.
하지만 “내 조직 정책”처럼 커스텀 로직이 필요하면, 아래 두 플러그인을 통해 외부 서버(웹훅) 로 위임할 수 있습니다.

  • MutatingAdmissionWebhook
  • ValidatingAdmissionWebhook

동작 개념:

  1. 요청이 API Server에 도착
  2. 기본 내장 Admission들을 통과
  3. 설정된 Webhook이 있으면 API Server가 웹훅 서버를 호출
  4. 웹훅 서버는 AdmissionReview JSON을 받고
  5. allowed: true/false 또는 JSONPatch(변경)로 응답
  6. 그 결과에 따라 요청이 최종 허용/거부(또는 수정 후 허용)

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가지입니다.

  1. clientConfig: 웹훅 서버 위치
    • 외부면 url: https://...
    • 내부면 service: { namespace, name, path, port }
  2. caBundle/TLS
    • API Server ↔ Webhook 서버 통신은 TLS 기반이어야 합니다.
    • 웹훅 서버 인증서 + 이를 검증할 CA 번들을 설정합니다.
  3. 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이 보이는 이유가 바로 이 흐름입니다.

 

Access the lab here: https://learn.kodekloud.com/user/courses/udemy-labs-certified-kubernetes-administrator-with-practice-tests/module/8e4261a6-bac4-4dfe-82c5-0a1bb8c527da/lesson/1f3b6bb8-1b60-486a-b7da-08c8c33d8508

'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
'CKA' 카테고리의 다른 글
  • Monitoring - Metric Server
  • Scheduling - 총 정리
  • Scheduling - Admission Controller
  • Scheduling- Scheduler Profiles
5jyan5
5jyan5
  • 5jyan5
    jyan
    5jyan5
  • 전체
    오늘
    어제
    • 분류 전체보기 (243)
      • 김영한의 스프링 핵심 원리(기본편) (8)
      • 김영한의 스프링 핵심 원리 - 고급편 (11)
      • 김영한의 스프링 MVC 1편 (1)
      • 김영한의 스프링 DB 1편 (3)
      • 김영한의 스프링 MVC 2편 (3)
      • 김영한의 ORM 표준 JPA 프로그래밍(기본편) (9)
      • 김영한의 스프링 부트와 JPA 활용2 (2)
      • 김영한의 실전 자바 - 중급 1편 (1)
      • 김영한의 실전 자바 - 고급 1편 (9)
      • 김영한의 실전 자바 - 고급 2편 (9)
      • Readable Code: 읽기 좋은 코드를 작성.. (2)
      • 김영한의 실전 자바 - 고급 3편 (9)
      • CKA (119)
      • 개발 (37)
      • 경제 (4)
      • 리뷰 (1)
      • 정보 (2)
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

      빈 후처리기
      Target
      단방향 맵핑
      @args
      Thread
      자바
      스레드
      조회 성능 최적화
      프록시
      JPQL
      김영한
      고급
      양방향 맵핑
      버퍼
      typequery
      hibernate5module
      reentarantlock
      gesingleresult
      페치 조인
      jpq
      락
      log trace
      WAS
      @discriminatorcolumn
      프록시 팩토리
      cglib
      @discriminatorvalue
      jdk 동적 프록시
      @within
      requset scope
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.2
    5jyan5
    Scheduling - Admission Controller 심화(Custom Webhook)
    상단으로

    티스토리툴바