Published on

EKS에서 Webhook 타임아웃? Admission 진단법

Authors

서버사이드 적용(Apply)이나 Helm 배포가 갑자기 멈추고, context deadline exceeded 같은 메시지와 함께 리소스 생성이 실패한다면 높은 확률로 Admission Webhook 타임아웃입니다. EKS에선 ALB Controller, cert-manager, Istio, Gatekeeper/OPA, Kyverno, ExternalDNS(간접), 자체 정책 엔진 등 다양한 컴포넌트가 Webhook을 등록하기 때문에, 한 번 문제가 생기면 클러스터 전체의 생성/업데이트 경로가 막히는 형태로 증상이 나타납니다.

이 글은 “Webhook 타임아웃”을 네트워크/엔드포인트 문제, Webhook 서버 자체 문제, API 서버-Webhook 호출 체인 문제, DNS/노드/보안그룹 문제로 나눠서, EKS에서 빠르게 원인을 좁히는 실전 진단 흐름을 제공합니다.

> 참고로 네트워크 계층에서 유사하게 보이는 장애로 TLS handshake timeout도 자주 섞여 들어옵니다. Webhook이 아니라도 EKS 내 통신이 전반적으로 느리거나 끊긴다면 아래 글도 같이 확인하세요: EKS TLS handshake timeout 원인·해결 9가지

1) 증상 패턴: 에러 메시지로 “Webhook”인지 먼저 확정

대표적인 에러는 대개 아래 중 하나로 나타납니다.

  • Internal error occurred: failed calling webhook "...": Post "https://...": context deadline exceeded
  • no endpoints available for service "..."
  • x509: certificate signed by unknown authority (CA 번들/서버 인증서 문제)
  • dial tcp ... i/o timeout (네트워크/보안그룹/라우팅)

먼저 어떤 Webhook이 문제인지 정확한 이름을 뽑아야 합니다.

# 배포 실패 시 출력된 에러에서 webhook 이름을 확인
# 예: failed calling webhook "webhook.cert-manager.io"

# 클러스터에 등록된 webhook 목록 확인
kubectl get validatingwebhookconfigurations
kubectl get mutatingwebhookconfigurations

# 특정 webhook 상세 확인
kubectl describe validatingwebhookconfiguration webhook.cert-manager.io
kubectl describe mutatingwebhookconfiguration aws-load-balancer-webhook

여기서 확인할 핵심 필드:

  • clientConfig.service.name / namespace / path / port
  • failurePolicy: Fail | Ignore
  • timeoutSeconds (기본 10초인 경우가 많음)
  • namespaceSelector / objectSelector (특정 네임스페이스에만 적용되는지)

2) 가장 흔한 1순위: Webhook Service에 Endpoint가 없다

Webhook은 대개 Service 뒤에 Deployment/Pod가 있어야 하고, 그 Pod가 Ready여야 Endpoint가 생깁니다. Endpoint가 없으면 API 서버는 호출을 못 하거나(또는 연결 실패), 타임아웃으로 이어집니다.

# webhook이 가리키는 서비스 확인
kubectl -n cert-manager get svc
kubectl -n cert-manager get endpoints cert-manager-webhook

# 엔드포인트가 비어있다면 Pod 상태 확인
kubectl -n cert-manager get pods -o wide
kubectl -n cert-manager describe pod <webhook-pod>
kubectl -n cert-manager logs deploy/cert-manager-webhook --tail=200

체크 포인트:

  • Pod가 CrashLoopBackOff / ImagePullBackOff / Pending 인지
  • ReadinessProbe 실패로 Ready가 안 되는지
  • 노드에 배치가 안 되는지(리소스 부족, taint/toleration, 노드 셀렉터)

Pod가 Pending에서 멈춘다면 스케줄링 이슈가 원인일 수 있습니다. 이 경우 아래 글의 체크리스트가 그대로 도움이 됩니다: EKS Pod Pending 0/XX nodes available 원인별 해결

3) API 서버 → Webhook 네트워크 경로 이해하기 (EKS 특성)

EKS에서 Admission Webhook 호출은 기본적으로 **EKS Control Plane(관리형 API 서버)**에서 클러스터 내부 Service로 들어오는 흐름입니다.

  • Control Plane은 AWS가 관리하는 VPC ENI를 통해 클러스터 VPC로 들어와 kube-proxy/iptables 경로로 Pod까지 도달합니다.
  • 따라서 다음이 깨지면 Webhook 타임아웃이 납니다.
    • 노드 Security Group/NACL이 Control Plane 트래픽을 막음
    • CNI/라우팅 문제로 Pod CIDR 접근이 불가
    • kube-proxy 문제로 Service → Pod NAT가 깨짐
    • CoreDNS 문제로 Service DNS 해석이 느림/실패(간접)

특히 “갑자기” 타임아웃이 시작됐다면 최근 변경(노드 SG, NACL, VPC 라우팅, CNI 업데이트, kube-proxy/iptables, DNS 정책)을 의심하는 게 빠릅니다.

4) Webhook Pod는 살아있는데도 타임아웃: in-cluster에서 직접 때려보기

Webhook 서비스가 살아있어도, 실제로 HTTPS 핸드셰이크/응답이 느리거나 막히면 API 서버가 타임아웃 낼 수 있습니다.

4.1 디버그 Pod로 Service 연결 테스트

# 임시 디버그 파드 실행
kubectl run -it --rm netshoot \
  --image=nicolaka/netshoot \
  --restart=Never -- bash

# (파드 내부) DNS 확인
nslookup cert-manager-webhook.cert-manager.svc

# (파드 내부) TCP/HTTPS 연결
curl -vk https://cert-manager-webhook.cert-manager.svc:443/healthz

# 서비스 포트가 443이 아니면 맞게 변경
  • nslookup이 느리거나 실패하면 CoreDNS/네트워크/DNS 정책을 의심
  • curl -vk에서 연결 자체가 안 되면 보안그룹/네트워크 정책/서비스 라우팅 문제
  • TLS 단계에서 멈추면 인증서/서버 구성/MTU/네트워크 품질 문제

4.2 NetworkPolicy가 Webhook 트래픽을 막는지

Calico/Cilium 등을 사용 중이고 NetworkPolicy를 적용했다면, Webhook 네임스페이스에 ingress 허용이 없어서 막히는 경우가 많습니다.

kubectl get networkpolicy -A
kubectl -n cert-manager describe networkpolicy

주의: API 서버(컨트롤 플레인)에서 들어오는 트래픽을 “클러스터 내부 Pod”로만 가정하고 막아버리는 정책이 특히 위험합니다.

5) 인증서/CA 번들 문제: x509 에러 또는 간헐적 타임아웃

Webhook은 HTTPS로 호출되며, ValidatingWebhookConfiguration/MutatingWebhookConfiguration 안에 caBundle이 들어갑니다. cert-manager가 관리하는 Webhook은 보통 자동으로 갱신되지만, 다음 상황에서 꼬일 수 있습니다.

  • Webhook 서버 인증서가 갱신됐는데 caBundle이 갱신되지 않음
  • Helm 업그레이드/롤백으로 리소스가 꼬여서 CA 불일치
  • admissionregistration.k8s.io 리소스에 잘못된 caBundle이 남아있음
# webhook 설정에서 caBundle 확인
kubectl get validatingwebhookconfiguration webhook.cert-manager.io -o yaml | yq '.webhooks[].clientConfig.caBundle'

# cert-manager webhook 관련 secret 확인(컴포넌트에 따라 이름 상이)
kubectl -n cert-manager get secret | grep webhook

해결은 컴포넌트별로 다르지만, 보통은:

  • 해당 컨트롤러/웹훅 Deployment 재시작
  • Helm으로 설치한 경우 helm upgrade --install로 정상 상태 복구
  • 최후 수단으로 webhook configuration을 재적용(삭제 후 재생성)

6) timeoutSeconds와 failurePolicy: “막히는 정도”를 줄이는 응급 처치

장애 대응 중에는 우선 배포 파이프라인을 살려야 할 때가 있습니다. 이때 failurePolicyFail이면 Webhook이 죽는 순간 해당 리소스 생성이 전부 실패합니다.

  • 보안/정책 목적 Webhook(OPA/Gatekeeper 등)은 보통 Fail이 맞음
  • 가용성이 더 중요한 환경에선 일부 Webhook을 Ignore로 바꿔서 “일단 배포”를 살릴 수 있음

다만 이는 정책 우회가 될 수 있으니, 영향 범위를 명확히 하고 단기 조치로만 사용하세요.

# 예시: 특정 webhook의 failurePolicy/timeoutSeconds를 패치
kubectl patch validatingwebhookconfiguration my-webhook \
  --type='json' \
  -p='[
    {"op":"replace","path":"/webhooks/0/failurePolicy","value":"Ignore"},
    {"op":"replace","path":"/webhooks/0/timeoutSeconds","value":20}
  ]'

운영 관점 팁:

  • timeoutSeconds를 무작정 크게 하면 API 요청이 더 오래 걸려 apiserver 부하가 커질 수 있습니다.
  • 반복 타임아웃이면 근본 원인(엔드포인트/네트워크/웹훅 성능)을 먼저 고치는 게 정석입니다.

7) Webhook 서버 성능/리소스 문제: “응답은 하는데 느리다”

Webhook Pod가 살아있고 연결도 되는데 타임아웃이 난다면, Webhook 핸들러가 느린 경우가 많습니다.

  • CPU throttling(리소스 limit 과도)
  • 외부 API 호출(예: 정책 엔진이 외부 시스템 조회)
  • 큰 오브젝트 처리(대형 CRD, 대량 annotation)
  • 리더 선출/락 경합
# 리소스 상태 확인
kubectl -n <ns> top pod
kubectl -n <ns> describe pod <webhook-pod>

# HPA/리플리카 확인
kubectl -n <ns> get deploy <webhook-deploy> -o wide

가능한 개선:

  • Webhook Deployment replica 증가(단, leader-election 여부 확인)
  • CPU/memory requests/limits 재조정
  • PDB 설정으로 업그레이드 중 동시 중단 방지

8) “특정 네임스페이스만” 실패한다면 selector를 의심

Webhook은 종종 namespaceSelector로 특정 라벨이 있는 네임스페이스에만 적용됩니다. 이때 신규 네임스페이스에 라벨이 잘못 붙거나, 반대로 제외해야 할 네임스페이스가 포함되면 의도치 않게 Webhook을 타게 됩니다.

kubectl get validatingwebhookconfiguration <name> -o yaml | yq '.webhooks[].namespaceSelector'

kubectl get ns --show-labels

예:

  • istio-injection=enabled 라벨이 붙은 ns에서만 sidecar injection webhook이 동작
  • cert-manager.io/disable-validation=true 같은 예외 라벨이 필요한데 누락

9) EKS에서 자주 같이 터지는 원인: DNS/CoreDNS/IRSA 주변 이슈

Webhook 자체는 클러스터 내부 서비스지만, Webhook Pod가 내부적으로 AWS API를 호출하거나(예: IRSA 기반), 외부 DNS를 조회하거나, STS 토큰을 갱신하는 과정에서 지연이 생기면 결과적으로 Webhook 응답이 늦어질 수 있습니다.

  • IRSA/ST​S 호출이 실패/지연 → Webhook 처리 지연 → 타임아웃
  • CoreDNS 장애 → Webhook Pod가 외부/내부 이름 해석 실패 → 처리 지연

IRSA/네트워크 계층 점검이 필요하다면 이 글도 같이 보면 좋습니다: EKS TLS handshake timeout 해결 - IRSA·VPC·CoreDNS

10) 실전 진단 순서(체크리스트)

장애 대응 시, 아래 순서대로 보면 대부분 10~20분 내에 범위를 좁힐 수 있습니다.

  1. 에러에서 webhook 이름 확보 (failed calling webhook "...")
  2. 해당 *WebhookConfiguration에서 service/namespace/path/timeout/failurePolicy 확인
  3. endpoints가 비었는지 확인 (kubectl get endpoints -n <ns> <svc>)
  4. Webhook Pod 상태/로그 확인(크래시, readiness, pending)
  5. 디버그 Pod로 DNS + curl -vk로 서비스 직접 호출
  6. NetworkPolicy/SG/NACL/라우팅 변경 이력 확인
  7. 인증서/caBundle 불일치 여부 확인(x509 에러/갱신 타이밍)
  8. 리소스 병목(top/requests/limits)과 replica/HPA 확인
  9. (응급) failurePolicy: Ignore 또는 timeout 튜닝은 제한적으로

11) 예시: cert-manager webhook 타임아웃 케이스 재현/해결 흐름

아래는 현장에서 흔한 “엔드포인트 없음 → 타임아웃” 흐름입니다.

# 1) 실패 로그에서 webhook 확인
kubectl apply -f issuer.yaml
# Internal error occurred: failed calling webhook "webhook.cert-manager.io": ... context deadline exceeded

# 2) webhook이 가리키는 서비스 확인
kubectl describe validatingwebhookconfiguration webhook.cert-manager.io | sed -n '1,120p'

# 3) 엔드포인트 확인
kubectl -n cert-manager get endpoints cert-manager-webhook

# 4) 파드 확인 (예: ImagePullBackOff)
kubectl -n cert-manager get pods
kubectl -n cert-manager describe pod <cert-manager-webhook-pod>

# 5) 원인 해결 후 재시도
kubectl -n cert-manager rollout restart deploy/cert-manager-webhook
kubectl apply -f issuer.yaml

핵심은 “Webhook 문제”를 “Webhook 서버(파드/서비스/엔드포인트) 문제”로 환원시키는 것입니다. Admission은 결국 API 서버가 특정 HTTPS 엔드포인트를 호출하는 구조라서, 엔드포인트가 없거나, 연결이 안 되거나, 응답이 늦으면 동일한 형태의 장애가 반복됩니다.

마무리

EKS에서 Webhook 타임아웃은 단순히 어떤 컨트롤러 하나의 문제가 아니라, 클러스터 변경 경로 전체를 멈추게 하는 체인 장애로 번지기 쉽습니다. 그래서 “어떤 webhook이 막았는지”를 먼저 특정하고, endpoints → 네트워크 → TLS/CA → 성능 순으로 좁혀가는 게 가장 빠릅니다.

운영 환경이라면 추가로 권장합니다.

  • Webhook 관련 Deployment에 PDB/replica 설정
  • CoreDNS/네트워크 변경 시 사전 점검(특히 NetworkPolicy)
  • 주요 webhook에 대한 SLO(응답 시간) 모니터링과 알람

이 흐름대로 점검했는데도 원인이 애매하다면, 실제 에러 메시지(전체), 문제 Webhook 이름, 해당 서비스/엔드포인트 상태, Webhook Pod 로그 일부를 모아서 보면 다음 단계(보안그룹/컨트롤플레인 경로/MTU 등)까지 더 정확히 좁힐 수 있습니다.