Incident Library
적용된 필터 구성 요소코디네이션 키-값 저장소기여 요인수동 조치 악화모두 풀기검색어 없이 필터만 적용한 목록입니다. 최근 사례부터입니다.
추천 필터 검색하면 검색어에서 찾은 분류 값이 여기에 나옵니다.

그래프

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

사례3건

3건 중 1~3번째

  1. 증상

    2021년 10월 28일 13:37 PST 에 Vault 성능이 떨어지고 Consul 서버 한 대의 CPU 부하가 높아졌다. 이때는 플레이어에게 영향이 없었다.

    촉발

    10월 27일 14:00 PST 에 트래픽 라우팅을 맡는 백엔드 서비스에 Consul 의 새 streaming 기능을 켰다. 같은 롤아웃에서 연말 트래픽에 대비해 트래픽 라우팅 노드 수를 50% 늘렸고, 하루 뒤 Consul 성능이 떨어지기 시작했다.

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

    10월 28일 13:37 PST 에 Vault 성능 저하와 Consul 서버 한 대의 높은 CPU 부하를 보고 Roblox 엔지니어들이 조사를 시작했다. Consul 클러스터 지표에서 KV 쓰기 지연이 올라간 것을 확인했다.

    조치
    • 하드웨어 성능 저하를 의심해 Consul 클러스터 노드 한 대를 교체했다.
    • 트래픽 증가를 의심해 Consul 클러스터의 모든 노드를 128코어와 더 빠른 NVME SSD 를 단 서버로 바꿨다.
    • Consul 클러스터 전체를 내리고 장애 시작 무렵인 몇 시간 전 스냅샷으로 상태를 되돌렸으며, iptables 로 접근을 막았다가 천천히 풀었다.
    • 외부 트래픽을 막고, Consul 을 쓰는 서비스 목록을 모아 꼭 필요하지 않은 사용을 끄는 설정을 배포했으며, 서비스 인스턴스를 한 자릿수로 줄이고 헬스 체크 간격을 60초에서 10분으로 늘렸다.
    • 경합이 128코어 서버로 옮긴 탓일 수 있다고 보고 Consul 클러스터를 다시 64코어 서버로 옮겼다.
    • 트래픽 라우팅 노드를 포함한 모든 Consul 시스템에서 streaming 기능을 껐고, 설정이 15:51 PST 에 다 퍼지자 KV 쓰기의 p50 지연이 300ms 로 내려갔다.
    • 느린 리더 문제의 원인을 모르는 채로, 문제가 있는 서버가 리더로 뽑힌 채 남지 않게 막았다.
    • 캐시 시스템을 다시 배포했고, 틀어진 스케줄링 데이터와 끝나지 않는 배포 같은 문제를 밤새 찾아 고쳤다.
    • 장애와 문제 분석 중에 내렸던 서비스들을 알맞은 용량으로 다시 띄우고 제대로 도는지 확인했다.
    • DNS 조정으로 무작위로 고른 일정 비율의 플레이어만 들이고 나머지는 정적 점검 페이지로 보냈으며, 데이터베이스 부하와 캐시 성능을 보며 약 10% 씩 늘렸다.
    후속 조치
    • HashiCorp 는 시험 환경에서 이 경합 문제를 재현하는 새 벤치마크를 만들고 대규모 시험을 늘린다.
    • HashiCorp 는 극한 부하에서도 경합이 생기지 않도록 streaming 시스템의 설계를 고친다.
    • 기존 BoltDB 도구로 데이터베이스를 압축하는 절차를 만들어 배포했고, 이것으로 성능 문제가 풀렸다.
    • 텔레메트리 시스템과 Consul 사이의 순환 의존을 없애, 텔레메트리 시스템이 감시 대상 시스템에 기대지 않게 했다.
    • Consul 과 BoltDB 성능, Roblox 서비스와 Consul 사이의 트래픽 패턴을 더 잘 보이게 텔레메트리를 넓혔고, 이번 장애 상태에 가까워지는 신호에 정밀한 알림을 건다.
    • 백엔드 서비스를 둘 지리적으로 떨어진 데이터센터를 하나 더 세웠고, 데이터센터 안에서 여러 가용 영역으로 옮긴다.
    • 서비스들의 Consul KV 와 헬스 체크 사용을 검토해 일부 핵심 서비스를 전용 클러스터로 나눠 중앙 Consul 클러스터의 부하를 줄였다.
    • Consul KV 를 데이터 저장소로 쓰던 핵심 서비스의 데이터를 더 알맞은 저장 시스템으로 옮긴다.
    • 쓰지 않는 KV 데이터를 대량으로 찾아 지웠고, Consul 성능이 좋아졌다.
    • HashiCorp 와 함께 BoltDB 대신 freelist 가 끝없이 커지는 문제가 없는 후속 라이브러리 bbolt 를 쓰는 새 Consul 버전을 배포한다. 연말 최대 트래픽을 피해 새해로 미뤘고 1분기에 끝낸다.
    • 캐시 배포 방식을 다시 설계해 아무것도 없는 상태에서도 캐시 시스템을 빨리 올릴 수 있게 한다.
    • 오래 멈춘 뒤 큰 작업을 다시 올리기 쉽게 하는 Nomad 개선 몇 가지를 HashiCorp 와 찾았고, 다음 Nomad 업그레이드에서 배포한다.
    • 서버 설정을 더 빨리 바꾸는 방법을 만들어 배포했다.
    • 새 streaming 구현을 Roblox 규모와 부하로 시험한 뒤에 조심스럽게 다시 들인다.
    교훈

    Roblox 는 원인 두 가지가 Consul 구현 깊숙이 묻혀 있어 진단이 어려웠던 것이 장애를 길게 만든 주된 이유라고 봤다. 원인을 보여 줄 모니터링 시스템이 장애가 난 Consul 에 기대고 있어 분석이 크게 막혔다. 모든 백엔드 서비스를 Consul 클러스터 하나에 올린 구성이 이런 장애에 취약했다. HashiCorp 는 Roblox 와 비슷한 규모에서 streaming 을 벤치마크했지만, 이 경합은 스트림 수가 많고 교체가 잦은 조건이 겹칠 때만 나타나 전에는 보지 못했다. 더 빠른 하드웨어는 도움이 되지 않았고 오히려 안정성을 해쳤을 수 있다. 오래 완전히 멈춘 상태에서 서비스를 올리는 데도 캐시 배포와 데우기 때문에 시간이 많이 걸렸다.

  2. 증상

    14:43 UTC 에 네트워크 스위치 하나가 ping 에 응답하지 않는다는 알림이 울리기 시작했다. 장애 동안 API 쿼리 성공률이 한때 75%까지 떨어졌고, 대시보드는 평소보다 최대 80배 느려졌다.

    촉발

    14:43 UTC 에 제어 플레인 데이터 센터의 네트워크 스위치 하나가 일부만 동작하는 상태에 빠졌다. LACP 와 BGP 는 계속 돌았지만 받은 패킷 일부를 전달하지 못했고, 스위치는 6분 뒤 스스로 회복했다.

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

    14:43 UTC 에 스위치가 ping 에 응답하지 않는다는 알림이 울리기 시작했다. 그 뒤 엔지니어들이 주 인증 데이터베이스가 과부하에 걸린 것을 확인했다.

    조치
    • SSL 인증서를 엣지로 보내는 속도와 메일 발송 같은 기능을 줄여 주 인증 데이터베이스가 늘어난 부하를 감당할 여유를 만들었다.
    • 읽기 복제본으로 처리할 수 있는 API 트래픽을 손으로 보조 데이터 센터로 돌렸다. API 가용성이 크게 나아졌다.
    • 대시보드 사용자의 불편이 커지자 인증 호출을 모두 주 데이터 센터로 되돌렸고, 성능이 떨어진 상태에서도 최대한 버티도록 주 데이터베이스를 계속 손봤다.
    • 21:20 UTC 에 첫 데이터베이스 복제본이 다시 만들어지자마자 자동으로 서비스에 투입됐고, 성능이 정상으로 돌아왔다.
    • 줄였던 서비스를 모두 다시 올려 밀린 비동기 처리가 따라잡게 했고, 한동안 지켜본 뒤 장애 종료를 선언했다.
    후속 조치
    • 새 primary 를 승격하면 데이터베이스 복제본을 모두 다시 만들어야 하는 클러스터 관리 시스템의 제약을 고친다. Cloudflare 는 글을 쓸 무렵 이 결함을 이미 고쳤다고 밝혔다.
    • 트래픽을 다른 데이터 센터로 돌려야 할 때 유연하게 대응하지 못하는 사용자 세션 시스템을 다시 설계한다.
    • 자동 복구 조치의 설정 값을 다시 검토한다. 적어도 데이터베이스 하나에서는 복제본을 primary 로 승격하는 절차를 그렇게 빨리 시작하지 않도록 장애 직후 설정을 바꿨다.
    • 이 장애에 얽힌 시스템마다 자기가 의존하는 시스템의 고장을 더 잘 견디도록 계속 조정한다.
    교훈

    모든 시스템에 이중화가 있었지만, 고장 난 시스템들은 완전히 멈추지 않고 성능이 떨어진 채로 동작했다. 그래서 뒤이어 일어난 일들을 미리 모델링하고 예상하기가 훨씬 어려웠다. 1분 만에 복제본을 승격하는 자동 조치는 Cloudflare 가 자랑하던 기능이었지만, 적어도 데이터베이스 하나에서는 그 조치가 원래 문제보다 더 큰 피해를 낼 수 있었다. 대부분의 범용 클러스터 관리 시스템은 비잔틴 장애를 견디는 프로토콜을 쓰지 않고 RAFT 처럼 단순한 프로토콜을 쓴다. 드문 장애 유형에 약하다고 알려진 단순한 프로토콜이 구현과 디버깅이 어려운 복잡한 프로토콜보다 안전한 경우가 많다고 Cloudflare 는 보았다.

  3. 증상

    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 의 연결 누수 문제를 찾아 고친다.
    • 내부 모니터링 에이전트가 지터를 넣은 백오프를 제대로 쓰지 않던 문제를 찾아 완화했다.
    • 문제가 생겨도 덜 중요한 시간대에 드러나도록, 유지보수 일정표를 정식으로 만들어 리전마다 정한 시간대에만 작업하게 했다.
    • 조정 계층의 정기 유지보수를 다루는 런북에 더 나은 판단 기준표를 넣는다.
    • 지원 창구와 상태 페이지로 나가는 안내를 두고 지원 리더십 팀과 피드백 루프를 만들었다.
    교훈

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

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

이 3건에서 가장 많이 나오는 구성 요소: 코디네이션 키-값 저장소, 인메모리 캐시. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.

원인별2