그래프
사례2건
2건 중 1~2번째
- 증상
2025-10-21 21:45 UTC, 타임아웃 오류를 줄이려는 배포 직후 자동 모니터링이 기능 플래그 서비스의 오류율 상승을 잡았다. 2분 만에 롤백했지만 오류율은 내려가지 않았고, US 데이터센터에서 평가 요청의 약 38% 가 오류를 냈다.
- 촉발
10월 21일에는 증상만 고치려던 타임아웃 처리 배포가 장애를 일으켰다. 28일에는 플래그 서비스와 무관한 일상 배포가 파드 롤아웃을 일으켰고, 이 롤아웃이 장애로 이어졌다. 24일에는 로드밸런서 뒤에서 모든 트래픽을 IP 하나에서 온 것으로 본 레이트 리밋 배포가 장애를 일으켰다.
- 원인
- 구성 요소
- 기여 요인
- 감지
21일에는 배포 2분 뒤 자동 모니터링이 오류율 상승을 잡았고, 28일에는 온콜이 높은 오류 수 경보를 받았다. PostHog 는 대부분의 경우 2분 안에 감지했다고 정리했다. 24일에는 429 오류 경보가 없어서 18:10 UTC 부터 들어온 고객 신고로 알았고, 감지까지 62분이 걸렸다. CPU 경보가 아예 없어서 공통 원인인 CPU 포화는 오래 드러나지 않았고, 29일에서 30일 사이 장애는 7시간 넘게 이어졌다.
- 조치
- 10월 21일 타임아웃 처리를 바꾼 배포를 2분 안에 롤백했지만 오류는 멈추지 않았다.
- 10월 21일 23:00 UTC 부터 연결과 Redis 쓰기를 조절해 23:28 UTC 에 서비스를 복구했다.
- 10월 28일 롤아웃을 멈추고 US 플래그 파드를 0개로 줄여 Redis 가 회복되기를 기다린 뒤, 파드를 차례로 다시 올렸다.
- 10월 30일 00:03 UTC 에 하드웨어 변경을 롤백해 오류는 대부분 가라앉혔지만 지연은 남았다.
- 파드 리소스 요청을 늘리고 쿠버네티스 플릿 크기를 조정해 노드당 파드 수를 줄였다.
- 로드밸런서와 서비스 사이 Envoy 재시도에 한도를 걸었다.
- 데이터베이스 연결 타임아웃과 다른 중요한 설정을 런타임 설정으로 옮기고, 타임아웃 값을 피크 부하에 맞게 늘렸다.
- 노드마다, 파드마다 CPU 사용률이 80% 를 5분 동안 넘으면 온콜을 호출하는 CPU 경보를 추가했다.
- 후속 조치
- 플래그, 수집, 인프라 팀 엔지니어로 전담 팀을 꾸려 애플리케이션과 인프라 전체를 살피고 남은 병목을 찾는다.
- 플래그 서비스의 Redis 를 본 애플리케이션의 Redis 와 분리하는 방안을 검토한다.
- ArgoCD 동기화를 다시 켜기 전에 플래그 서비스 차트 설정을 ArgoCD 의 현재 값에 맞추고, 배포 전략과 Redis 전략을 정한다.
- 플래그 관련 코드의 필수 코드 오너를 기능 플래그 팀으로 정한다.
- 중요한 플래그 지표와 런북 링크를 한데 모은 대시보드를 만들고, 기능 플래그 런북을 고친다.
- 기존 서비스 지표와 인프라 지표에 빠져 있는 경보를 추가한다.
- readiness 검사가 liveness 검사를 그대로 따라 하지 않고, 데이터베이스에 ping 을 보내는 식으로 부하가 걸렸을 때 약해졌던 의존성을 확인하게 바꾼다.
- 캐시 채우기 작업에 레이트 리밋을 걸어 Redis 에 감당하지 못할 만큼 작업이 몰리지 않게 한다.
- 연결 풀을 모니터링해 풀이 바닥에 가까워지면 자동으로 요청을 조절하고, 동시 연결 수에 상한을 둔다.
- 운영 규모의 부하 시험 체계를 만든다.
- 점진적 롤아웃 기반을 만들어 배포가 미치는 범위를 줄인다.
- Postgres 에서 Redis 로 가는 데이터 흐름을 문서로 정리하고, 데이터 전송이 한꺼번에 몰릴 때 쓸 런북을 만든다.
- 교훈
가장 큰 교훈은 CPU 크기 산정이었다. 노드가 파드 요청에 비해 작으면 노드 하나에 파드가 너무 많이 몰리고, CPU 포화가 과도한 병렬 처리, 연결 풀 고갈, 느린 쿼리처럼 서로 다른 모습으로 나타난다. 증상만 고친 수정 때문에 21일의 장애가 28일에 되풀이됐다. PostHog 는 CPU 를 넉넉히 받은 파드를 적은 수로 돌리는 편이 낫다고 정리했다. 기능 플래그 서비스와 본 애플리케이션이 Redis 를 같이 쓰면 한쪽 과부하가 다른 쪽을 쓰러뜨리는 단일 장애 지점이 된다. CPU 지표는 처음부터 경보로 걸어야 하고, Postgres 에서 Redis 로 가는 전송 급증도 경보 대상이다. 재시도, 캐시 채우기, 연결 생성에 한도가 없으면 장애가 커진다. 과부하 패턴은 운영 트래픽에서만 드러났으므로 부하 시험이 필요하고, 중요한 설정은 배포 없이 바꿀 수 있어야 한다.
IL-0003etcd 클러스터 재구성 뒤 쿠버네티스 버그로 linkerd 가 서비스 위치 갱신을 받지 못했고, linkerd 를 모두 재시작하자 엔드포인트가 없는 서비스를 파싱하지 못하는 오류가 드러나 플랫폼 전체가 멈췄다Monzo2017- 증상
14:10 에 입출금 계좌 결제 처리에 필요한 서비스 하나를 배포하자 그 서비스로 가는 요청이 모두 실패했다. 이때부터 입출금 계좌 고객의 결제가 실패했다. 선불 카드는 이 서비스를 쓰지 않아 아직 영향이 없었다.
- 촉발
14:10 에 엔지니어가 입출금 계좌 결제 처리에 필요한 서비스에 변경을 배포했다. 2주 전 etcd 클러스터를 재구성한 뒤로 쿠버네티스와 etcd 클라이언트 버그가 요청 타임아웃을 낼 수 있는 상태였고, 이 때문에 linkerd 는 배포 뒤 새 파드의 위치를 받지 못했다.
- 원인
- 구성 요소
- 기여 요인
- 감지
14:10 배포 직후 그 서비스로 가는 요청이 모두 실패했고 입출금 계좌 결제가 실패하기 시작했다. 14:12 롤백 뒤에도 오류가 계속되자 14:16 에 내부적으로 장애를 선언했다. 15:13 에 플랫폼 전체가 멈추자 자동 알림이 거의 모두 울렸다.
- 조치
- 14:12 에 배포한 변경을 롤백했지만 오류는 계속됐다.
- 고객 영향을 줄이려고 장애 때 쓰는 내부 백업 절차를 가동해 대부분의 고객이 계속 카드를 쓸 수 있게 했다.
- 14:26 에 linkerd 인스턴스 수백 개를 모두 재시작하기 시작했고, 이 조치가 장애를 키웠다.
- 14:37 에 kubelet 이 apiserver 에서 설정을 받지 못하자 apiserver 프로세스 세 개를 재시작했다.
- 15:27 에 플랫폼 팀이 새 linkerd 버전을 배포하기 시작했다. 이 버전에는 비호환 문제를 고친 코드가 들어 있었고, 스테이징에서 몇 주째 시험하던 버전이었다.
- 15:31 에 엔드포인트가 없는 쿠버네티스 서비스를 지워 linkerd 가 서비스 디스커버리 정보를 읽게 했고, 플랫폼이 회복했다.
- 후속 조치
- 클러스터 재구성 뒤 타임아웃을 일으킬 수 있는 쿠버네티스 버그를 고친다.
- 파싱 오류를 고친 새 linkerd 버전을 배포한다.
- 영향을 받은 구성 요소에 더 나은 헬스 체크, 대시보드, 알림을 만들어 무엇이 잘못됐는지 더 분명한 신호를 주고 사람의 실수를 막는다.
- 장애를 내부와 외부에 더 분명하고 빠르게 알리도록 절차를 개선한다.
- 교훈
분산 시스템의 대규모 장애는 이해하기 매우 어렵고, 사람이 좋은 뜻으로 한 조치가 오히려 문제를 키울 수 있다. 이번에는 linkerd 를 모두 재시작한 결정이 또 다른 버전 비호환 문제를 드러내 장애를 더 키웠다. 배포가 잦고 노드와 애플리케이션 장애에 자동으로 대응하는 백엔드에서는 네트워크가 매우 동적이다. 그래서 배포와 요청 라우팅 시스템을 믿을 수 있는 것이 무엇보다 중요하다. Monzo 는 인터페이스를 바꿀 때 앞뒤 버전과 호환되게 해서 롤백을 안전하게 할 수 있게 해 두었지만, 이번에는 롤백한 뒤에도 오류가 계속됐다.
이 2건에서 가장 많이 나오는 구성 요소: 인메모리 캐시, 애플리케이션 데이터베이스. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.