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

사례7건

7건 중 4~7번째

  1. 증상

    롯데온 서비스에서 HPA 가 파드 수를 줄이는 스케일 인 때마다 일정 시간 동안 요청이 오류로 끝났다. 엔드포인트에서 파드 IP 가 빠지기 전에 컨테이너가 먼저 지워지면, 들어오는 트래픽이 여전히 지워진 컨테이너로 가서 502 에러가 났다.

    촉발

    두 가지 작업이 각각 장애를 일으켰다. 하나는 HPA 가 파드를 줄이는 스케일 인이고, 다른 하나는 Service 레이블 셀렉터를 그린 디플로이먼트로 바꾼 뒤 블루 파드를 지우는 블루/그린 배포다.

    원인
    구성 요소
    기여 요인
    조치
    • 컨테이너 종료를 늦춰 Service 엔드포인트에서 파드가 빠질 때까지 기다리게 했다. 방법은 애플리케이션의 SIGTERM 처리 로직에서 기다리게 하거나 preStop 훅에 sleep 을 넣는 것이다. 무한정 기다리지 않도록 terminationGracePeriodSeconds 도 함께 설정한다.
    • 대상 그룹 한도인 1000개를 넘지 않는 일부 워크로드에서 ingress 로 만드는 ALB 를 instance 모드에서 IP 모드로 바꿨다.
    후속 조치
    • ALB IP 모드를 전체 워크로드에 점진적으로 적용한다.
    교훈

    Kubernetes 에서 엔드포인트 제거와 컨테이너 종료는 동시에 진행되므로, 종료를 늦추지 않으면 스케일 인 때 지워진 컨테이너로 트래픽이 가서 502 가 날 수 있다. preStop 훅으로 기다릴 때는 terminationGracePeriodSeconds 로 최대 대기 시간을 함께 정해야 한다. ALB 를 instance 모드로 쓰면 트래픽이 노드의 iptables 와 conntrack 을 거치므로, 블루/그린 전환 뒤에도 established 연결이 지워진 파드로 갈 수 있다. IP 모드는 이 경로를 없애고 네트워크 홉도 줄이지만, 대상 그룹에 대상을 1000개까지만 넣을 수 있다.

  2. 증상

    2022년 6월 23일 18시 56분 PDT, UTC 로는 6월 24일 01시 56분에 여러 모델이 한꺼번에 오프라인이 됐다. 일부 파인튜닝 모델인 curie 와 davinci, 일부 Codex 베타 모델인 code-davinci-001 과 code-cushman-001, 일부 구형 GPT 모델인 curie, babbage, ada, 그리고 모든 Embeddings 모델이 응답하지 않았다.

    촉발

    사람의 실수로 운영 클러스터 하나에 파괴적인 작업이 실행돼 클러스터가 완전히 내려갔다. 안전장치에 예상하지 못한 구멍이 있었고, 그 작업이 어떤 영향을 주는지 알려 주는 정보가 미묘하게 빠져 있었다.

    원인
    구성 요소
    기여 요인
    조치
    • 내려간 클러스터가 맡던 모델을 남은 두 운영 클러스터에 다시 배치했다.
    • 클러스터 구성 중 AKS 연결이 끊기자 Azure 지원팀과 함께 VPN 링크를 다시 만들었다.
    • Azure Private Link 연결이 다시 끊기자 Azure 지원팀과 우회 방법을 만들었다.
    • 업그레이드한 쿠버네티스 버전이 인그레스와 호환되지 않자 클러스터를 지우고 처음부터 다시 만들었다.
    • 05시 30분부터 06시 30분 PDT 사이에 다시 만든 클러스터로 트래픽을 옮겼다.
    후속 조치
    • 이번 클러스터처럼 운영에 꼭 필요한 인프라가 실수로 바뀌지 않도록 검사와 잠금을 더한다. 기존 보호 장치는 범위가 좁아 이번 같은 클러스터 장애를 막지 못했다.
    • 실행 중인 작업이 더 잘 보이게 하고, 시스템 구성 요소의 이름이 글자만 봐도 서로 확실히 구별되도록 바꾼다.
    • AKS 네트워크 연결 문제를 Azure 와 계속 조사해 새 클러스터 작업이 다시 방해받지 않게 한다.
    • 이번에 드러난 클러스터 장애 유형을 플레이북에 넣고, 새 클러스터와 인프라를 구성하는 절차를 고친다.
    • 쿠버네티스를 체계적으로 업그레이드하고, 앞으로 버전이 뒤처지지 않도록 업그레이드할 시간을 따로 확보한다.
    • 파인튜닝 모델을 여러 클러스터에 나눠 배치하고, 클러스터 사이 복제를 더 자동으로 하는 방법을 만든다.
    • Azure Blob Storage 를 분산하고 복제해 파인튜닝 모델을 더 빠르고 안정적으로 불러올 수 있게 한다.
    • Azure Blob Storage 병목을 덜어 줄 노드 간 캐시의 배포를 마무리한다.
    • 모델 가중치를 저장하는 방식을 바꿔 더 효율적이고 빠르게 불러올 수 있게 한다.
    교훈

    클러스터 하나를 통째로 잃으면 평소의 여유 용량이 한 번에 바닥난다. GPU 처럼 몇 시간 안에 늘릴 수 없는 자원을 쓰는 서비스는 남은 클러스터만으로 완전히 되살릴 수 없다. 운영 클러스터를 지울 수 있는 작업에는 그 영향을 분명히 보여 주는 정보와 잠금이 있어야 한다. 쿠버네티스 버전이 뒤처져 있으면 급하게 하는 업그레이드가 인그레스 호환성 같은 새 문제를 만든다. AKS 는 다운그레이드가 되지 않아 되돌릴 수도 없었다. 대용량 모델을 처음부터 다시 올리는 상황에서는 스토리지 대역폭과 캐시 무효화가 복구 시간을 좌우했다.

  3. 증상

    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 스키마도 잘못된 매니페스트 적용을 막지 못했다. 팀은 대응 과정에서 장애 관리자를 정했다면 도움이 됐을 것으로 봤다. 그리고 워룸 회의를 녹화하고, 대응에 참여하지 않는 사람은 글로만 제안하고, 일지를 남기자고 정리했다. 대응 초반에 각자의 생각과 직감을 짧게 나누는 시간도 갖자고 했다.

  4. 증상

    고객에게 영향이 간 장애였다. IAM 서비스에서 404 오류가 나기 시작했다.

    촉발

    발표는 문제의 출발점으로 CronJob 매니페스트 하나를 보여 주었다. 이 매니페스트에는 concurrencyPolicy, successfulJobsHistoryLimit, failedJobsHistoryLimit 필드가 CronJob spec이 아니라 파드 템플릿 spec 안에 들어 있었다. 실행 일정은 평일 9시부터 19시까지 15분마다였다.

    원인
    구성 요소
    기여 요인
    조치
    • CronJob 매니페스트를 고쳤다. concurrencyPolicy와 이력 보존 개수 필드를 CronJob spec으로 옮기고, Job에 activeDeadlineSeconds: 120을 넣고, 실행 일정을 바꿨다.
    후속 조치
    • API 서버에 문제가 생겨도 인그레스가 healthy 상태를 유지하도록 고친다.
    • API 서버가 응답하지 않아도 인그레스가 마지막으로 받은 라우트 목록을 계속 쓰도록 고친다.
    • ResourceQuota로 파드 수 상한을 1500개로 둔다.
    교훈

    ALB는 등록된 호스트가 모두 unhealthy를 보고하면 모든 호스트로 트래픽을 보낸다. 인그레스는 API 서버에 문제가 생겨도 healthy 상태를 유지해야 하고, 마지막으로 받은 라우트 목록을 계속 써야 한다. 파드 수에는 ResourceQuota로 상한을 걸어 둔다.

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

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

원인별6

업그레이드로 깨진 호환성2건

  1. IL-0092 ingress-nginx 를 1.12.0 에서 1.14.3 으로 올리자 새 ModSecurity 와 OWASP Core Rule Set 이 정상 요청을 오탐으로 막아 HMPPS 사용자가 인증하지 못했다.
  2. IL-0117 인그레스 업그레이드가 네트워크 컨트롤 플레인 회귀를 일으켜 데이터 플레인이 잠깐 끊겼고, 한꺼번에 재시작한 서비스들이 백엔드 저장소에 과부하를 일으켜 OpenAI API 오류가 늘었다
    OpenAI2024

배포 결함1건

  1. IL-0188 EKS 롤링 업데이트 때 Kubernetes 는 새 파드가 Ready 가 되자마자 옛 파드를 지웠지만 ALB 는 새 파드를 아직 healthy 로 보지 않아, 배포마다 약 30초 동안 502 가 났다.

DNS·네트워크 장애1건

  1. IL-0178 EKS 에서 HPA 가 파드를 줄일 때 엔드포인트 제거보다 컨테이너 종료가 먼저 끝나 502 가 났고, 블루/그린 전환 뒤에는 conntrack 에 남은 연결이 삭제된 파드로 가서 클라이언트가 타임아웃을 받았다.

운영 실수1건

조직
  1. IL-0115 OpenAI 의 운영 AKS 클러스터 세 개 중 하나가 사람의 실수로 통째로 내려가 Codex, Embeddings, 구형 GPT 모델과 파인튜닝 모델이 최대 12시간 동안 제대로 응답하지 못했다
    OpenAI2022

소프트웨어 결함1건

조직
  1. IL-0106 잘못된 IngressRoute 매니페스트가 Traefik v2 버그를 건드려 Traefik 파드가 모두 재시작된 뒤 Kubernetes 의 모든 서비스가 404 를 냈다
    DFDS2021

용량 한계1건

조직
  1. IL-0031 API 서버가 OOMKill로 죽자 Skipper 인그레스가 라우트를 잃었고, 고객 트래픽이 끊기며 IAM 서비스에서 404 오류가 났다