본문 바로가기
일반IT

[Kubernetes] 클러스터의 문지기, 웹훅(Webhook)과 어드미션 웹훅(Admission Webhook) 완벽 정복하기 🛡️

by gasbugs 2025. 8. 8.

안녕하세요! 쿠버네티스를 사용하다 보면 kubectl apply 명령어로 리소스를 생성하는 것이 얼마나 편리한지 느끼게 됩니다. 하지만 이런 편리함 속에서 문득 이런 생각이 들 때가 있죠.

  • "모든 파드(Pod)에 특정 레이블을 자동으로 붙일 순 없을까? 🤔"
  • "보안을 위해 latest 태그를 사용하는 이미지는 배포를 막고 싶은데..."
  • "모든 디플로이먼트(Deployment)에 리소스 제한(resource limits)을 강제할 순 없을까?"

이런 고민들을 해결해 주는 강력한 기능이 바로 쿠버네티스 웹훅(Webhook), 특히 어드미션 웹훅(Admission Webhook)입니다. 오늘은 클러스터의 정책과 보안을 책임지는 든든한 문지기, 웹훅에 대해 쉽고 상세하게 알아보겠습니다!

 

웹훅(Webhook)이란 무엇일까요? 🚪🔔

쿠버네티스 웹훅을 알아보기 전에, '웹훅'이라는 개념부터 가볍게 짚고 넘어갈게요.

웹훅은 어떤 이벤트가 발생했을 때, 지정된 URL로 HTTP 요청을 보내는 자동화된 메커니즘입니다. "역방향 API(Reverse API)"라고도 불리죠. 일반적인 API는 클라이언트가 서버를 호출하지만, 웹훅은 서버(이벤트 발생 시스템)가 클라이언트(알림을 받을 시스템)를 호출합니다.

가장 쉬운 예시는 GitHub 웹훅입니다.

  1. 이벤트 발생: GitHub 저장소에 새로운 코드가 push 됩니다.
  2. 웹훅 호출: GitHub가 미리 설정된 Jenkins나 CircleCI 같은 CI/CD 도구의 URL로 "새로운 코드 왔어!"라는 정보를 담아 HTTP POST 요청을 보냅니다.
  3. 자동화된 작업 수행: 알림을 받은 CI/CD 도구는 자동으로 빌드, 테스트, 배포 작업을 시작합니다.

이처럼 웹훅은 시스템 간의 이벤트를 실시간으로 연결해 주는 강력한 접착제 역할을 합니다.

 


쿠버네티스의 심장부와 소통하는 방법, 어드미션 웹훅 (Admission Webhook) 🏛️

쿠버네티스에서 웹훅은 다양한 방식으로 활용될 수 있지만, 오늘 우리가 집중할 것은 바로 어드미션 웹훅입니다.

어드미션 웹훅은 쿠버네티스 클러스터에 어떤 리소스(Pod, Deployment, Service 등)가 생성, 수정, 삭제되기 직전에 API 서버의 요청을 가로채서 추가적인 검증이나 변경을 수행할 수 있게 해주는 HTTP 콜백입니다.

쉽게 말해, 클러스터로 들어오는 모든 요청을 검문하는 "입학 사정관" 또는 "커스텀 검문소"라고 생각할 수 있습니다.

 

Back to Basics: Kubernetes Admission Webhooks ❘ by Mina Omobonike ❘ Geek Culture ❘ Medium

 

왜 어드미션 웹훅이 필요한가요? ✨

쿠버네티스는 이미 Role-Based Access Control (RBAC)을 통해 사용자가 특정 작업을 수행할 수 있는지 '권한'을 제어합니다. 하지만 RBAC만으로는 다음과 같은 '정책'을 강제하기 어렵습니다.

  • 보안 강화: 컨테이너가 root 권한으로 실행되는 것을 방지, 특정 이미지 레지스트리만 허용.
  • 운영 일관성: 모든 리소스에 생성자, 팀 이름 등의 표준 레이블(label)을 강제로 추가.
  • 리소스 관리: 모든 파드에 CPU와 메모리 요청/제한(requests/limits) 설정을 의무화.
  • 설정 자동화: Istio나 Linkerd 같은 서비스 메시는 어드미션 웹훅을 사용해 애플리케이션 파드에 자동으로 사이드카 프록시 컨테이너를 주입합니다. 개발자는 사이드카를 신경 쓸 필요가 없죠!

이처럼 어드미션 웹훅은 쿠버네티스의 기본 기능을 확장하여 우리 조직만의 맞춤형 정책과 자동화를 구현하는 핵심 도구입니다.

 

어드미션 웹훅의 작동 원리 (Admission Control Flow)

사용자가 kubectl apply를 실행하면 어떤 일이 일어날까요? 어드미션 웹훅은 이 과정의 핵심적인 단계에 관여합니다.

이미지 출처: 쿠버네티스 공식 문서

  1. 요청 (Request): 사용자가 kubectl 등으로 API 서버에 YAML 파일을 보내 리소스 생성을 요청합니다.
  2. 인증 & 인가 (Authentication & Authorization): API 서버는 요청을 보낸 사용자가 누구인지(인증), 그리고 이 작업을 수행할 권한이 있는지(인가, RBAC) 확인합니다.
  3. 변형 어드미션 웹훅 (Mutating Admission Webhooks) 🧬: 첫 번째 검문소입니다. 등록된 변형 웹훅들이 순서대로 호출됩니다. 이 웹훅들은 API 서버로 전달된 오브젝트의 내용을 수정할 수 있습니다. 예를 들어, 레이블을 추가하거나 사이드카 컨테이너를 주입하는 등의 작업을 수행합니다.
  4. 스키마 검증 (Object Schema Validation): (만약 수정되었다면) 수정된 오브젝트가 쿠버네티스의 기본 규칙(스키마)에 맞는지 검증합니다.
  5. 검증 어드미션 웹훅 (Validating Admission Webhooks) ✅/❌: 두 번째 검문소입니다. 등록된 검증 웹훅들이 순서대로 호출됩니다. 이 웹훅들은 오브젝트를 수정할 수는 없으며, 오직 요청을 승인(Allow)할지 거부(Deny)할지만 결정할 수 있습니다. 예를 들어, latest 태그 사용 여부나 리소스 제한 설정 여부를 검사하여 정책에 맞지 않으면 요청을 거부합니다.
  6. etcd에 저장: 모든 검문소를 무사히 통과한 오브젝트는 쿠버네티스의 데이터베이스인 etcd에 저장되고, 비로소 클러스터에 리소스가 생성됩니다.

 

만약 어느 단계에서든 실패하면, 사용자에게 에러 메시지가 반환되고 리소스는 생성되지 않습니다.


두 종류의 어드미션 웹훅: Mutating vs. Validating

어드미션 웹훅은 그 역할에 따라 두 가지로 나뉩니다.

1. MutatingAdmissionWebhook 🧬 (변형 웹훅)

이름 그대로, API 오브젝트를 변형(Mutate)하거나 수정하는 역할을 합니다.

  • 주요 기능: 요청받은 리소스 명세에 필드를 추가, 수정, 삭제합니다.
  • 작동 방식: 웹훅 서버는 API 서버로부터 AdmissionReview 요청을 받고, 오브젝트를 어떻게 수정할지에 대한 정보를 담은 JSON Patch를 AdmissionReview 응답에 담아 반환합니다.
  • 대표적인 예시:
    • Istio 사이드카 인젝터: 파드 명세에 Istio 프록시 컨테이너(istio-proxy)를 자동으로 추가합니다.
    • 기본 레이블 주입기: 모든 파드에 created-by: admission-webhook과 같은 공통 레이블을 자동으로 붙여줍니다.

2. ValidatingAdmissionWebhook ✅ (검증 웹훅)

API 오브젝트가 조직의 정책을 준수하는지 검증(Validate)하는 역할을 합니다.

  • 주요 기능: 리소스 명세를 검사하여 정책 위반 시 요청을 거부합니다. 절대 리소스를 수정할 수 없습니다.
  • 작동 방식: 웹훅 서버는 AdmissionReview 요청을 받고, 검사 결과(allowed: true 또는 allowed: false)와 거부 사유(status)를 응답으로 보냅니다.
  • 대표적인 예시:
    • OPA Gatekeeper, Kyverno: 코드를 통해 복잡한 정책을 정의하고 강제하는 CNCF 프로젝트들입니다. (예: "모든 Ingress 호스트네임은 *.mycompany.com 형태여야 한다.")
    • 리소스 제한 검사기: 파드 명세에 resources.limits 필드가 없으면 배포를 거부합니다.

직접 어드미션 웹훅을 만들어보자! (구성 요소) 🛠️

그렇다면 이 멋진 기능을 어떻게 구현할 수 있을까요? 어드미션 웹훅은 두 가지 주요 구성 요소로 이루어집니다.

 

1. 웹훅 서버 (Webhook Server)

실제로 로직을 처리하는 애플리케이션입니다.

  • 역할: API 서버로부터 AdmissionReview HTTP POST 요청을 받아서 처리하고, AdmissionReview 응답을 반환하는 로직을 담고 있습니다.
  • 구현: Go, Python, Node.js 등 HTTP 서버를 만들 수 있는 어떤 언어로도 작성할 수 있습니다.
  • 배포: 보통 쿠버네티스 클러스터 내부에 Deployment와 Service로 배포됩니다.
  • 중요! TLS 보안: API 서버와 웹훅 서버 간의 통신은 매우 민감하므로 반드시 HTTPS(TLS)로 암호화되어야 합니다. 이를 위해 웹훅 서버는 TLS 인증서를 가지고 있어야 합니다. (쿠버네티스 내에서는 cert-manager 같은 도구를 사용하면 편리합니다.)

 

2. 웹훅 설정 (Webhook Configuration)

API 서버에게 "이런 요청이 오면, 저기 있는 웹훅 서버에게 물어봐!"라고 알려주는 쿠버네티스 리소스입니다.

  • 리소스 종류:
    • MutatingWebhookConfiguration
    • ValidatingWebhookConfiguration
  • 주요 필드:
    • webhooks: 하나 이상의 웹훅 규칙을 정의합니다.
    • rules: 어떤 리소스(예: pods, deployments)의 어떤 작업(예: CREATE, UPDATE)을 가로챌지 정의합니다.
    • clientConfig: API 서버가 웹훅 서버를 어떻게 찾을지(보통 Service 이름과 경로)와 CA 인증서 정보를 담습니다.
    • failurePolicy: 웹훅 서버와 통신에 실패했을 때 요청을 무시(Ignore)할지, 실패(Fail)시킬지 결정합니다. 매우 중요한 설정입니다! Fail로 설정했는데 웹훅 서버가 다운되면 해당 리소스는 아무도 생성/수정할 수 없게 됩니다.
    • sideEffects: 웹훅이 리소스 외부에 영향을 미치는지 여부를 나타냅니다. (None 권장)

설정 예시 (ValidatingWebhookConfiguration)

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  name: "pod-policy.example.com"
webhooks:
- name: "pod-policy.example.com"
  rules:
  - apiGroups:   [""]
    apiVersions: ["v1"]
    operations:  ["CREATE", "UPDATE"]
    resources:   ["pods"]
    scope:       "Namespaced"
  clientConfig:
    service:
      name:      "pod-policy-webhook-svc" # 웹훅 서버를 가리키는 서비스
      namespace: "webhook-demo"
      path:      "/validate"
    caBundle: "Ci0tLS0t...<CA 인증서 Base64 인코딩 값>...tLS0K"
  admissionReviewVersions: ["v1"]
  sideEffects: None
  failurePolicy: Fail # 웹훅 서버 문제 시, 파드 생성/수정 실패 처리

마치며: 강력한 만큼 신중하게! 🚀

어드미션 웹훅은 쿠버네티스를 단순한 컨테이너 오케스트레이션 도구를 넘어, 조직의 정책과 거버넌스를 자동화하는 플랫폼 플랫폼(Platform for Platforms)으로 만들어주는 강력한 기능입니다.

 

보안 정책 강제, 멀티테넌시 환경 구성, 운영 자동화 등 그 가능성은 무궁무진합니다.

 

하지만 "큰 힘에는 큰 책임이 따른다"는 말을 기억해야 합니다. ⚠️ 잘못 설정된 웹훅 하나가 클러스터 전체의 안정성을 해칠 수 있습니다. 특히 failurePolicy: Fail 설정은 웹훅 서버의 가용성이 매우 중요해지므로, 신중한 설계와 충분한 테스트가 반드시 필요합니다.

 

이제 여러분도 어드미션 웹훅이라는 강력한 무기를 장착했으니, 더 안전하고 효율적인 쿠버네티스 클러스터를 만들어보세요!