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

사례4건

4건 중 1~4번째

  1. 증상

    Oregon 리전에 배포한 일부 웹 서비스와 정적 사이트가 간헐적으로 404 응답을 냈다. 장애 동안 이 클러스터들에 새로 만든 서비스는 모두 404 를 받았다.

    촉발

    2025-11-05 에 코드에서 더는 참조하지 않는 기능 플래그를 시스템에서 정리했다. 이 플래그에 아직 기대던 메타데이터 서비스가 효율이 낮은 옛 데이터 전송 방식으로 돌아갔다.

    원인
    구성 요소
    기여 요인
    조치
    • 메타데이터 서비스가 쓸 수 있는 메모리를 늘렸다. 이 조치는 나중에 되돌렸다.
    • 라우팅 서비스와 메타데이터 서비스 사이에 효율적인 데이터 전송을 쓰도록 기능 플래그를 잠시 다시 켰다. 이 플래그는 나중에 지웠다.
    • 메타데이터 서비스가 더는 기능 플래그에 기대지 않도록 다시 배포했다.
    후속 조치
    • 메타데이터 서비스의 모니터링을 보강해 이번과 같은 방식의 장애가 나면 알림이 오게 했다.
    • 아직 서비스가 값을 읽고 있는 기능 플래그는 지울 수 없도록 기능 플래그 관리 관행을 고친다.
    • 메타데이터 서비스에서 상태를 한 번도 받아 오지 못한 라우팅 서비스 인스턴스에는 트래픽이 가지 않게 한다.
  2. 증상

    2022년 2월 22일 태평양 시간 오전 6시 직후 Slack 에 접속하지 못한다는 사용자 티켓과 내부 사용자의 문제 보고가 들어왔고, 여러 엔지니어링 팀에 호출과 알림이 거의 동시에 왔다. 많은 사용자가 Slack 에 접속하지 못했다. 클라이언트는 부팅 과정에서 채널 목록, 설정, 최근 대화를 서버에서 가져오는데, 부팅하지 못하면 Slack 은 오류 페이지를 보였다.

    촉발

    2월 22일 Consul 에이전트 업그레이드를 비율 단위로 롤아웃하는 단계에서 전체 에이전트의 25% 를 차례로 재시작했다. memcached 노드의 에이전트가 재시작될 때마다 캐시 제어 계층인 Mcrib 가 그 노드를 비어 있는 예비 노드로 바꾸거나 다시 들어온 노드를 비웠고, 하루 중 트래픽이 가장 많은 시간에 캐시 적중률이 떨어졌다.

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

    태평양 시간 오전 6시 직후 Slack 에 접속하지 못한다는 사용자 티켓, 내부 사용자의 문제 제기, 여러 엔지니어링 팀의 호출과 알림이 거의 동시에 들어왔다.

    조치
    • 대응 초기에 장애를 촉발한 Consul 에이전트 재시작 작업을 멈췄다. 그때는 재시작이 장애와 관련 있다고 의심하지 않았다.
    • 느린 부팅 요청이 데이터베이스 자원을 바닥내 이미 부팅한 사용자의 요청까지 막자 클라이언트 부팅 요청에 엄격한 속도 제한을 걸었다.
    • 처음 제한을 너무 많이 풀어 데이터베이스 부하와 실패한 요청이 다시 늘자 부팅 속도 제한을 다시 낮췄고, 그 뒤로는 작은 폭으로 올렸다.
    • 캐시 미스마다 모든 샤드를 읽던 쿼리를 memcached 에 없는 데이터만 Vitess 에서 읽도록 바꿨다.
    • 그룹 DM 데이터는 바뀌지 않아 조금 오래된 값을 써도 되므로 쿼리가 Vitess 프라이머리뿐 아니라 복제본에서도 읽도록 바꿨다.
    • 캐시가 다시 차고 적중률이 오르자 데이터베이스 처리량을 최대로 유지하면서 클라이언트 부팅 속도 제한을 천천히 정상 트래픽 수준까지 올렸다.
    후속 조치
    • Consul 롤아웃 절차를 바꿔 업그레이드 중에 같은 장애가 다시 촉발되지 않게 했다.
    • 캐시 노드에 짧은 네트워크 단절이 생겨도 같은 연쇄 장애가 나지 않도록 Mcrib 제어 루프의 해당 부분을 바꿔 배포한다.
    • 문제가 된 scatter query 를 채널 기준으로 샤딩한 테이블에서 읽도록 바꿨다.
    • 캐시 계층 뒤에 있는 다른 데이터베이스 쿼리를 분석해 비슷한 위험이 있는 대량 scatter query 가 있는지 찾는다.
    • 장기 프로젝트로 캐시 계층의 복원력을 높이는 다른 방법을 찾는다.
    교훈

    Slack 은 성능 병목, 연쇄 장애, 데워진 캐시에 기대는 구조, 촉발 요인이 된 변경이 장애에서 자주 보이는 패턴이라고 봤다. 이번 장애는 여러 시스템의 경계를 넘는 상호작용이었고 그중 일부 시스템은 최근에 바뀌었다. 큰 소프트웨어 시스템에서 복잡성과 변경은 피할 수 없고, 그만큼 시스템이 예측하지 못한 방식으로 움직일 위험도 커진다. Mcrib 는 틀리거나 비효율적이어서가 아니라 오히려 빠르고 효율적이어서 장애를 키웠다. 빠진 memcached 인스턴스를 더 빨리 찾아 설정을 고치면서 캐시 계층의 교체가 늘었고, 더 나은 구성 요소가 전체 시스템을 덜 안전하게 만들었다. 캐시 노드에 짧은 네트워크 단절이 생겨도 같은 연쇄 장애가 날 수 있다는 위험도 드러났다. 연쇄 장애에 빠진 시스템은 부하를 크게 줄이거나 용량을 늘리는 외부 개입 없이는 안정 상태로 돌아오지 않는다.

  3. 증상

    2020년 5월 12일 태평양 시간 오후 4시 45분 무렵, Slack 이 평소보다 많은 HTTP 503 오류를 내고 있다는 알림이 왔다. 사용자에게 보이는 장애가 이때 시작됐다.

    촉발

    미국 업무 시간이 끝나 트래픽이 줄자 webapp 계층이 축소되기 시작했다. 자동 확장은 오래된 인스턴스부터 종료하므로, HAProxy 상태에 남아 있던 오래된 webapp 서버만으로는 요청을 감당하지 못하게 됐다.

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

    평소보다 HTTP 503 오류가 많다는 알림으로 알아챘다. 이 상황을 직접 잡도록 만든 알림은 고장 나 있어 울리지 않았다.

    조치
    • HAProxy 서버 전체를 순차 재시작했다.
    후속 조치
    • 모든 인그레스 로드 밸런싱을 Envoy Proxy 로 옮기고, HAProxy 서버 상태를 바꾸던 파이프라인을 Envoy 가 xDS 컨트롤 플레인에서 엔드포인트를 받는 방식으로 바꾼다.
    교훈

    변화가 적은 시스템은 엔지니어가 모니터링과 알림을 들여다볼 일이 적어서, 알림이 고장 나도 오래 모른 채 지나간다. HAProxy 서버 상태를 바꾸는 복잡한 파이프라인에는 이번 장애가 드러낸 것 같은 운영상의 위험이 있다.

  4. 증상

    2020년 3월 16일 14:19 PDT 에 실시간 연결과 채팅 메시지를 처리하는 Elixir 서비스 대부분이 죽어 용량이 한순간에 사라졌고, 여기에 의존하는 다른 시스템으로 장애가 번졌다. 14:21 에 핵심 지표가 떨어졌다는 알림과 클러스터 사용률 이상 알림이 여럿 울렸고 SEV1 이 선언됐다. 대부분의 사용자가 Discord 에 접속하지 못했다.

    촉발

    2020년 3월 16일 14:18 PDT 에 Google Cloud 관리형 인스턴스 그룹 오토스케일러가 API 클러스터에 새 노드를 넣었고, 이 노드가 etcd 에 자신을 등록하는 도중 연결이 끊겨 값이 빈 키가 서비스 디스커버리에 쓰였다.

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

    14:21 PDT 에 핵심 지표가 떨어졌다는 알림과 클러스터 사용률 이상 알림이 여럿 울렸고, SEV1 이 선언됐다.

    조치
    • 잃은 실시간 용량을 다시 띄우고 장애가 난 노드를 고쳤다.
    • 서비스 복구를 돕기 위해 Discord 로 들어오는 접속을 조절하기 시작했다.
    • 모두가 다시 접속하는 동안 자원이 바닥나지 않도록 ScyllaDB 클러스터 두 곳의 데이터베이스 유지 작업인 anti-entropy repair 를 멈췄다.
    • 서비스가 회복되는 대로 접속 허용량을 계속 늘려 더 많은 사용자가 다시 접속하게 했다.
    후속 조치
    • 값이 잘못된 키가 쓰일 가능성을 줄이려고, etcd 클라이언트가 자신을 등록하는 요청을 TCP 패킷 두 개가 아니라 하나로 보내게 바꿨다.
    • 키 값이 깨진 서비스는 무시하도록 오류 처리를 더해, 같은 일이 다시 나도 그 서비스가 발견되지 않을 뿐 크래시 루프에 빠지지 않게 했다.
    • Go 프로젝트에 이 문제를 버그로 보고한다.
    교훈

    서비스 디스커버리 시스템은 etcd 안의 여러 장애에는 견디도록 만들었지만, 일시적인 네트워크 오류로 값 없는 키가 쓰일 수 있다는 것은 예상하지 못했다. 이 경우 Go 의 net/http 는 HTTP 1.1 규격을 어겨, Content-Length 헤더가 있고 본문이 불완전한 요청을 거부하지 않는다. 이 때문에 예상하지 못한 장애 상황이 하나 더 생겼다.

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

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

원인별3