Incident Library

IL-0587 Elastic · 2019-01-18databaseawsnetworking

Elastic Cloud AWS eu-west-1 리전의 클러스터 접속이 약 3시간 심하게 저하되고 20분 동안 완전히 끊겼다

Elastic Cloud 의 리전마다 백엔드는 세 계층으로 이루어진다. allocator 계층은 Elasticsearch 와 Kibana 인스턴스를 올리는 호스트다. 조정 계층은 3노드 Apache ZooKeeper 앙상블이고, 시스템 상태와 각 클러스터 노드와 Kibana 인스턴스의 실제 위치를 담고 있다. 프록시·라우팅 계층은 클러스터의 가상 호스트 이름을 보고 트래픽을 보내고, 그 앞에는 여러 프록시 인스턴스로 부하를 나누는 로드 밸런서가 있다. 프록시는 Apache Curator 프레임워크로 ZooKeeper 에 직접 붙는 클라이언트다. 프록시는 모든 배포와 그 노드를 나타내는 znode 하위 트리 전체를 TreeCache 로 감시한다.

TreeCache 는 ZooKeeper 와의 연결이 끊겼다가 다시 붙으면 미러 트리 전체를 돌면서 노드마다 데이터를 다시 읽고 watch 를 다시 거는 요청을 한꺼번에 큰 묶음으로 보낸다. TreeCache 하나에 znode 가 수만 개일 수 있고, 새로 고침 도중 연결이 또 끊기면 같은 묶음을 다시 보낸다. 클라이언트는 정해진 시간 안에 heartbeat 를 받지 못하면 연결이 끊긴 것으로 보므로, ZooKeeper 서버가 과부하로 긴 GC 멈춤을 겪어도 연결이 불안정해진다. 그러면 프록시가 요청을 쏟아내 서버의 요청 큐가 차고 GC 가 더 나빠진다. 서버가 응답을 못 보내는 사이에는 클라이언트의 크기 제한 없는 송신 큐에 요청이 쌓여 클라이언트가 메모리 부족에 빠진다. 이번 장애에서는 09:09 UTC 에 리더 서버의 CPU 가 높은 임계치에 닿아 클라이언트 연결이 끊겼고, 09:35 UTC 부터 프록시가 쌓인 새로 고침 요청 때문에 자원이 바닥나 메모리 부족 상태가 됐다. 이 악순환이 12:42 UTC 의 완전 중단으로 이어졌다.

SRE 들은 12:42 UTC 부터 13:02 UTC 까지의 완전 중단 동안 프록시 계층을 수직과 수평으로 늘리고, 리더 선출을 일으켜 ZooKeeper 앙상블을 안정시켰다. 13:03 UTC 에 클러스터 가용성이 돌아왔고, 지켜보는 시간을 거친 뒤 장애를 해결로 닫았다. Elastic 은 사고 몇 달 전부터 TreeCache 와 API 가 호환되도록 새로 쓴 TreeWatcher 를 만들고 있었다. TreeWatcher 는 재개된 세션에서는 트리를 새로 고치지 않고, 부모 노드의 응답을 받은 뒤에만 자식 노드의 요청을 보낸다. 또 새로 고침 도중 세션을 잃으면 진행 중인 새로 고침을 취소하고 새로 시작한다. Elastic 은 TreeWatcher 를 2018년 12월부터 관리 플레인과 컨트롤 플레인, 그다음 데이터 플레인 순서로 배포하고 있었고, 프록시 계층의 전환은 2019년 1월 21일 주로 잡혀 있었다.

심각도
–
영향 범위
Access to Elastic Cloud deployments (Elasticsearch clusters and Kibana instances): severely degraded for about 3 hours, and all deployments in the region unavailable for about 20 minutes
영향 사용자
Elastic Cloud customers with deployments in AWS eu-west-1
지역
AWS eu-west-1 (Ireland)
감지까지
26m
복구까지
3h 54m

증상

2019년 1월 18일 09:35 UTC 에 Elastic Cloud 의 당번 SRE 들이 AWS eu-west-1 리전 조정 계층의 서비스 저하 알림을 받았다. 10:08 UTC 무렵부터 이 리전에 배포를 둔 고객은 약 3시간 동안 자기 클러스터에 접속하기가 매우 어려워졌다.

조정 계층은 3노드 Apache ZooKeeper 앙상블이다. 09:09 UTC 에 이 앙상블의 리더 서버에 CPU 부하가 크게 걸려 높은 CPU 임계치에 닿았고, ZooKeeper 클라이언트들의 연결이 끊기기 시작했다.

트래픽을 각 클러스터 노드로 보내는 프록시·라우팅 계층은 ZooKeeper 와의 연결이 붙었다 끊겼다를 반복했고, 프록시가 쓰는 클라이언트 라이브러리는 이 상황을 제대로 다루지 못했다. 프록시는 연결이 다시 붙을 때마다 큰 묶음의 데이터 새로 고침 요청을 ZooKeeper 로 보냈고, 응답을 받지 못한 요청이 프록시 안에 쌓여 메모리 부족 오류가 났다.

장애는 시간이 갈수록 나빠졌다. 10:08 UTC 에 프록시·라우팅 계층이 저하 상태에 들어갔고 10:30 UTC 부터 더 나빠졌다. 12:42 UTC 부터 13:02 UTC 까지 20분 동안 리전의 모든 배포를 쓸 수 없었고, 13:03 UTC 에 클러스터 가용성이 돌아왔다.

SRE 들은 클라이언트가 다시 연결하지 못하게 막고 초기화 단계를 다시 밟게 했다. 그러나 이 조치로는 ZooKeeper 쿼럼이 안정되지 않았다.

증상 데이터베이스 과부하서비스 중단OOMKilled

원인

촉발
09:09 UTC 에 ZooKeeper 앙상블 리더 서버의 CPU 사용량이 높은 임계치에 닿으면서 클라이언트 연결이 끊긴 것이 시작이었다.

감지

09:35 UTC 에 당번 SRE 들이 조정 계층의 서비스 저하 알림을 받았고, 내부 절차에 따라 운영 장애를 열었다.

조치

후속 조치

교훈

–

출처

관련 사례

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

kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이 사례와 같은 상태를 점검합니다. 이 사례의 구성 요소: 코디네이션 키-값 저장소, 서비스 디스커버리. 점검 항목의 근거는 이 사례 같은 공개 보고서입니다.

AI 도구와 스크립트용

API 는 키가 필요 없습니다. MCP 서버는 search_incidents, get_incident, list_incidents, get_topic, vocab 도구를 내놓습니다. 사용법은 API 와 MCP.