Incident Library
  • 원인
  • 구성 요소
  • 증상
  • 기여 요인
  • 사례

사례7건

7건 중 1~5번째

  1. 증상

    운영 중 장애로 드러난 증상은 없다. 이 사례는 Wiz Research가 Ingress NGINX Controller의 어드미션 컨트롤러 코드를 검토하다 찾은 취약점들이고, 이 취약점들을 묶어 IngressNightmare라고 부른다. CVSS v3.1 기본 점수는 9.8이다.

    촉발

    인증 없는 어드미션 웹훅에 악성 Ingress 객체를 담은 AdmissionReview 요청을 보내면 공격이 시작된다. 어드미션 컨트롤러는 받은 Ingress 객체로 임시 NGINX 설정 파일을 만들고 nginx -t로 검사한다. 이때 어노테이션 값과 객체 UID가 제대로 걸러지지 않은 채 설정 파일에 들어갔다.

    원인
    구성 요소
    기여 요인
    감지

    Wiz Research가 어드미션 컨트롤러 코드를 검토하다 찾았다. 2024년 12월 31일 CVE-2025-1974와 CVE-2025-24514를 쿠버네티스에 보고했고, 2025년 1월 2일 CVE-2025-1097을, 1월 21일 CVE-2025-1098을 보고했다. 일반 공개는 2025년 3월 24일이었다.

    조치
    • 쿠버네티스가 2025년 2월 7일 CVE-2025-1098, CVE-2025-1097, CVE-2025-24514 주입 취약점을 고친 내부 패치를 만들었다.
    • 쿠버네티스가 어드미션 컨트롤러에서 NGINX 설정 검사를 빼 CVE-2025-1974를 막았고, 2025년 2월 20일 이를 Wiz에 알렸다.
    • 수정이 들어간 Ingress NGINX Controller 1.12.1과 1.11.5가 나왔다.
    교훈

    Ingress NGINX Controller를 최신 버전으로 올리고, 어드미션 웹훅 엔드포인트를 외부에 노출하지 않는다. 바로 올릴 수 없다면 네트워크 정책으로 쿠버네티스 API 서버만 어드미션 컨트롤러에 닿게 하거나 어드미션 컨트롤러를 잠시 끈다. Helm으로 설치했다면 controller.admissionWebhooks.enabled=false 로 다시 설치하고, 직접 설치했다면 ingress-nginx-admission ValidatingWebhookConfiguration을 지우고 컨트롤러의 --validating-webhook 인자를 뺀다. 업그레이드한 뒤에는 어드미션 컨트롤러를 다시 켠다. 어드미션 컨트롤러는 흔히 놓치는 공격 지점이다. 인증 없이 도는 웹 서버이면서 권한이 높고, 클러스터 안 어느 파드에서나 닿는다. 공격자가 컨테이너 탈출이나 SSRF로 파드 네트워크에 들어오는 일은 생각보다 쉽다. Wiz는 최소 권한 설계가 없어 공격이 클러스터 장악까지 이어졌다고 지적했다. 걸러지지 않은 사용자 입력을 nginx -t로 검사하는 것 자체도 위험하다고 봤다. 2025년 11월 갱신된 글에 따르면 ingress-nginx는 2026년 3월에 유지보수를 끝내고 지원을 종료한다. 그러니 Gateway API나 다른 인그레스 컨트롤러로 옮겨야 한다.

  2. 증상

    배포 도중 쿠버네티스로 들어오는 트래픽이 갈 곳을 잃기 시작했다. 일부 API 요청이 타임아웃됐다.

    촉발

    오래 걸리는 NGINX 전체 리로드가 진행되는 동안 배포 롤아웃으로 백엔드 엔드포인트가 바뀌었다. ingress-nginx 컨트롤러에는 enable-serial-reloads 옵션이 켜져 있었다.

    원인
    구성 요소
    기여 요인
    –
    조치
    • 문제를 풀어 보려고 NGINX Ingress 컨트롤러를 재시작했다.
    후속 조치
    • enable-serial-reloads 가 엔드포인트 동적 갱신을 막는 문제를 kubernetes/ingress-nginx 에 이슈로 올린다.
    교훈

    자원 소모를 막으려고 켠 무해해 보이는 플래그 하나가, 라우팅이 실제 배포 상태와 어긋나는 구간을 만들 수 있다. 엔드포인트 동적 갱신이 리로드에 묶이면 배포 중 트래픽이 사라진 파드로 간다.

  3. 증상

    2024년 8월 27일 14:20 UTC부터 15:16 UTC까지 일부 HubSpot 고객이 계정에 로그인하지 못했고 콘텐츠에 접근하거나 도구를 쓰지 못했다. 모니터링은 플랫폼 전반에서 성능이 크게 떨어진 것을 잡았다.

    촉발

    트래픽 관리 시스템의 핵심 구성 요소를 평소대로 운영하던 중 로드 밸런서 스택이 경로 처리 설정을 갱신했다. 외부 문서에는 알려져 있었지만 HubSpot 은 몰랐던 문제 때문에 이 갱신이 헬스 체크 응답을 잠시 막았다.

    원인
    구성 요소
    기여 요인
    감지

    HubSpot 은 14:20 UTC에 내부에서 문제를 확인했다. 14:23 UTC에는 모니터링 시스템이 플랫폼 전반의 성능 저하를 잡았고 장애 대응 팀이 소집됐다.

    조치
    • 14:59 UTC에 팀이 남은 로드 밸런서 인스턴스의 용량을 늘리는 작업에 들어갔다.
    • 15:04 UTC에 새 로드 밸런서 인스턴스가 올라와 시스템의 부하를 덜었고 트래픽이 안정되기 시작했다. 15:16 UTC에 시스템이 완전히 복구됐다.
    후속 조치
    • 헬스 체크가 잘못 타임아웃되지 않도록 설정을 고쳤다.
    • 설정 갱신 같은 작업 중에도 헬스 체크가 끊기지 않고 먼저 처리되도록 헬스 체크 시스템을 다시 설계한다.
    • 갑작스러운 트래픽 급증 때 더 많은 트래픽을 받을 수 있도록 로드 밸런서 용량을 늘렸다.
    • 트래픽 급증을 더 일찍 감지하고 실시간으로 부하를 나눠 특정 인스턴스 묶음에 부하가 몰리지 않도록 로드 밸런싱 구조를 고친다.
    • 대규모 장애 때 상태 페이지가 자동으로 갱신되도록 했다.
    • 상태 갱신이 더 빠르고 정확해지도록 모니터링 시스템을 소통 도구와 더 긴밀하게 연결한다.
    • 트래픽이 많은 상황을 재현하는 부하 테스트를 넓혀 약한 곳을 미리 찾는다.
    • 장애 상황을 일부러 만들어 플랫폼의 복원력을 정기적으로 시험하는 카오스 엔지니어링을 도입한다.
    • 최대 허용 연결 수 대비 현재 연결 수의 비율을 포함해 트래픽 흐름을 자세히 보는 새 지표를 넣었다.
    • 트래픽 흐름에 맞춰 자원 용량을 자동으로 조절하는 오토스케일링을 구현한다.
    교훈

    핵심 문제는 설정 갱신 중에 헬스 체크가 잠시 막혀 로드 밸런서 여러 대가 비정상으로 잘못 판정된 것이었다. 여러 인스턴스가 동시에 내려가자 남은 인스턴스에 부하가 몰려 연쇄 장애가 됐다. 넘치는 연결을 거부하는 보호 장치가 있었지만 트래픽 급증이 너무 빠르고 커서 감당하지 못했다. 모니터링은 장애를 빨리 잡았지만, HubSpot 은 비정상적인 트래픽 급증을 더 일찍 알아챘다면 연쇄 장애를 막을 수 있었다고 봤다. 상태 페이지 갱신이 늦어 고객에게 오래되거나 불완전한 정보가 갔다.

  4. 증상

    2021-09-06 08:00 UTC 에 Kubernetes 의 모든 서비스가 404 를 내기 시작했다. 30분 전인 07:30 에는 노드를 자동으로 교체하는 롤오버가 시작됐다.

    촉발

    2021-09-01 11:34 UTC 에 형식이 잘못된 IngressRoute 가 Kubernetes 에 적용됐다. 이 매니페스트는 2.5 미만 Traefik v2 의 버그를 건드렸지만, 버그는 Traefik v2 파드가 모두 재시작된 뒤에야 드러났다. 2021-09-06 07:30 에 자동 노드 롤오버가 시작됐고, 08:00 에 모든 서비스가 404 를 냈다.

    원인
    구성 요소
    기여 요인
    감지

    08:00 UTC 에 모든 서비스가 404 를 내기 시작했고 08:05 에 원인 조사를 시작했다. 감지까지 5분이 걸렸다.

    조치
    • ALB 헬스체크 경로를 바꿔 08:15 에 ALB 대상을 healthy 로 되돌렸지만 404 는 멈추지 않았다.
    • 08:50 에 주 인그레스 컨트롤러를 Traefik v1 으로 되돌리기로 하고, 09:00 에 손으로 롤백했다.
    • 09:10 에 잘못된 IngressRoute 를 손으로 지워 근본 원인과 Traefik v2 버그를 확인했다.
    • 09:20 에 바꾼 내용을 업스트림에도 반영했다.
    후속 조치
    • 버그가 고쳐진 Traefik v2.5 로 올리고 버그가 사라졌는지 확인한다.
    • Traefik v2 헬스체크 경로를 더 믿을 만한 경로로 바꾼다.
    • 인그레스 컨트롤러를 클러스터 바깥에서 확인하는 liveness 점검을 둔다.
    • 워크로드를 나눠 장애가 번지는 범위를 줄이는 방안을 검토한다.
    • Traefik v2 API 에서 짧은 시간에 많은 변경이 일어나는지 모니터링하는 방법을 알아본다.
    • 노드 롤오버 중과 롤오버 뒤에 스모크 테스트를 돌리는 방법을 알아본다.
    교훈

    Traefik v2 는 오류를 드러내지 않고 실패해서 조사를 ALB 쪽으로 잘못 이끌었다. 공식 API 스키마도 잘못된 매니페스트 적용을 막지 못했다. 팀은 대응 과정에서 장애 관리자를 정했다면 도움이 됐을 것으로 봤다. 그리고 워룸 회의를 녹화하고, 대응에 참여하지 않는 사람은 글로만 제안하고, 일지를 남기자고 정리했다. 대응 초반에 각자의 생각과 직감을 짧게 나누는 시간도 갖자고 했다.

  5. 증상

    Ravelin 이 API 계층을 기존 VM 에서 GKE 의 쿠버네티스 클러스터로 옮기고 Ingress 를 설정한 뒤, 통합 테스트가 가끔 502 오류를 받기 시작했다.

    촉발

    파드가 종료될 때 SIGTERM 을 받자 새 연결을 받지 않는 정상 종료를 시작했지만, GKE Ingress 는 엔드포인트 변경을 늦게 반영해 그 파드로 계속 새 트래픽을 보냈다.

    원인
    구성 요소
    기여 요인
    감지

    Ingress 를 설정한 뒤 통합 테스트가 가끔 502 오류를 받는 것을 보고 알았다.

    교훈

    쿠버네티스에서 엔드포인트 제거와 SIGTERM 은 동시에 일어나므로, SIGTERM 을 받았다고 바로 새 연결을 거부하면 안 된다. Ingress 는 특히 엔드포인트 변경을 늦게 반영한다. 파드는 종료 유예 시간이 끝날 때까지 계속 요청을 처리해야 하고, 유예 시간은 로드 밸런서에 변경이 반영되는 시간보다 길어야 한다.

내 클러스터에도 있는지 확인하기

이 7건에서 가장 많이 나오는 구성 요소: 인그레스 컨트롤러, 어드미션 웹훅. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.

원인별1

소프트웨어 결함7건

  1. IL-0053 Ingress NGINX Controller의 어드미션 웹훅이 인증 없이 열려 있어, 조작한 Ingress 객체로 NGINX 설정을 주입해 원격 코드를 실행하고 클러스터의 모든 Secret을 읽을 수 있었다
    Wiz2025
  2. IL-0081 ingress-nginx 의 enable-serial-reloads 옵션이 NGINX 리로드 중에 엔드포인트 동적 갱신을 막아, 배포 중 트래픽이 이미 없는 파드로 가면서 API 요청이 타임아웃됐다.
    Cresta2025
  3. IL-0495 쿠버네티스에서 도는 내부 로드 밸런서 일부가 헬스 체크 실패로 한꺼번에 내려가고 남은 인스턴스가 연결 폭증으로 무너졌다
  4. IL-0106 잘못된 IngressRoute 매니페스트가 Traefik v2 버그를 건드려 Traefik 파드가 모두 재시작된 뒤 Kubernetes 의 모든 서비스가 404 를 냈다
    DFDS2021
  5. IL-0062 GKE Ingress 뒤의 파드가 SIGTERM 을 받자마자 새 연결을 받지 않고 정상 종료해서 API 에 가끔 502 오류가 났다
  6. IL-0011 HAProxy 인그레스 템플릿이 백엔드 파드를 IP 순으로 정렬해 일부 파드에 요청이 몰리고 인그레스 컨테이너가 OOMKilled 됐다
  7. IL-0072 etcd 쓰기 지연으로 API 서버가 오래된 데이터를 읽어 클러스터 상태가 두 가지로 번갈아 보였고, 주 운영 클러스터 전체가 약 4시간 멈췄다