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

사례2건

2건 중 1~2번째

  1. 증상

    2021년 9월부터 메트릭 질의 서비스의 업데이트를 롤아웃할 때마다 오류가 늘었다. 서비스 로그에는 DNS 오류 때문에 메트릭 데이터 저장소에 연결하지 못했다는 내용이 찍혔다. 클라이언트가 실패한 질의를 자동으로 재시도해 사용자에게 보이는 오류는 적었지만, 재시도 때문에 대시보드와 모니터의 지연이 늘었다.

    촉발

    2021년 8월 메트릭 질의 클라이언트의 업데이트를 롤아웃하면서 새 기본값인 gRPC round_robin 부하 분산 정책이 처음 적용됐다. round_robin 은 끊긴 채널을 자동으로 다시 연결하는데, 오래전에 넣어 둔 매우 공격적인 gRPC 재연결 타임아웃과 겹쳐 서비스 롤아웃 때마다 사라진 파드 IP 로 SYN 이 쏟아졌다.

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

    2021년 9월부터 메트릭 질의 서비스 롤아웃 때 오류가 늘어나는 것을 보았고, 서비스 로그에서 DNS 오류가 데이터 저장소 연결을 막는 것을 확인했다.

    조치
    • node-local-dns 파드의 메모리를 64 MB 에서 256 MB 로 올렸다. OOM 오류는 멈췄지만 DNS 오류는 계속됐다.
    • AWS 가 더 많은 연결을 추적할 수 있다고 한 더 큰 인스턴스 유형으로 서비스 인프라를 올려 보았고, 그것만으로 문제가 사라지는 것을 확인했다.
    • SYN 폭주를 일으킨 사용자 지정 gRPC 재연결 파라미터를 지우고 기본값으로 되돌리는 PR 을 만들었다. 다음 롤아웃에서는 오류가 나지 않았다.
    후속 조치
    • Cilium 프로젝트에 PR 을 기여한다. 이 PR 은 옛 파드 IP 에 unreachable 경로를 더해, 지워진 파드로 가는 요청이 martian 패킷이 되지 않게 한다. 그러면 역경로 필터가 SYN 을 버리지 않고, 클라이언트는 분명한 ICMP 오류를 받는다.
    교훈

    gRPC, 쿠버네티스, AWS 같은 강력한 추상화도 엣지 케이스에서는 평소에 숨어 있던 복잡함이 오류로 드러난다. 몇 달을 조사한 끝에, 이번 장애의 뿌리가 팀이 직접 한 변경에 있다는 것을 찾았다. 의존성의 버그를 피해 가려던 변경, 이전 장애를 고치려던 변경, 기본 재연결 파라미터를 덮어쓴 변경이었다. 이 변경들은 당시에는 안전해 보였지만 한참 뒤에 상관관계를 찾기 어려운 때에 뜻밖의 결과를 냈다. DNS 문제처럼 보여도 DNS 문제가 아닐 때가 있다. AWS ENA 지표와 VPC Flow Logs 는 연결 추적을 들여다보는 데 중요하다. DNS 전파 시간은 여러 요인에 좌우된다.

  2. 증상

    2019년 2월 4일 02:50 UTC 무렵부터 AWS us-east-1 의 Elastic Cloud 고객이 클러스터에 접속하기 어려워졌고, 로드 밸런서에서 HTTP 5xx 오류가 늘었다. 고객 대부분은 Kibana 에도 접속하지 못했고, Elastic Cloud User Console 은 배포 목록을 볼 때 타임아웃이 늘었다.

    촉발

    2019년 2월 4일 AWS us-east-1 리전에서 조정 계층의 ZooKeeper 를 정기 패치하면서 02:25~02:45 에 앙상블 멤버 두 대를 패치한 호스트로 바꿨다.

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

    Elastic 은 02:50 UTC 에 로드 밸런서에서 HTTP 5xx 오류가 늘어난 것을 확인했다.

    조치
    • 03:22 와 06:00 에 클라이언트 연결 문제를 줄이려고 내부 서비스를 일괄 재시작했다.
    • 04:39 에 클라이언트 연결을 끊어 앙상블을 떼어 놓고 시스템을 안정시켰다.
    • 04:46 에 호스트가 불안정해지자 남은 앙상블 멤버의 롤백을 시작했다.
    • 05:25 에 호스트가 불안정해 두 번째 앙상블 멤버도 롤백하기 시작했다.
    • runc 버그로 응답하지 않게 된 ZooKeeper 앙상블 멤버 두 대를 재부팅했다.
    • 가능한 곳에서 클라이언트 부하를 걷어 내 앙상블이 안정될 시간을 준 뒤, 클라이언트 부하를 조금씩 다시 들여 쿼럼을 다시 세웠다.
    • 프록시가 쓰는 ZooKeeper observer 계층의 initLimit 설정을 늘려 observer 계층을 안정시켰다.
    • 늘어난 Elasticsearch 클러스터 트래픽을 받도록 프록시를 키우고 대수를 늘렸다.
    • 내부 프록시 컨테이너와 Kibana 인스턴스를 재시작하고 sysctl 한도를 거는 런북을 만들어 적용했다.
    후속 조치
    • ZooKeeper 앙상블이 담는 데이터셋을 60% 넘게 줄였다.
    • 정상으로 표시된 프록시 노드가 로드 밸런싱 대상에 들어가는 데 필요한 헬스 체크 횟수와 간격을 줄였다.
    • 프록시 헬스 체크에서 ZooKeeper 연결 여부를 빼, 초기화를 마친 프록시가 ZooKeeper 상태 때문에 비정상이 되지 않게 한다.
    • 프록시 서비스를 ZooKeeper 상태에서 떼어 낸 v2 구조의 프록시 계층을 운영 리전에서 카나리로 시험한다.
    • 내부 로깅을 늘리고 ZooKeeper 프로세스, JVM, 컨테이너와 호스트 시스템의 지표를 더해 ZooKeeper 의 관측성을 높인다.
    • Kibana 의 경로 탐색 방식을 더 튼튼하게 만든다.
    • 가용성 사고 중에 Kibana 가 내부 HTTP 요청을 몇 배로 늘려 보내는 문제를 찾아 고친다.
    • Kibana 의 연결 누수 문제를 찾아 고친다.
    • 내부 모니터링 에이전트가 지터를 넣은 백오프를 제대로 쓰지 않던 문제를 찾아 완화했다.
    • 문제가 생겨도 덜 중요한 시간대에 드러나도록, 유지보수 일정표를 정식으로 만들어 리전마다 정한 시간대에만 작업하게 했다.
    • 조정 계층의 정기 유지보수를 다루는 런북에 더 나은 판단 기준표를 넣는다.
    • 지원 창구와 상태 페이지로 나가는 안내를 두고 지원 리더십 팀과 피드백 루프를 만들었다.
    교훈

    서비스 지표가 호스트를 정상으로 보고해 유지보수를 이어 가도 된다는 신호를 줬지만, 그 지표로는 개별 호스트와 조정 계층 전체의 상태를 충분히 알 수 없었다. 다른 플랫폼 구성 요소가 조정 계층에 의존해서 조정 계층의 불안정과 쿼럼 상실이 큰 서비스 중단으로 번졌다. 원인을 찾는 동안 관련 없는 문제들을 만나 해결이 더 늦어졌고, 하나하나는 성공한 완화 조치도 장애의 규모 때문에 한동안 효과가 없었다.

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

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

원인별2