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

사례7건

7건 중 1~5번째

  1. 증상

    가용 영역 장애 대비 훈련을 마친 뒤 정리 단계에서 런북대로 Kafka 브로커를 없애자, 운영 환경의 여러 토픽 파티션이 리더 없이 남았다. 망가진 파티션만 배정된 팀과 환경은 데이터 수집이 실패했다.

    촉발

    12월 5일 운영 환경에서 가용 영역 장애 훈련을 마친 뒤, 워크로드 균형을 되돌리는 정리 단계를 런북대로 진행하다 Kafka 브로커를 일부러 없앴다. 이때 동기화가 끝나 있던 기존 브로커까지 함께 없어졌다.

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

    대응자들은 알림이 쏟아지는 가운데 수집 서비스 Shepherd 의 크래시 루프를 한 시간 넘게 지나서야 알아챘다. 토요일 아침에는 대응자들이 Kafka 밸런싱 작업이 나아가지 않고 디스크 사용량이 줄지 않는 것을 봤다. 메타데이터 토픽을 고치자 SLO 처리 트리거가 약 18시간 늦은 데이터를 알렸다.

    조치
    • 망가진 파티션을 프로듀서 쪽에서 읽기 전용으로 돌려 수집 서비스의 크래시 루프를 멈췄다.
    • 파티션 재배치를 돌려 고객들의 수집을 정상으로 되돌렸다.
    • Kafka autobalancer 를 끄고, 균형을 일부 되찾는 수동 재배치 계획을 세워 밤새 돌렸다.
    • 자정 무렵 PT 에 브로커 디스크가 너무 빨리 차자 Kafka 의 로컬 보존 기간을 줄이고 긴 보존은 S3 tiered storage 에 맡기려 했다.
    • _confluent-tier-state 와 __consumer_offsets 토픽의 깨진 파티션을 고쳤다. 그러자 막혀 있던 SLO 처리 서비스가 늦은 데이터를 따라잡기 시작했다.
    • 토요일 아침 7시 PT 에 디스크 여유 공간이 5.07% 일 때 수집을 껐다. 디스크 사용량은 멈췄지만 줄지 않았다.
    • tiered storage 를 끄자 디스크 공간이 바로 돌아왔다. 2021년 예전 장애 때 통했던 방법이었다.
    • 수집을 다시 열었고, 이때 고객 영향이 끝났다.
    • 그날 늦게 완전히 망가진 Retriever 토픽 파티션을 손으로 고쳐 잘라 내고 읽기 전용으로 두었다. Retriever 가 offset 초기화를 감당하지 못해 오래된 데이터를 한동안 조회할 수 없었지만 데이터를 잃지는 않았다.
    • Activity Log 가 Kafka 로 이벤트를 보내지 못하게 되자 Honeycomb MySQL 읽기 전용 복제본의 binlog 보존 기간을 늘렸다.
    • offset 이 망가졌어도 Retriever 노드가 죽지 않고 대기 상태로 남아 오래된 데이터를 조회할 수 있게, 작은 수정 여러 개를 넣었다.
    • 금요일 정오 무렵 Storage 팀이 Retriever 의 offset 초기화 장치가 동작하게 만들었다.
    • 새 Kafka 클러스터로 옮기는 마이그레이션을 화요일에 두 시간 만에 큰 문제 없이 끝냈고, 신호 지연은 많아야 한 시간이었다.
    • 새 복제본으로 binlog 보존 기간을 늘리려던 방법이 통하지 않자, 12월 9일 화요일 시점의 인스턴스를 띄워 그때부터 복제해 Activity Log 손실을 줄였다.
    • 옛 Kafka 클러스터를 정리하고 EU 리전의 Activity Log 일부를 따라잡았다.
    후속 조치
    • 조직이 커지는 만큼 여러 곳에 흩어진 정보를 더 잘 모은다.
    교훈

    Honeycomb 은 "다음에는 Kafka 클러스터를 없애지 말자" 는 설명에서 멈추지 않고 더 넓은 영향을 봐야 한다고 밝혔다. 사전 운영 클러스터는 노드가 적어 구조상 이 문제를 재현하기 어려웠고, 운영과 더 닮은 클러스터에서 시험했다면 잡을 가능성이 훨씬 높았다. 이번 장애에 얽힌 요소 상당수는 이미 알려져 있었고 우회 계획, RFC, 안전하게 훈련하는 절차를 적은 문서도 있었지만, 쓴 사람 말고는 그런 문서가 있는지 몰랐거나 검색으로 찾을 수 없었다. 마감이 멀고 범위가 불확실한 내부 작업은 급한 작업에 밀려 거듭 미뤄지기 쉽다. 핵심 개입 상당수는 이제 그 구성 요소를 맡지 않는 사람들에게서 나왔고, 이는 팀 구성과 기술 구성 사이에 틈이 벌어졌다는 뜻이다. 에스컬레이션을 더 빨리 했어야 했다는 의견과 대응을 지속 가능하게 해야 한다는 의견이 함께 나왔다. 선임 엔지니어들이 들어오자마자 저절로 지휘를 잡는 문제와, 베타 기능의 손실을 너무 자세히 알린 대외 소통도 과제로 남았다.

  2. 증상

    여러 리전에서 Cloud Pub/Sub 에 메시지를 게시할 수도, 구독할 수도 없었다. 백로그 지표는 오래된 값이거나 아예 비어 있을 수 있었다. 상태 페이지의 제목은 "Multiple regions completely blocked for subscribe for Pubsub" 였다.

    촉발

    미국 태평양 시간 06:54 부터 07:30 사이에 잘못된 서비스 설정 변경이 여러 리전에 배포됐다. 이 변경은 리전 메타데이터 데이터베이스에 접근하는 권한을 의도치 않게 지나치게 좁혔다.

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

    엔지니어들은 영향이 시작되고 9분 뒤인 미국 태평양 시간 07:03 에 내부 텔레메트리로 장애 알림을 받았다. 순서 지정 구독 일부가 백로그를 소비하지 못하는 문제는 09:07 에 역시 내부 텔레메트리 알림으로 알았다.

    조치
    • 문제를 일으킨 설정 변경을 찾아 미국 태평양 시간 08:07 에 롤백을 마쳤다.
    • 영향을 받은 순서 지정 구독을 모두 찾아 고쳤고, 이 작업을 미국 태평양 시간 23:09 에 마쳤다.
    후속 조치
    • 설정 변경의 영향을 운영 환경에 닿기 전에 잡을 수 있도록 사전 운영 환경과 운영 환경의 설정을 같게 맞추는 규칙을 더 강하게 적용한다. 목표일은 2025년 1월 31일이다.
    • 변경 관리 절차를 검토해 앞으로 설정 변경이 우선순위에 맞춰 단계적으로 배포되게 한다. 목표일은 2025년 1월 31일이다.
    • 순서 메타데이터의 불일치를 미리 잡아내는 모니터링을 더한다. 목표일은 2025년 3월 31일이다.
    • 순서 지정 메시지가 전달되지 않게 만든 Cloud Pub/Sub 의 순서 메타데이터 관리 버그를 고친다. 목표일은 2025년 6월 30일이다.
  3. 증상

    10:08 CEST 에 모니터링에 메시징 플랫폼 연결 문제가 보였고, 10:09 에 엔지니어가 이벤트 버스에 데이터를 넣지 못하는 것을 확인했다. 하이퍼바이저의 에이전트, 로드 밸런서의 로그 전달기, 배포가 영향을 받기 시작했다.

    촉발

    10:06 CEST 에 데이터 팀이 Apache Pulsar 를 3.3.1 로 올리는 작은 롤링 업그레이드를 시작하면서, 번들 배치를 최적화하는 새 로드 밸런서 TransferShedder 와 extensible unload 전략도 함께 켰다. 첫 브로커가 업그레이드될 때 새 로드 매니저 확장 기능이 제대로 초기화되지 않았고, 브로커들은 부하 메타데이터를 맞추는 시스템 토픽을 만들지 못했다.

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

    10:08 CEST 에 모니터링이 메시징 플랫폼 연결 문제를 보여 줬고, 10:09 에 엔지니어가 이벤트 버스에 데이터를 넣지 못하는 것을 확인했다. 시스템 토픽이 만들어지지 않은 첫 브로커는 죽지 않아 모니터링에 정상으로 보였고, 엔지니어들은 플랫폼 대역폭이 떨어지는 것을 보고 어떤 토픽도 로드되지 않았다는 것을 알았다.

    조치
    • 엔지니어들이 플랫폼 대역폭이 떨어지고 어떤 토픽도 로드되지 않았다는 것을 알고 unload 방식 변경을 되돌렸다. Pulsar 3.3.1 릴리스는 그대로 유지했다.
    • 11:36 CEST 에 메타데이터 충돌로 브로커가 다시 시작하지 못하자 엔지니어링 팀이 클라이언트 프록시를 내려 브로커에 걸린 부담을 덜었다.
    • 11:50 CEST 에 배포 담당 팀이 메시징 문제를 피하려고 알림 이벤트를 RabbitMQ 로 보내도록 바꿨다.
    • 모든 브로커를 멈추고 하나만 띄워 브로커 사이의 메타데이터 충돌을 막았다. 그 브로커가 배정되지 않은 시스템 토픽을 로드하자 토픽을 지웠고, 모든 브로커가 다시 시작해 10분이 안 되어 평소 상태로 돌아왔다.
    • 12:54 CEST 에 메시징 프록시를 재시작했다. 연결이 돌아오고 메시지 생산과 소비가 정상이 됐다.
    • 12:39 CEST 에 watchdog 이 실패한 구성 요소를 한꺼번에 다시 띄우지 못하게 멈추고, 상황을 파악하며 구성 요소를 하나씩 시작했다.
    • 12:50 CEST 에 저장소 클러스터를 지키려고 Metrics API 수집을 껐다. 버퍼링 덕분에 수집은 계속 받을 수 있었다.
    • 자원을 확보하려고 관측 지표의 장기 저장소인 Warp10/FoundationDB 클러스터를 비롯한 덜 중요한 서비스를 멈췄다. 핵심 서비스는 메모리 안의 Warp10 단독 인스턴스로 관측을 이어 갔다.
    • 13:35 CEST 에 모든 리전의 모니터링 인스턴스를 전역 유지보수 상태로 돌려 업스케일, 다운스케일, 도달 불가, 디스크 같은 모니터링 작업을 오케스트레이터로 보내지 않게 했다.
    • 과부하를 일으키는 VM 을 모아 정렬해 보니 메모리가 작은 VM 이었고, SRE 팀이 이 VM 을 하나씩 죽여 하이퍼바이저를 다시 통제했다.
    • 13:50 CEST 에 하이퍼바이저 12대에 작업 일부를 빼내라는 표시를 했고, 아직 자원이 필요한 다른 인스턴스를 위해 일부 로드 밸런서를 내려 CPU 와 메모리를 확보했다.
    • 14:08 CEST 에 복구를 앞당기려고 좀비 VM 일부를 정리했다.
    • 15:45 CEST 에 모니터링 인스턴스의 알림 큐를 비워 아직 쌓여 있던 모니터링 이벤트가 오케스트레이터 명령 사이로 쏟아져 들어가지 않게 했다.
    • 16:05 CEST 에 업그레이드를 위해 비워 두고 세워 둔 EU-FR-1 리전의 새 하이퍼바이저를 투입해 과부하된 하이퍼바이저를 도울 용량을 더했다.
    • 16:15 CEST 에 과부하된 하이퍼바이저 위에서 함께 과부하되어 오케스트레이션을 방해하던 RabbitMQ 노드를 클러스터에서 뺐다. 그 뒤 오케스트레이터가 제대로 돌았다.
    • 17:06 CEST 까지 모든 리전 L7LB 를, 17:30 까지 모든 L4LB 와 전용 L7LB 를 차례로 재시작했다.
    • 18:40 CEST 에 하이퍼바이저 에이전트와 컨트롤 플레인 사이의 통신 오류를 의심해 인프라의 모든 HV 에이전트를 재시작했다. 컨트롤 플레인 이벤트 버스와 통신하지 못하는 것으로 보이는 애드온 공급자 API 도 재시작했다.
    • 18:53 CEST 에 stopping 상태로 남은 VM 을 모두 없앴고 애플리케이션 배포가 이어졌다.
    • 20:51 CEST 에 Metrics API 수집을 부하를 단계적으로 올리는 QoS 정책과 함께 다시 켰다. 22:53 에 이 정책을 끄고 클러스터가 완전히 정상으로 돌아왔다.
    후속 조치
    • Pulsar 브로커와 클러스터 상태, 하이퍼바이저 부하와 I/O, 커널 패닉으로 인한 하이퍼바이저 재부팅, 좀비 VM, RabbitMQ 브로커와 클러스터 상태, 배포 큐 소비를 지표로 잡는다. 각 지표를 사건 시각, 감지 시각, 결정 시각, 해결 시각으로 따져 운영이 잘 돌아간 곳과 가시성이나 대응이 모자란 곳을 가려낸다.
    • 너무 많은 모니터링 알림을 다루는 방법을 정한다.
    • 리전 bastion 하나가 취약하므로 백업 bastion 을 검토한다.
    • 컨트롤 플레인 복구 절차를 다시 세운다.
    • 모니터링과 오케스트레이션의 연관 관계를 다시 따진다.
    • 장애 도메인 분리와 멀티 테넌시의 관계를 다시 검토한다.
    • 런타임 이미지와 하이퍼바이저의 역할을 다시 생각한다.
    • Pulsar 처럼 여러 차례에 나눠 내보내는 릴리스 업그레이드를 격리한다.
    • 런타임 이미지를 다시 설계하고 하이퍼바이저와 더 잘 통합한다.
    • 관측 서비스를 리전별로 나눠 이중화한다.
    • 작은 VM 의 Vector 설정에서 buffer.max_events 와 buffer.max_size 를 정한다. type=disk 이면 buffer.max_size 는 적어도 256Mo 여야 한다.
    • Vector 의 buffer.type 을 기본값 memory 에서 disk 로 바꾼다.
    • Vector 의 buffer.when_full 을 기본값 block 에서 drop_newest 로 바꾼다.
    • Journald 의 로그 상세 수준과 SystemMaxUse 를 조정한다.
    • Cgroups 제한을 걸어 프로세스를 더 잘 통제한다.
    • VM 관리자에 I/O 제한을 건다.
    • 좀비 VM 을 더 잘 찾아낸다.
    교훈

    작은 릴리스나 작아 보이는 설정 변경은 큰 릴리스에 쓰는 시뮬레이션 절차를 거치지 않았고, 이번 장애는 그 변경에서 시작됐다. 브로커가 살아 있으면 정상으로 보는 모니터링은 확장 기능의 초기화 실패를 잡지 못했다. Clever Cloud 가 자기 플랫폼 위에서 도는 구조는 평소 이점이 많지만, 이번에는 복구에 필요한 스케줄러와 컨트롤 플레인이 같은 장애에 묶였다. 모니터링이 도달 불가와 CPU 증가에 반응해 배포를 크게 늘렸고, 이 배포가 과부하된 컨트롤 플레인과 인프라를 더 눌렀다. Clever Cloud 는 Pulsar 와 RabbitMQ 의 브로커 상태와 클러스터 상태, 하이퍼바이저 부하와 I/O, 커널 패닉 재부팅, 좀비 VM, 배포 큐 소비를 지표로 삼아 사건 시각, 감지 시각, 결정 시각, 해결 시각으로 따졌다. Clever Cloud 는 이 방식으로 기존 규칙을 다시 따져 볼 수 있었고, 인프라 일부를 고치거나 다시 설계할 수 있다는 것을 알게 됐다고 밝혔다. 여름 휴가철이었지만 Clever Cloud 는 13:00 CEST 에 이미 휴가 중인 사람들까지 불러 대응 인력을 빠르게 늘렸다.

  4. 증상

    2024-07-30 PDT 오후 2:45 부터 US-EAST-1 리전의 여러 AWS 서비스에서 지연과 오류율이 올랐다. CloudWatch Logs, Amazon Data Firehose, Amazon S3 이벤트를 게시하는 이벤트 프레임워크, Amazon ECS, AWS Lambda, Amazon Redshift, AWS Glue 가 영향을 받았다. 같은 리전의 다른 Kinesis Data Streams 셀로 가는 요청은 정상이었다.

    촉발

    2024-07-30 PDT 오전 9:09 에 내부 Kinesis 셀 하나의 가용 영역 한 곳에서 정기 배포가 시작됐다. 이 셀에는 처리량이 아주 낮은 샤드가 아주 많았다. 배포가 호스트를 서비스에서 뺐다가 다시 넣자 셀 관리 시스템이 잘못 동작했다.

    원인
    구성 요소
    기여 요인
    조치
    • PDT 오후 4:25 에 덜 급한 내부 워크로드의 유입 스트림을 줄여 부하를 덜어 내는 변경을 배포했다. 셀 관리 시스템이 처리할 데이터가 줄어 오후 5:39 에 오류율과 지연이 나아지기 시작했다.
    • 보안 연결을 만드는 하위 시스템에 용량을 더해 셀 관리 시스템의 상태를 되살렸다. 오후 5:55 에 셀 관리 시스템이 Kinesis 요청 처리에 쓰는 보안 연결을 제대로 맺었다.
    • 오후 6:32 에 연결 프로비저닝을 더 나아지게 하려고 용량을 더 늘렸고, 오류율이 더 내려갔다.
    후속 조치
    • 장애 중에 한 변경을 US-EAST-1 에 그대로 남긴다. 데이터 플레인 연결을 만드는 용량을 늘리고, 부하를 덜어 내는 도구를 운영에 넣고, 연결 한도를 바꾼 것이 여기에 든다.
    • 새 Kinesis Data Streams 아키텍처의 셀이 있는 다른 모든 AWS 리전에도 같은 변경을 이미 적용했다.
    • 이번 장애를 일으킨 워크로드를 더 잘 다루도록 셀 관리 시스템을 더 고친다.
  5. 증상

    한 셀의 Kafka 브로커가 응답하지 않았다. 몇 시간 뒤 여러 셀의 Kafka 브로커 디스크가 차면서 브로커가 하나둘 멈췄고, US 리전의 많은 고객이 데이터 수집과 알림을 쓸 수 없었다.

    촉발

    엔지니어가 응답하지 않는 Kafka 브로커를 수동으로 재시작했는데, 같은 시각 자동 복구도 돌아 클러스터가 오래 성능 저하 상태에 머물렀다. 엔지니어는 밀린 데이터를 지키려고 장애 대응 도구로 Kafka 데이터 보존 기간을 크게 늘렸고, 이 변경이 문제가 난 셀뿐 아니라 모든 셀에 적용됐다.

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

    7월 29일 아침 엔지니어링 팀이 한 셀의 Kafka 브로커가 응답하지 않는 것을 봤다. 나중에 디스크 여유 공간이 줄어들 때 모니터링 시스템이 알림을 보냈지만, 같은 시각 다른 여러 시스템이 관계없는 경고를 내고 있어 엔지니어들은 이 알림을 놓쳤다.

    조치
    • 엔지니어링 팀이 응답하지 않는 Kafka 브로커를 수동으로 재시작했다. 같은 시각 자동 복구도 돌았고, 두 작업 모두 결국 무사히 끝났다.
    • 브로커의 디스크 공간 문제를 해결했다. 그 뒤에도 Kafka 문제가 여러 셀에 넓게 퍼져 있어 서비스 복구에 시간이 걸렸다.
    교훈

    셀 격리는 넓은 장애를 막는 가장 강한 보호 수단이다. 평소 운영뿐 아니라 긴급 도구도 이 격리를 지켜야 한다. 긴급 대응 도구는 혼란스러운 상황에서도 안전하게 쓸 수 있어야 하고, 그러면서도 필요한 기능은 빠짐없이 갖춰야 한다. 사람의 주의력은 한정되어 있으므로 장애 대응 절차와 알림을 계속 다시 따져 엔지니어의 주의가 가장 급한 신호로 가게 해야 한다.

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

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

원인별5

운영 실수2건

  1. IL-0286 Honeycomb 운영 Kafka 클러스터에서 브로커가 한꺼번에 사라져 토픽 파티션 여럿이 리더를 잃고 일부는 되살릴 수 없게 망가졌다
  2. IL-0280 New Relic US 리전의 여러 NRDB 셀에서 Kafka 브로커가 디스크 부족으로 잇따라 멈춰 고객이 몇 시간 동안 데이터 수집과 알림을 쓸 수 없었다

설정 변경2건

  1. IL-0528 Cloud Pub/Sub 가 여러 리전에서 게시와 구독을 모두 못 했고 순서 지정 구독 일부는 그날 밤까지 메시지를 받지 못했다
  2. IL-0285 Clever Cloud 의 Apache Pulsar 메시징 클러스터가 멈추면서 EU-FR-1 리전의 배포 API 가 먹통이 되고 하이퍼바이저들이 커널 패닉으로 재부팅됐다

소프트웨어 결함1건

  1. IL-0535 US-EAST-1 에서 AWS 내부용 Kinesis Data Streams 셀 하나가 느려져 CloudWatch Logs 와 이를 쓰는 여러 서비스의 지연과 오류가 늘었다

용량 한계1건

  1. IL-0384 US-EAST-1 의 Amazon Kinesis Data Streams 에서 레코드 읽기와 쓰기가 하루 대부분 실패했다

클라우드 제공자 장애1건

조직
  1. IL-0588 AppOptics 와 Librato 의 메트릭 API 가 대부분의 데이터에 5xx 를 내고 Kafka 파티션이 리더 없이 오프라인으로 남았다