Incident Library
적용된 필터 구성 요소메시지 브로커기여 요인순환 의존모두 풀기검색어 없이 필터만 적용한 목록입니다. 최근 사례부터입니다.
추천 필터 검색하면 검색어에서 찾은 분류 값이 여기에 나옵니다.

그래프

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

사례2건

2건 중 1~2번째

  1. 증상

    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 에 이미 휴가 중인 사람들까지 불러 대응 인력을 빠르게 늘렸다.

  2. 증상

    2020년 11월 25일 5:15 AM PST 에 Kinesis 레코드를 넣고 가져오는 호출의 오류 알람이 울리기 시작했다. Kinesis 를 쓰는 CloudWatch, CloudWatch Events, EventBridge 도 같은 시각부터 오류와 지연을 보였다.

    촉발

    2:44 AM PST 부터 3:47 AM PST 까지 Kinesis 프런트엔드 서버군에 비교적 작은 용량을 더했다. AWS 는 이것이 촉발 요인이었지만 근본 원인은 아니었다고 밝혔다.

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

    5:15 AM PST 에 Kinesis 레코드를 넣고 가져오는 호출의 오류 알람이 울리기 시작했고, 팀이 로그를 보기 시작했다.

    조치
    • 조심하려고 다른 오류를 조사하면서 새로 더한 프런트엔드 용량을 빼기 시작했다.
    • 재시작을 빠르게 하려고, 프런트엔드 서버가 시작할 때 이웃 프런트엔드 서버 대신 정본 메타데이터 저장소에서 바로 데이터를 받도록 설정을 넣기 시작했다.
    • 10:07 AM PST 부터 프런트엔드 서버를 다시 올리며 시간당 수백 대씩 천천히 트래픽을 더했다.
    • Cognito 팀은 장애 초기에 용량을 더해 Kinesis 호출을 버퍼링할 여유를 늘렸다.
    • 10:15 AM PST 에 Cognito 의 Kinesis 의존을 줄이는 변경을 배포하기 시작했고, 오류율이 내려가기 시작했다.
    • 10:36 AM PST 에 엔지니어들이 Lambda 함수 호출 호스트의 메모리 경합을 줄이는 조치를 해서 호출 오류가 풀렸다.
    • 의존이 적은 예비 도구로 Service Health Dashboard 에 게시하고, Personal Health Dashboard 로 영향받은 고객에게 직접 알리고, Service Health Dashboard 에 전역 배너 요약을 올려 고객에게 상황을 알렸다.
    후속 조치
    • CPU 와 메모리가 더 큰 서버로 옮겨 서버 수를 줄이고, 서버마다 서버군 안에서 통신하는 데 필요한 스레드 수를 줄인다.
    • 서비스의 스레드 사용량에 세밀한 알람을 더한다.
    • 운영체제 설정의 스레드 수 한도를 올리는 시험을 마친다.
    • 프런트엔드 서버군의 콜드 스타트 시간을 크게 줄이는 변경을 한다.
    • 프런트엔드 서버 캐시를 전용 서버군으로 옮긴다.
    • CloudWatch 같은 큰 AWS 서비스 몇 개를 따로 나눈 프런트엔드 서버군으로 옮긴다.
    • 백엔드에서 한 것처럼 프런트엔드 서버군의 셀 단위 분리를 크게 앞당긴다.
    • Cognito 웹 서버가 Kinesis API 오류를 겪어도 버퍼를 다 쓰지 않고 버티도록 고쳤다.
    • CloudWatch 로컬 지표 데이터 저장소에 지표 데이터 3시간 치를 보관해, CloudWatch 사용자와 AutoScaling 같은 서비스가 최근 지표를 바로 읽게 한다. US-EAST-1 에는 적용을 마쳤고 앞으로 몇 주 동안 전 세계에 배포한다.
    • 지원 엔지니어가 Service Health Dashboard 예비 게시 도구를 정기적으로 훈련받도록 지원 교육을 바꿨다.
    교훈

    프런트엔드 서버마다 유지할 스레드 수는 서버군의 서버 수에 비례하므로, 서버 수를 줄이면 스레드 수에 큰 여유가 생긴다. AWS 에 따르면 셀 단위 분리는 서비스 안에서 장애의 영향을 가두고, shard-map 캐시 같은 구성 요소가 이미 시험하고 운영해 본 범위 안에서 돌게 하는 방법이다. 프런트엔드 서버군의 셀 단위 분리는 진행 중이었지만 일이 커서 아직 끝나지 않았다. AWS 는 이 작업이 끝나면 앞으로 드러날 모르는 확장 한도에도 더 잘 대비할 수 있다고 봤다.

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

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

원인별2