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

사례3건

3건 중 1~3번째

  1. 증상

    2026년 9월 29일 10시 03분 UTC 부터 15시 58분 UTC 까지 Sweden Central 리전의 Azure OpenAI Service, Foundry Agent Service, Foundry Models, Azure AI services 에서 요청이 간헐적으로 실패했다. 고객은 이 리전에 올라간 모델과 데이터 플레인 API 에 요청을 보낼 때 지연 증가, HTTP 500 오류, HTTP 503 오류를 겪었다.

    촉발

    09시 38분 UTC 에 Sweden Central 에서 내부 서비스 하나의 계획된 배포가 시작됐다. 이 배포가 그 서비스의 캐시를 비웠고, 배포 시점이 리전의 트래픽 정점과 겹쳤다.

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

    10시 17분 UTC 서비스 모니터링이 리전의 Azure OpenAI Service 요청 실패율 상승을 감지해 엔지니어링 팀에 경보를 보냈다. 고객 영향이 시작되고 14분 뒤였다. 10시 28분 엔지니어가 투입돼 조사를 시작했다.

    조치
    • 15시 40분 UTC 백엔드 서비스의 자동 헬스 체크가 원격 연결에 의존하지 않도록 구성을 바꿔 재시작 루프를 멈췄다.
    후속 조치
    • 백엔드 서비스의 자동 헬스 체크가 데이터베이스 계층 연결에 의존하지 않도록 바꿔, 의존 서비스에 문제가 생겨도 인스턴스가 불필요하게 재시작되지 않게 했다.
    • 백엔드 서비스가 쓰는 캐시 계층의 부하와 지연에 모니터링과 경보를 더했다.
    • 이런 연결 고갈 상황에 맞춰 문제 해결 가이드와 절차를 고쳐 온콜 엔지니어가 비슷한 상황을 수습할 수 있게 했다.
    • 트래픽이 갑자기 늘어도 백엔드 서비스가 버티도록 스로틀링과 요청 속도 제한을 더한다. 완료 목표는 2026년 10월이다.
    • 여러 리전에서 백엔드 서비스가 쓰는 캐시 계층의 용량을 늘린다. 완료 목표는 2026년 10월이다.
    • 진단 지표와 자동 탐지를 개선해 이런 문제를 더 빨리 찾게 한다. 완료 목표는 2026년 10월이다.
    • 장기적으로 백엔드 서비스가 쓰는 캐시 계층을 파티션으로 나눠 처리량을 높인다. 완료 목표는 2026년 12월이다.
    교훈

    헬스 체크가 원격 의존성 연결에 기대면, 의존성 쪽 문제가 인스턴스를 계속 재시작시키는 루프로 번진다. 이번 장애는 트래픽 급증 자체보다 이 재시작 루프 때문에 6시간 가까이 이어졌다. 캐시를 비우는 배포를 트래픽 정점에 내보내면 캐시 미스가 뒤쪽 서비스로 한꺼번에 몰린다. 연결 고갈은 기존 네트워크 지표에 잘 드러나지 않았고, 그 사이 규모 조정과 자원 증설처럼 원인과 맞지 않는 조치에 시간을 썼다. Microsoft 는 고객에게 지수 백오프를 쓰는 재시도 패턴과 Microsoft Foundry 의 비즈니스 연속성 지침을 검토하라고 권했다.

  2. 증상

    Omio 는 6개월 동안 원인을 알 수 없는 멈춤을 겪었다. 애플리케이션이 멈추거나 헬스 체크에 응답하지 않았고, 네트워크 연결이 끊겼다.

    촉발

    쿠버네티스는 CPU limit 을 커널 CFS 의 쿼터로 구현한다. 주기는 100ms 이고, limit 2코어는 주기마다 CPU 시간 200ms 가 된다. 스레드 10개가 동시에 돌면 20ms 만에 쿼터를 다 쓰고, 남은 80ms 동안 파드의 모든 스레드가 멈춘다. 여기에 커널 CFS 스케줄러의 알려진 버그가 불필요한 스로틀링을 일으켜, 컨테이너가 허용된 쿼터를 다 쓰기도 전에 스로틀링됐다.

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

    팀은 6개월 동안 애플리케이션이 멈추거나 헬스 체크에 응답하지 않는 현상을 겪었지만, 쿠버네티스가 cgroup 지표를 내보내지 않아 스로틀링을 바로 알아채지 못했다. 파드 안에서 /sys/fs/cgroup/cpu/cpu.stat 의 nr_throttled 와 throttled_time 을 읽어 스로틀링 비율을 확인했다.

    조치
    • 버그를 고친 최신 커널이 모든 클러스터에 배포될 때까지 CPU limit 을 껐다.
    후속 조치
    • CFS 쿼터 버그를 고친 최신 커널을 모든 클러스터에 배포한다.
    • 사용률, 포화도, 오류를 보는 USE 지표와 함께 API 지연과 오류율을 지켜보며 결과가 기대한 대로인지 확인한다.
    교훈

    CFS 쿼터 버그가 고쳐지지 않은 커널을 쓴다면 쿠버네티스에서 CPU limit 을 없애거나 kubelet 에서 CFS 쿼터를 끄는 편이 낫다. CPU request 와 limit 은 설정이 비슷해 보여도 구현이 전혀 다르다. CPU 스로틀링은 쿠버네티스 기본 지표에 드러나지 않으므로 cpu.stat 을 직접 확인해야 한다. limit 을 끄면 최적화되지 않은 애플리케이션이 노드의 CPU 를 독차지할 수 있으니, JVM, Go, Node 런타임을 미리 튜닝해 둬야 한다.

  3. 증상

    2018년 12월 4일 아침 8시 회의 중 운영자가 NRE Labs의 일일 통계를 보다가 레슨 사용량이 떨어진 것을 알아챘다.

    촉발

    kubeadm이 etcd 정적 파드 매니페스트에 넣은 liveness probe가 실패하기 시작했다. 이 probe는 etcdctl로 foo 키를 조회한다. failureThreshold가 8, timeoutSeconds가 15라서 약 2분 동안 실패가 이어지면 kubelet이 etcd를 재시작한다. probe가 왜 실패하기 시작했는지는 끝내 밝히지 못했다.

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

    운영자가 아침 회의 중 NRE Labs 일일 통계를 보다가 레슨 사용량이 떨어진 것을 보고 알았다. 클러스터 모니터링은 갖추지 않은 상태였고, 원문은 모니터링이 우선순위에서 밀려 있었다고 적었다.

    조치
    • kubeadm이 만든 etcd 매니페스트에서 liveness probe 부분을 통째로 지우고, 다음 etcd 재시작 때 kubectl apply로 반영했다.
    후속 조치
    • 단일 마스터 클러스터에 모니터링을 갖춘다.
    • 장애가 나면 트위터를 보라고 안내하는 점검 페이지를 Google Cloud Functions에 만든다. 계획된 작업이든 아니든 일이 생기면 트래픽을 그 페이지로 돌린다.
    교훈

    모든 인프라를 코드로 관리한 덕에 클러스터를 금방 다시 만들 수 있었다. 하지만 원인을 모른 채 지우면 증거도 함께 사라진다. 단일 마스터로 운영한다면 모니터링이 더 중요하다. kubectl 출력에서 Running만 보지 말고 재시작 횟수까지 읽어야 한다. 복잡한 원인을 기대하기 전에 기본부터 의심하고, 장애의 급박함에 밀려 성급한 결정을 내리지 않는다. 사이트를 반쯤 망가진 채로 두지 말고 점검 페이지로 상황을 알려야 한다.

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

이 3건에서 가장 많이 나오는 구성 요소: kubelet, 인메모리 캐시. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.

원인별3