Skip to content
us‑east‑1 장애 분석: 2025년 10월 DynamoDB DNS 실패와 EC2 연쇄 고장

us‑east‑1이 재채기할 때: 10월 19–20일 AWS 장애 현장 가이드

Updated on

2025년 10월 19–20일 발생한 AWS us‑east‑1 장애의 전체 분석. DynamoDB의 DNS 레이스 컨디션이 EC2, Lambda, NLB 등으로 어떻게 연쇄 고장을 일으켰는지와 실용적인 예방 전략.

사건 발생 일시: 2025‑10‑19 → 10‑20 (태평양 시간) 주요 촉발 원인: DynamoDB 지역 엔드포인트에 대한 DNS 자동화 결함 영향 범위: DynamoDB → EC2 인스턴스 시작 → Network Manager → NLB → (Lambda, STS, IAM 로그인, Redshift, ECS/EKS/Fargate, Connect) — us‑east‑1


요약 (바쁜 분들을 위한 한눈 정리)

  • 무엇이 시작했나 (10월 19일 23:48): DynamoDB의 자동 DNS 관리에서 발생한 레이스 컨디션으로 지역 엔드포인트 dynamodb.us-east-1.amazonaws.com빈(empty) 레코드로 바뀌었습니다. us‑east‑1에서 DynamoDB에 대해 새로운 연결을 시도하는 모든 요청은 DNS 조회에 실패했습니다.
  • DynamoDB 주요 복구 (10월 20일 02:25–02:40): AWS가 올바른 DNS 레코드를 복원했고, 캐시된 DNS 항목이 만료되면서 고객 복구가 진행되었습니다.
  • 왜 여기서 끝나지 않았나: EC2의 내부 제어 플레인은 호스트(“droplet”) 리스에 DynamoDB를 사용합니다. DNS 장애 동안 리스들이 만료되어 Droplet Workflow Manager의 **혼잡성 붕괴(congestive collapse)**와 Network Manager의 **작업 적체(backlog)**가 발생했습니다. 새로운 EC2 인스턴스 시작이 오류를 내거나 네트워크 상태 없이 올라왔습니다.
  • 로드밸런서 영향 (05:30–14:09): Network Load Balancer(NLB) 헬스체크가 네트워크 전파 지연으로 플래핑하면서 일부 용량이 간헐적으로 제거되어 연결 오류가 발생했습니다.
  • 완전 정상화 시점: 대부분 서비스는 10월 20일 오후 초에 안정화되었고, EC2 교체로 인한 Redshift 잔여처리는 10월 21일 04:05에 마무리되었습니다.

일련의 사건을 다이어그램식 타임라인으로 요약 (PDT)

시간 범위 (10월 19–20일)고객이 본 증상내부적으로 실제로 깨진 것
23:48 → 02:40us‑east‑1에서 DynamoDB API 오류; 새로운 연결 시도는 실패DNS Planner/Enactor의 레이스로 DynamoDB 지역 엔드포인트에 대해 빈 Route 53 레코드가 생성됨; 사람이 수동으로 02:25에 복구; 캐시 만료로 02:40까지 클라이언트가 복구됨
02:25 → 13:50EC2: 인스턴스 시작 오류(“insufficient capacity” / “request limit exceeded”), API 지연 증가DWFM이 물리 호스트(“droplets”)에 대한 리스를 잃음; 복구 시 대량의 재리스 작업이 발생하여 큐가 붕괴됨. 스로틀링과 선택적 재시작(04:14부터)으로 캐치업 수행; 05:28에 리스 복구; 스로틀 완화 11:23; 완전 복구 13:50
05:30 → 14:09NLB: 일부 로드밸런서에서 연결 오류 증가Network Manager가 인스턴스의 네트워크 상태를 완전히 전파하지 못해 NLB 헬스체크가 플래핑; 자동 AZ 장애전환이 용량을 제거함; 09:36: 용량 진동을 멈추기 위해 자동 장애전환 비활성화; 14:09에 다시 활성화
서비스별 잔영(에코)Lambda(최대 14:15), STS(최대 09:59), 콘솔 IAM 로그인(최대 01:25), ECS/EKS/Fargate(최대 14:20), Connect(최대 13:20), Redshift 쿼리/제어플레인(대부분 02:21까지, 일부 컴퓨트는 10월 21일 04:05까지)각 서비스는 DynamoDB, EC2 시작 용량, NLB 헬스, 혹은 IAM/STS와 다른 결합을 가지고 있어 증상 도달 및 해소 시점이 상이함

핵심 개념 두 분 정리 (초보 독자용)

DNS (도메인 네임 시스템)
DNS는 인터넷의 전화번호부라고 생각하면 됩니다. 이름을 물어보면 어디로 연결할지(IP)를 반환합니다. 초대형 인프라에서는 DNS 레코드와 헬스체크로 거대한 플릿과 가용 영역 간 트래픽을 조정합니다. 빠르고 범용적이지만 트랜잭션형 데이터베이스는 아니며, 일관성 및 변경 순서 문제는 별도 설계가 필요합니다.

DynamoDB
AWS의 완전관리형 키‑값/NoSQL 데이터베이스입니다. 지연이 매우 낮고 탄력적이며 AWS 자체의 제어 플레인과 메타데이터 저장소로도 광범위하게 사용됩니다. Global Tables는 리전 간 복제를 제공합니다. 만약 앱이나 AWS 서브시스템이 제어 상태(read/write)를 DynamoDB에 의존하는데 접근 불가하면 문제가 누적됩니다.

EC2 & 제어 플레인
EC2는 인스턴스를 물리 호스트(“droplet”) 위에서 실행합니다. 내부 서비스들은 해당 호스트에 대한 리스를 관리하고 네트워크 상태(라우트, 시큐리티 그룹 등)를 전파합니다. 인스턴스 시작은 보통 간단하지만 내부 조정이 불건전하거나 큐가 막히면 어려워집니다.

NLB (Network Load Balancer)
레이어‑4 로드밸런서입니다. 헬스체크를 수행하고 AZ 간 라우팅을 지원합니다. 헬스체크가 플래핑하거나 DNS 기반 실패전환이 과도하면 순간적으로 너무 많은 용량을 제거할 수 있습니다 — 정확히 필요한 순간에 말이죠.


실제로 무엇이 실패했나: DynamoDB DNS 자동화

AWS는 DynamoDB DNS 관리를 두 역할로 나눕니다:

  • DNS Planner: 각 엔드포인트(지역, FIPS, IPv6, 계정별)에 대해 어떤 로드밸런서들을 어떤 가중치로 적용할지 원하는 레코드 집합을 계산합니다.
  • DNS Enactor: 서로 다른 AZ에 세 개의 중복 워커가 그 계획을 Route 53에 적용하며, 각 워커는 트랜잭셔널 업데이트를 수행합니다.

이례적인 경쟁 상황에서 한 Enactor는 느리게 진행되는 동안 다른 Enactor는 더 최신의 계획으로 경쟁했고, 그 과정에서 오래된 세대의 계획을 정리(garbage‑collect)했습니다. 느린 Enactor의 구식 "오래된" 계획이 빠른 Enactor의 정리 이전에 덮어쓰여져 지역 엔드포인트의 모든 IP를 제거하는 원자적 상태를 만들었고, 이로 인해 시스템이 자동 업데이트를 더 이상 진행할 수 없는 상태가 되었습니다. 사람이 개입하여 이를 복구했습니다.

왜 문제가 되었나: 지역 엔드포인트가 사라졌습니다. us‑east‑1에서 DynamoDB에 대해 새로운 DNS 해석을 해야 했던 모든 것이 즉시 실패했습니다. 기존 연결은 일반적으로 계속 동작했습니다.


왜 연쇄적으로 번졌나: 강한 결합과 시간의 방향성

  1. 제어 플레인 결합 (EC2 ⇄ DynamoDB).
    EC2의 Droplet Workflow Manager(DWFM)는 물리 호스트에 대한 리스를 유지합니다. 그 확인이 DynamoDB에 의존합니다. DNS 장애 동안 리스들이 타임아웃되어 droplet들이 새로운 인스턴스 배치에 부적격해졌습니다. DynamoDB가 복구되자 DWFM은 거대한 규모에서 리스를 재확립해야 했고, 큐 타임아웃을 맞아 **혼잡(congestion)**이 발생했습니다.

  2. 네트워크 전파 지연.
    인스턴스가 다시 시작되기 시작했을 때도, Network Manager는 그들의 네트워크 상태를 전파하는 데 적체가 있었습니다. 인스턴스는 네트워크 상태가 완전히 전파되기 전까지 완전한 연결성 없이 올라왔습니다(약 10:36경까지).

  3. 헬스체크 피드백 루프 (NLB).
    불완전한 네트워크 상태의 신규 용량은 비정상으로 보였고, NLB는 노드나 AZ를 철회하여 일시적으로 용량을 축소했습니다. 그 결과 연결 오류가 악화되었습니다. 운영자는 자동 헬스체크 장애전환을 일시 중단해 진동을 멈추고, EC2가 안정된 뒤 재활성화했습니다.

  4. 하류 서비스의 울림(에코).
    Lambda는 동기 호출을 보호하기 위해 특정 경로를 제한했고, STS/IAM 로그인이 불안정해졌다가 복구되었으며, 컨테이너 제어 플레인(ECS/EKS/Fargate)과 Connect는 EC2/NLB 영향의 복합 효과를 받았고, Redshift는 추가 변형이 있었습니다: IAM 기반 쿼리 인증이 잠깐 전역적으로 실패했고 일부 클러스터는 EC2 호스트 교체를 기다리느라 10월 21일까지 걸렸습니다.

“스위스 치즈 모델”을 떠올리신다면 맞습니다 — 여러 얇은 방어선들이 우연히 모두 정렬되며 큰 사고가 났습니다.


복잡계 관점 (왜 “근본 원인”만으론 부족한가)

여러 HN 사용자들이 Richard Cook의 How Complex Systems Fail과 Perrow의 Normal Accidents를 언급했습니다. 이 프레임은 이번 사건에 놀랍도록 잘 맞습니다.

  • 단일 원인은 없다. DNS 레이스가 성냥불을 켰지만, 긴 꼬리는 EC2의 **준안정(metastable)**한 복구 모드와 NLB의 헬스체크 진동에서 왔습니다 — 각각은 개별적으로는 합리적인 설계였지만 스트레스 상황에서 나쁘게 상호작용했습니다.
  • 시스템은 보통 저성능 상태로도 운영된다. Planner/Enactor 재시도, 리스 만료, 적체 등은 시스템이 통상적으로 견디는 마찰들입니다 — 운이 나쁘게 겹쳤습니다.
  • 사람이 안전을 만든다. 자동화가 멈추자 운영자가 수동으로 복구(수동 DNS 복원, DWFM 스로틀링/재시작, NLB 자동 장애전환 비활성화)하여 다시 연결고리를 재구성했습니다.

결론: 버그를 고치는 것도 중요하지만, 작은 실패가 눈덩이처럼 불어나지 않게 하는 **준안정 복구 경로(metastable recovery traps)**와 피드백 루프를 찾아 제거해야 합니다.


AWS가 발표한 변경 사항

  • DynamoDB DNS 자동화: 레이스 버그를 수정하는 동안 전역적으로 자동화를 비활성화; 잘못된 계획 적용/삭제를 방지하는 안전장치 추가 예정.
  • NLB: 헬스체크 장애전환의 **속도 제어(velocity control)**를 추가하여 너무 빠르게 과도한 용량을 제거하지 못하도록 함.
  • EC2: DWFM에 대한 새로운 복구 테스트 스위트 도입; 데이터 전파 시스템 전반에 걸친 큐 인식 스로틀링(queue‑aware throttling) 개선.

이들은 올바른 보완 클래스입니다: 잘못된 쓰기를 방지하고, 자기 치유 속도를 조절하며, 부하 상태에서 복구 경로를 검증하는 것입니다.


여러분이 할 수 있는 조치들 (월요일 아침 체크리스트)

AWS를 바꿀 수 없더라도, 자신 시스템의 충격을 완화할 수 있습니다.

  1. 지역 엔드포인트를 우선 사용하고 us‑east‑1의 숨은 의존성을 제거하세요.
    STS처럼 지역화된 제어 플레인을 제공한다면 사용하세요. 관습적으로 인증이나 메타데이터를 us‑east‑1에 중앙집중하지 마세요.

  2. 중요 제어 상태에는 멀티리전 데이터 접근을 설계하세요.
    DynamoDB Global Tables는 두 번째 리전으로 읽기/쓰기를 페일오버할 수 있게 해줍니다. 코드가 복제 지연을 견디고 이후 조정(reconcile)할 수 있어야 합니다.

  3. 헬스체크 진동에 대해 ‘닫힘(fail‑closed)’ 설계를 하세요.
    자동 장애전환을 댐핑(damping)으로 보호하세요: 연속 실패 횟수, 히스테리시스, 분당 용량 제거 한도 등을 둡니다. 진동을 멈추게 하는 수동 오버라이드 서킷브레이커를 고려하세요.

  4. 의존성 그래프를 명시적으로 만드세요.
    어떤 서비스가 인스턴스 시작/스케일에 필수적인지(인증, 큐, 설정 저장소 등)를 문서화하세요. “X가 2시간 느리거나 사용할 수 없다면?”을 연습하세요.

  5. 준안정 복구(metastable recovery)를 연습하세요.
    데이터 평면만이 아니라 제어 플레인에 대한 카오스 실험:

    • 일부 플릿에서 리스 만료를 시뮬레이션하세요.
    • 네트워크 구성 전파기를 폭주시키세요.
    • 백프레셔와 **스로틀 해제 순서(throttle‑lift sequencing)**를 리허설하세요.
  6. 의도 있는 캐싱을 사용하세요.
    DNS 캐시는 복구 지연을 숨겨주기도 합니다(클라이언트가 TTL 만료를 기다림). 신규 연결을 공격적으로 여는 SDK의 경우 커넥션 풀링지터가 있는 지수 백오프를 사용해 동시 재시도를 피하세요.

  7. “세이프 모드” 룬북을 만드세요.

    • 오류 급증시 동시성 또는 속도 제한을 낮춤.
    • 오토스케일러를 재활성화하기 전에 적재량을 먼저 소화(drain)하도록 우선.
    • 제어 플레인 장애 동안 비용이 큰 백그라운드 작업을 비활성화할 수 있는 피처 플래그 활용.
  8. 자신의 “planner/enactor” 패턴을 보호하세요.
    원하는 상태(desired state)를 생성하고 다른 곳에 적용한다면 다음을 추가하세요:

    • 버전 관리된 계획compare‑and‑swap(비교‑교환) 시맨틱.
    • 마지막으로 알려진 정상 상태를 삭제할 수 없는(cleanup protection) 정리 절차.
    • 엔드포인트당 단일 작성자 리스(single‑writer lease) 또는 작은 시퀀서(벡터 클록 / 단조 증가 카운터).

이번 사건은 “DNS 오용”인가?

그렇지 않습니다. 초대형 환경에서는 모든 클라이언트, 라이브러리, VPC 리졸버가 DNS를 사용하므로 DNS는 사실상 서비스 발견 및 트래픽 스티어링 도구입니다. 문제는 DNS를 사용한 것이 아니라 **동시 쓰기(concurrent writers)**와 **정리(janitor)**가 확실한 순서를 보장하지 못하게 상호작용한 점, 그리고 네트워크 전파 적체 동안 헬스체크 기반 DNS가 너무 빨리 용량을 제거하도록 허용한 점입니다. 이들은 고칠 수 있는 엔지니어링 선택입니다.


용어 사전 (60초 요약)

  • Route 53: AWS의 DNS 및 헬스체크 서비스. 가중치/지연/헬스 기반 라우팅과 트랜잭셔널 레코드 변경을 지원합니다.
  • TTL (time to live): 리졸버가 DNS 응답을 캐시할 수 있는 시간. 짧은 TTL은 장애 전환을 빠르게 하지만 쿼리량을 증폭시킵니다.
  • DWFM (Droplet Workflow Manager): EC2 서브시스템으로 물리 호스트에 대한 리스를 관리합니다.
  • Network Manager: VPC/네트워크 구성(state)을 인스턴스와 네트워크 장비에 전파합니다.
  • Global Tables (DynamoDB): 테이블의 멀티리전 복제 기능으로, 궁극적 일관성(eventual consistency)과 충돌 해결을 제공합니다.

마무리 생각

이번 장애는 “단지 DNS 문제”가 아니었습니다. 그것은 DNS + 제어플레인 복구 + 헬스체크 역학 + 사람의 개입이 결합된 사건으로, 가용성은 개별 구성요소의 특징이 아니라 전체 시스템의 속성임을 상기시켜줍니다. 고무적인 부분은 완화책들이 매우 구체적이라는 점입니다: 계획 적용의 직렬화, 용량 제거 속도의 조절, 부하 상태에서의 복구 경로 압력 테스트. 이런 패턴을 자신의 스택에 옮겨두면 다음 번 us‑east‑1의 재채기 때 필요한 휴지의 수를 크게 줄일 수 있습니다.

📚