그래프
사례2건
2건 중 1~2번째
- 증상
2025년 8월 28일 03:53 UTC 에 PagerDuty 의 Kafka 에서 장애가 시작됐다. 처음 온 알림은 Kafka 브로커 하나의 고장을 가리켰지만, 곧 다른 브로커들도 메모리가 바닥났다. 미국 서비스 리전의 일부 고객은 새 이벤트가 처리되지 않거나 늦게 처리됐다.
- 촉발
API 키 사용 내역을 Kafka 토픽에 남기는 새 기능의 논리 오류로 API 요청마다 새 Kafka 프로듀서가 만들어졌다. 이 기능은 8월 21일 1% 에서 시작해 27일 5%, 같은 날 저녁 25%, 28일 75% 로 롤아웃됐다.
- 원인
- 구성 요소
- 기여 요인
- 감지
03:53 UTC 에 장애가 시작되자 처음 온 알림은 Kafka 브로커 하나의 고장을 가리켰다. 두 번째 장애는 16:38 UTC 에 Kafka 성능이 다시 떨어지며 울린 알림으로 알았다. 핵심 API 오류를 알리는 중요한 알림은 웹훅 호출에 묻혔다.
- 조치
- 처음 알림이 브로커 하나의 고장을 가리켜 하드웨어 문제를 의심했고, 클러스터를 늘리고 그 브로커를 뺐다.
- 원인을 조사할 여유를 얻으려고 Kafka 힙 크기를 두 배로 늘렸고, 이를 적용하려고 클러스터 전체를 롤링 재시작해 Kafka 를 안정시켰다.
- 상태 페이지 자동 게시가 되지 않자 엔지니어링 팀을 더 부르고 백업 절차를 시작해 상태 페이지에 손으로 공지를 올렸다.
- Kafka 가 돌아온 뒤 여러 애플리케이션을 손으로 복구했고, ksqlDB 스트림 관리 중 생긴 데이터 손실은 스크립트로 백필했다.
- 두 번째 장애 때 당번 대응자가 힙 크기를 다시 두 배로 늘리고 롤링 재시작했다.
- API 사용 기능의 롤아웃과 힙 증가 사이의 강한 상관관계를 찾아, 이 기능이 Kafka 메시지를 더는 보내지 않게 하는 풀 리퀘스트로 기능을 되돌렸다.
- 후속 조치
- 상태 페이지 자동 게시를 막은 의존을 없앴고, 손으로 공지하는 런북을 단순하게 고쳐 다시 냈다.
- 플랫폼 일부가 망가져도 상태 공지가 빨리 나가도록 실전 연습을 평소 업무에 더 꾸준히 넣는다.
- 힙, 가비지 컬렉션, 프로듀서와 컨슈머 상태 같은 JVM 과 Kafka 수준의 모니터링을 넓혀 가용성에 영향이 가기 전에 부하 신호를 드러낸다.
- 서비스 의존 관계 지도를 보강해 대응 중에 연쇄 장애를 더 쉽게 따라가게 한다.
- 고객 영향 지표 수집을 인시던트 작업 흐름에 자동으로 넣어 대응자가 영향 범위를 늘 볼 수 있게 한다.
- 큰 롤아웃에 준비 점검표와 더 느린 증가 기간 같은 변경 관리 장치를 더 엄격하게 두고, 큰 장애 직후에는 특히 그렇게 한다.
- 스트리밍 시스템의 복구 방법을 고쳐 장애가 길어질 가능성을 줄인다.
- 상태 페이지 공지, 내부와 외부 동기화, 알림 같은 소통 작업을 자동화해 혼선을 줄이고 이해관계자가 같은 정보를 보게 한다.
- 상태 페이지 장애 조치와 PD-on-PD 절차 같은 큰 장애 대응 흐름을 카오스 엔지니어링으로 매달 시험해 자동화에 덜 기댄다.
- 인시던트 심각도 등급과 전담 소통 담당을 포함한 역할 정의를 더 분명히 해 혼란을 줄이고 대응을 빠르게 한다.
- 교훈
PagerDuty 는 연쇄 장애가 본래 예측하기 어렵고, 한 서비스의 작은 문제가 시스템 도표로는 보이지 않는 길로 다른 서비스에 번진다고 봤다. 관측성의 빈틈 때문에 대응자는 하위 시스템 여러 개가 망가질 때까지 처음 무너진 것을 보지 못했다. 사람은 의존 관계를 직선으로 생각하지만 운영 시스템은 그렇게 움직이지 않는다. 통화에 참여한 누구도 시스템 전체를 머릿속에 담고 있지 않아 의존 관계를 잇는 데 시간이 걸렸다. 새 기능은 안전하게 내려고 별도 배포 대신 설정으로 조금씩 켰는데, 이 때문에 장애와 변경을 바로 잇기 어려웠다. 이 기능은 잘 쓰지 않는 프레임워크와 라이브러리로 만들어서, 요청마다 프로듀서를 새로 만든다는 것이 코드에 드러나지 않았다. 여기에 Kafka 알림이 적었던 것이 겹쳐 점진적 롤아웃 절차가 있어도 장애를 막지 못했다. 중요한 알림이 우선순위 낮은 웹훅 알림에 묻혔고, 백업 절차로 상태 페이지에 공지하는 일처럼 일부 운영 절차는 더 자주 연습해야 했다. 미리 만들어 둔 백필 스크립트와, 처리를 일시 정지했다가 재개하는 런북은 완벽하지 않았지만 대응자에게 출발점을 줬다.
- 증상
2022년 4월 11일 13:17 UTC 에 고객과 Gitpod 직원들이 워크스페이스가 간헐적으로 응답하지 않는다고 알렸다. 4월 8일과 9일에 새 세대 워크스페이스 클러스터 ws39 를 모든 리전에 배포한 직후였다.
- 촉발
2022년 4월 8일과 9일에 새 세대 워크스페이스 클러스터 ws39 를 모든 리전에 배포한 것이 시작이었다.
- 원인
- 구성 요소
- 기여 요인
- 감지
2022년 4월 11일 13:17 UTC 에 고객과 Gitpod 직원들의 신고로 알았고, incident.io 연동으로 Slack 에 장애를 열었다. 4월 12일에도 고객과 직원의 신고로 알았고, 4월 17일에는 엔지니어들이 워크스페이스 노드의 CPU 부하가 오른 것을 보고 내부 장애를 열었다.
- 조치
- IO 제한 기능이 없어 워크스페이스 시작 트래픽을 이전 세대 클러스터 ws38 로 돌렸고, 4월 11일 15:37 UTC 에 마쳤다.
- t2d 대신 더 빠른 c2d 머신 유형과 로컬 SSD 를 쓰는 새 클러스터 ws39a 를 만들어 트래픽을 옮겼다.
- Let's Encrypt 속도 제한 문제를 풀고, Let's Encrypt 에 한도를 올려 달라고 요청했다.
- ws38 클러스터를 쓸 수 없어 EU XL 트래픽을 임시로 리전 EU 클러스터로 보내 워크스페이스를 다시 시작할 수 있게 했다. 그리고 망가진 ws-eu39xl 을 대신할 ws-eu39bxl 클러스터를 새로 만들었다.
- stopping 상태에 걸린 워크스페이스를 정리해 사용자가 다시 시작할 수 있게 했다.
- 4월 8일 배포 전처럼 1TB 부트 디스크를 단 노드로 ws40 을 만들어 디스크 IO 대역폭을 늘렸다.
- 모니터링으로 노드의 작업을 직접 살펴 과도한 CPU 시간을 쓰는 워크스페이스를 찾아 시스템에서 지웠다.
- 노드를 손으로 뒤지고 채굴 탐지 시스템을 함께 써서 부정 사용자를 찾아 Gitpod 사용을 막았다.
- ws38 세대에는 없던 ws-daemon 변경을 되돌려 CPU 제한을 다시 안정시켰고, 이 수정을 ws34 클러스터에 담아 배포했다.
- 새 ws34 배포에서 워크스페이스 포트로 가는 ACME HTTP 요청을 막아 Let's Encrypt 한도에 다시 걸리지 않게 했다.
- 워크스페이스 사이에 디스크 IO 를 공정하게 나누는 ws41xl 클러스터와 일반 리전용 ws41 클러스터를 만들어 트래픽을 단계적으로 옮겼다.
- 후속 조치
- 테스트 결과가 진행하면 안 되는 배포를 미리 걸러 내도록 테스트 자동화에 계속 투자한다.
- 새 클러스터로 트래픽 비율을 옮기는 간격을 배포마다 다르게 하고, 큰 배포일수록 단계 사이를 길게 둔다.
- 워크스페이스 클러스터 배포에 위험 평가 단계를 넣어 변경 묶음의 크기와 배포 속도를 정하고, 이 단계를 자동화하는 것을 목표로 한다.
- 팀 사이 의존이 롤백을 막지 않도록 팀끼리 주는 영향을 계속 줄인다.
- PR 을 머지하기 전에 하위 호환이 깨지는 변경을 찾는 리뷰 기준을 더하고, 그런 PR 은 나눠서 배포를 롤백하기 어려운 상황을 피한다.
- 장애 완화의 첫 수단으로 롤백을 권하도록 절차를 고쳤고, 이 과정을 자동화하는 방법을 논의한다.
- 상태 페이지의 워크스페이스 서비스가 장애를 주황이나 빨강으로 제대로 표시하도록 고쳤고, 플레이북도 그에 맞게 고쳤다.
- 장애 중 내부 소통을 Slack 채널 하나와 Google Meet 하나로 모으고, 장애 절차를 그에 맞게 고쳤다.
- 당번 체계를 다시 짜서 5월 9일부터 엔지니어링 인력의 10% 가 늘 당번을 맡고, 그 시간으로 관측성과 알림과 시스템 안정성을 개선한다.
- 교훈
4월 11일에 롤백을 결정했다면 가장 좋았다. 롤백하지 않고 수정을 계속 만들어 배포하면서 고객은 필요 이상으로 오래 성능 저하를 겪었고 일부는 데이터를 잃었다. 규모가 크고 바로 앞 배포와 가까운 변경을 너무 빨리 내보냈고, 테스트 결과가 배포를 막았어야 했다. 배포 묶음을 작게 하고 배포를 자주 한다는 원칙을 ws39 에서 지키지 못했고, 팀 사이 의존이 롤백을 어렵게 만들었다. 기여 요인 가운데 일부는 막을 수 있었다.
이 2건에서 가장 많이 나오는 구성 요소: 컨테이너 CPU 한도, 메시지 브로커. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.
원인별1
배포 결함2건
- 기여 요인