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

사례2건

2건 중 1~2번째

  1. 증상

    GCP 의 관리형 커넥션 풀러에서 자체 운영 PgBouncer 로 옮기는 첫 운영 카나리에서, 일부 음성 요청이 대화 도중 멈췄다가 정확히 300초 뒤 타임아웃됐다. 다른 요청은 그보다 훨씬 일찍 SQLAlchemy 커넥션 풀 고갈로 실패했다.

    촉발

    Decagon 이 GCP 의 관리형 커넥션 풀러에서 자체 운영 PgBouncer 로 옮기면서 PgBouncer 와 Postgres 사이의 TLS 경로가 바뀌었다. 첫 운영 카나리에서 이 바뀐 경로 때문에, PgBouncer 에 숨어 있던 버그가 드러날 마지막 조건이 갖춰졌다.

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

    운영 카나리 중 일부 음성 요청이 대화 도중 멈추고 정확히 300초 뒤 타임아웃됐다. Sentry 에 "SSL connection has been closed unexpectedly" 오류가 몇 건 찍혔고, 다른 요청은 SQLAlchemy 커넥션 풀 고갈로 실패했다.

    조치
    • 애플리케이션에서 application name 값을 줄여 ParameterStatus 패킷이 PgBouncer 의 작은 패킷 파싱 기준 아래에 머물게 했고, 버그의 세 조건 중 하나를 없애 마이그레이션을 계속했다.
    후속 조치
    • PgBouncer 업스트림에 이벤트 루프 버그의 수정을 머지했다. epoll() 대기로 돌아가기 전에 SSL_pending() 을 확인하고, OpenSSL 에 복호화된 바이트가 남아 있으면 계속 읽는다.
    교훈

    인프라 마이그레이션은 자기 시스템만 바꾸는 것이 아니라 스택의 다른 곳에 숨어 있던 버그를 드러낼 수 있다. 이번에는 자체 운영 PgBouncer 로 옮긴 일이 SQLAlchemy, PgBouncer, OpenSSL, PostgreSQL wire protocol 이 얽힌 오래된 예외 상황이 드러날 마지막 조건을 만들었다. 버그는 응답이 정확히 그 모양일 때는 늘 재현됐지만, 그런 응답 자체가 드물어 스테이징에서 나타나지 않았다.

  2. 증상

    2019년 7월 10일 16:35 UTC 에 데이터베이스 클러스터의 primary 노드가 고장 났고, 1분 뒤 자동 모니터링이 선출 실패를 잡아 알림을 보냈다. Stripe API 요청 대부분이 실패하기 시작했다.

    촉발

    16:35 UTC 에 데이터베이스 클러스터의 primary 노드가 고장 났다. 그 shard 에는 멈춘 노드가 여럿 있어 석 달 전 마이너 버전 업그레이드로 들어온 장애 조치 결함이 드러났다. 두 번째 장애는 선출 프로토콜을 이전 마이너 버전으로 되돌린 변경 때문에 일어났다.

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

    첫 장애는 자동 모니터링이 1분 안에 선출 실패를 잡았고, 16:36 UTC 에 팀이 알림을 받아 대응을 시작했다. 두 번째 장애는 21:14 UTC 에 클러스터의 shard 몇 개를 사용할 수 없다는 자동 알림으로 알았다.

    조치
    • 17:00 UTC 에 데이터베이스 클러스터의 모든 노드를 재시작해 새 primary 선출을 성공시켰다. 17:02 에 Stripe API 가 완전히 복구됐다.
    • 22:34 UTC 에 운영 설정을 고쳐 새로 배포하고 데이터베이스 클러스터의 노드를 재시작해 영향받은 shard 를 되살렸다.
    • 클러스터가 정상인지 확인한 뒤 사용자가 직접 보낸 API 요청에 필요한 서비스부터 트래픽을 다시 올렸다. 22:47 UTC 에 완전히 복구됐다.
    후속 조치
    • 노드가 복제 지연 지표를 보내지 않으면 알리는 모니터링을 더했다.
    • shard 가 데이터베이스 장애 조치 시스템의 이 선출 결함을 일으킬 수 있는 상태에 들어가면 알리는 모니터링을 더했다.
    • 이 결함을 고치는 수정을 데이터베이스 메인테이너와 함께 만든다.
    • 특정 클러스터로 가는 작업이 실패하면 끊어 내는 서킷 브레이커를 더 넣는다. 이번 사고의 클러스터도 대상이다.
    • shard 하나가 고장 나도 그 영향을 가두는 장애 격리 기법을 더 도입한다.
    • 실패한 요청을 거듭 재시도하는 클라이언트가 쓰는 자원을 제한한다.
    • 장애 대응 중 운영자가 설정을 빠르게 바꿀 때 더 안전하게 할 수 있도록 절차와 도구를 더 만든다.
내 클러스터에도 있는지 확인하기

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

원인별1