그래프
사례2건
2건 중 1~2번째
IL-0572Merpay 회계 이벤트 처리 시스템에서 Cloud Pub/Sub 메시지 1000만 건이 밀려 새 회계 데이터가 하루 넘게 Cloud Spanner에 들어가지 못했다Mercari2026- 증상
월말 마지막 영업일 아침 6시쯤부터 Cloud Pub/Sub 메시지가 밀리기 시작했고, Cloud Spanner에 새 회계 데이터를 등록하지 못하는 상태가 간헐적으로 이어졌다. 밀린 메시지는 1000만 건 규모에 이르렀다. 복구와 재발을 거듭하며 수습하기까지 하루가 넘게 걸렸다.
- 촉발
장애 한 달여 전 Cloud Functions를 1st gen에서 Cloud Run 기반 2nd gen으로 옮기면서 --max-instances 를 지정하지 않아, 스케일 상한이 1st gen 기본값인 사실상 무제한에서 2nd gen 기본값인 100으로 내려갔다. 월말 아침 부하가 쉬는 구간 없이 약 40분 이어지자 이 상한에 걸렸다.
- 원인
- 구성 요소
- 기여 요인
- 조치
- 별도 pull 구독으로 Dataflow가 Cloud Storage에 저장해 둔 데이터를 다시 넣어 데이터 손실을 피했다.
- 후속 조치
- max-instances 를 비롯한 스케일 관련 파라미터를 배포 정의에 모두 명시해 세대나 기본값이 바뀌어도 영향을 받지 않게 했다. max-instances 는 Spanner 부하를 생각해 100에서 1000까지 단계적으로 올렸다.
- 콜드 스타트를 피하려고 min-instances 를 1로 두고, 핸들러의 공유 상태가 안전한지 확인한 뒤 concurrency 를 1에서 10으로 올렸다. 이에 맞춰 cpu는 1, memory는 512MB에서 1Gi로 늘렸다.
- mercari/spanner-autoscaler를 관리하는 SRE 팀이 High priority CPU와 Total CPU를 OR 조건으로 보는 dual CPU scaling mode를 구현했다. 팀은 이 기능이 담긴 v0.8.0을 도입해 Total CPU 임계값 70%를 새로 뒀다.
- 스케일업이 더 빨리 시작되도록 High priority CPU 임계값을 60%에서 55%로 내렸다.
- 월말 피크가 시작될 때 확보한 PU가 줄지 않도록 아침 5시부터 7시까지 Spanner 스케일다운을 막는다.
- 월말 아침이나 대규모 리컨사일이 도는 달처럼 부하를 예상할 수 있는 기간에는 일정에 따라 PU를 미리 확보한다.
- Datadog에 Cloud Run 인스턴스 수가 상한의 40%와 60%에 이르면 각각 경고 단계와 심각 단계로 알리는 모니터를 더했다.
- Datadog에 Pub/Sub의 전달되지 않은 메시지 수가 임계값을 넘으면 알리는 모니터를 더했다. 오탐을 피하려고 보수적인 임계값에서 시작해 평소 상태를 알아 가며 단계적으로 낮춘다.
- 교훈
관리형 서비스의 세대를 옮길 때는 직접 바꾸지 않은 기본값이 부하가 걸릴 때 문제로 드러난다. 스케일 상한, 동시 처리 수, 타임아웃처럼 평소에는 효과가 보이지 않는 파라미터는 옮길 때마다 명시해야 한다. 장애 원인은 하나가 아닐 수 있으므로 촉발, 증폭, 실제 피해로 이어진 요인을 각각 봐야 한다. 설정 최적화와 그 한계에 가까워지는 것을 알아채는 모니터링은 늘 함께 갖춰야 하고, 물려받아 운영하는 시스템일수록 설정과 전제를 정기적으로 다시 살펴야 한다.
IL-0285Clever Cloud 의 Apache Pulsar 메시징 클러스터가 멈추면서 EU-FR-1 리전의 배포 API 가 먹통이 되고 하이퍼바이저들이 커널 패닉으로 재부팅됐다Clever Cloud2024- 증상
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건에서 가장 많이 나오는 구성 요소: 메시지 브로커, 자동 용량 관리 시스템. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.
원인별2
업그레이드로 깨진 호환성1건
- 조직