들어가며: 장애가 오히려 모니터링을 멈추게 한다면?
운영 중인 시스템에 장애가 발생하면, 엔지니어가 가장 먼저 하는 일은 대시보드를 켜고 알람을 확인하는 것입니다. 그런데 만약 그 대시보드와 알람 시스템이 지금 다운된 바로 그 인프라에 의존하고 있다면 어떨까요? 모니터링이 블라인드 되는 순간, 원인 분석은 커녕 현재 상황조차 파악할 수 없게 됩니다.
에어비앤비(Airbnb)의 옵저버빌리티 팀은 바로 이 문제에 직면했습니다. 수천 개의 서비스가 공유 쿠버네티스(Kubernetes)와 Istio 서비스메시 위에서 동작하는 환경에서, 메트릭 파이프라인이 바로 그 공유 인프라에 의존하고 있었기 때문입니다.
이 글에서는 에어비앤비가 어떻게 이 '순환 의존성(circular dependency)'을 식별하고, 컴퓨팅/네트워킹/메타 모니터링 세 가지 레이어에서 단계적으로 해결했는지 상세히 소개합니다. 단순한 아키텍처 개선이 아니라, '모니터링은 모니터링 대상보다 더 높은 가용성을 가져야 한다' 는 원칙을 실천한 사례입니다.

순환 의존성: 옵저버빌리티의 숨은 리스크
에어비앤비의 플랫폼 팀은 개발자들이 최소한의 마찰로 서비스를 배포/운영할 수 있도록 공유 인프라(쿠버네티스, 서비스메시 등)를 제공합니다. 문제는 옵저버빌리티 스택 자체가 그 공유 인프라 위에 구축되어 있었다는 점입니다.
graph TD
A[서비스 A] -->|메트릭 전송| B[공유 쿠버네티스]
C[서비스 B] -->|메트릭 전송| B
D[모니터링 시스템] -->|메트릭 수집| B
B -->|장애 발생| D
D -->|알람 중단| E[엔지니어]
E -->|장애 원인 파악 불가| F[블라인드]
이 구조의 문제는 명확합니다: 모니터링 시스템이 다운된 인프라의 도움을 받아야만 동작할 수 있다면, 장애 상황에서 가장 필요한 순간에 시야를 잃게 됩니다.
해결 원칙: 단순하지만 강력한
에어비앤비 팀의 접근법은 원칙적으로 단순했습니다.
모든 내부 고객(internal customer)에게 중복된(redundant), 고가용성의 메트릭 수집 경로를 제공하라.
단, 여기서 '내부 고객'의 범위를 명확히 했습니다. 자신들이 보장해야 할 시스템(옵저버빌리티 팀이 직접 관리하는 서비스)에 대해서만 중복성을 설계하고, 외부 장애 도메인(fault domain)까지 책임지려 하지 않았습니다.
1. 컴퓨팅 레이어 분리: 전용 클러스터의 절충점
에어비앤비 클라우드 팀은 전체 쿠버네티스 클러스터를 관리합니다. 옵저버빌리티 팀은 자신의 워크로드를 어디에서 실행할지 두 가지 극단적인 선택지 사이에서 고민했습니다.
| 선택지 | 장점 | 단점 |
|---|---|---|
| 공용 프로덕션 클러스터에서 실행 | 운영 부담 최소화 | 모니터링 대상과 강결합 → 순환 의존성 |
| 자체 쿠버네티스 클러스터 운영 | 완벽한 격리 | 깊은 운영 전문성 필요, 유지보수 부담 |
에어비앤비가 선택한 '딱 맞는' 해결책은 전용 쿠버네티스 클러스터였습니다.
- 이 클러스터는 프로덕트나 다른 인프라 애플리케이션과 공유되지 않습니다.
- 하지만 여전히 클라우드 팀이 관리합니다. 즉, 운영 부담은 클라우드 팀이 지되, 장애 도메인은 분리된 것입니다.
변경 관리도 철저히 했습니다. 한 번에 하나의 주요 변경만 적용하고, 낮은 우선순위 클러스터에서 먼저 검증한 뒤 운영 클러스터에 반영했습니다. 국내 SI/클라우드 환경에서도 '전용 클러스터'를 두는 것은 추가 비용이 들 수 있지만, 장애 상황에서의 가시성(visibility)을 비용으로 환산하면 충분히 투자할 가치가 있는 영역입니다.

2. 네트워킹 레이어 분리: 서비스메시에서 벗어나기
옵저버빌리티 트래픽은 일반 비즈니스 트래픽과 성격이 완전히 다릅니다.
- 볼륨: 옵저버빌리티 데이터가 비즈니스 트래픽보다 훨씬 많습니다.
- 우선순위: 장애 상황에서 메트릭은 가장 중요한 데이터 중 하나입니다.
에어비앤비는 Istio를 서비스메시로 사용하고 있었는데, 두 가지 문제가 있었습니다.
- 순환 의존성: 서비스메시의 메트릭을 수집하기 위해 동일한 서비스메시에 의존해야 함.
- 트래픽 혼잡: 텔레메트리 스파이크가 공유 대역폭을 점유하여 비즈니스 트래픽까지 영향.
해결: 커스텀 Envoy 프록시 레이어
에어비앤비는 서비스메시와 독립적인 커스텀 Layer 7 네트워크 인그레스 레이어를 구축했습니다. Envoy 기반으로 동작하며, 로드밸런싱과 라우팅을 전담합니다.
# 의사 코드: 헤더 기반 라우팅 예시
# 실제 Envoy 설정의 개념적 표현
def route_request(request):
# 모든 요청은 tenant 헤더를 포함해야 함
tenant = request.headers.get("X-Tenant-Id")
if not tenant:
return reject_request("Missing tenant header")
# 서비스 이름을 기반으로 백엔드 클러스터 매핑
backend_cluster = service_to_cluster_map.get(request.service_name)
if not backend_cluster:
return reject_request("Unknown service")
# 읽기/쓰기 요청 분기
if request.method == "WRITE":
return route_to_primary(backend_cluster, request)
else:
return route_to_replica(backend_cluster, request)
이 커스텀 레이어를 통해 얻은 이점:
- 격리: 서비스메시 장애가 메트릭 수집에 영향을 주지 않음.
- 우선순위 제어: 텔레메트리 트래픽과 비즈니스 트래픽을 명확히 분리.
- 유연한 기능: 메트릭 미러링, 세분화된 접근 제어 등 커스텀 기능 구현 가능.
국내 클라우드 환경 팁: Istio나 Linkerd 같은 서비스메시를 이미 사용 중이라면, 옵저버빌리티 트래픽만이라도 별도의 네트워크 경로(예: dedicated Envoy proxy)로 분리하는 것을 고려해보세요. 특히 대규모 Kafka 클러스터나 Prometheus를 운영한다면 더욱 필요합니다.
3. 메타 모니터링: 모니터를 모니터링하는 방법
컴퓨팅과 네트워킹 레이어를 안정화한 후, 자연스러운 질문이 생겼습니다. "그럼 이 모니터링 시스템 자체가 잘 동작하는지는 어떻게 알지?"
에어비앤비는 메타 모니터링(meta-monitoring) 레이어를 추가했습니다.
- 별도의 Prometheus 인스턴스가 옵저버빌리티 스택 전용으로 실행됩니다.
- 이 Prometheus는 옵저버빌리티 스택과 다른 가용존(AZ), 다른 쿠버네티스 노드에 배치되어 상관 장애(correlated failure)를 방지합니다.
- Alertmanager와 Prometheus 쌍이 동일한 공유 인프라에 배치되지 않도록 합니다.
데드맨 스위치(Dead Man's Switch)
메타 모니터링이 다운되면? 무한 회귀(infinite regress)를 피하기 위해 데드맨 스위치를 사용합니다.
# Prometheus alerting rule 예시 (데드맨 스위치)
groups:
- name: meta-monitoring
rules:
- alert: DeadMansSwitch
expr: vector(1)
labels:
severity: none
annotations:
summary: "Dead Man's Switch - always firing if Prometheus is healthy"
동작 방식:
- Prometheus가 정상적으로 스크래핑 중이면
DeadMansSwitch알림이 항상 발생(firing) 합니다. - Alertmanager는 이 알림을 지속적으로 AWS SNS 토픽으로 전송합니다.
- CloudWatch 알람이 SNS 메시지 수신률을 모니터링합니다.
- 메시지가 중단되면(Prometheus 다운, 스크래핑 중단, Alertmanager 장애 등) 온콜(on-call) 엔지니어에게 페이지가 전송됩니다.
이 구조는 단순하지만, '모니터링의 모니터링'이 침묵하는 장애(silent failure)에 빠지는 것을 방지합니다.

결론: 모니터링을 프로덕션 시스템으로 대우하라
에어비앤비의 사례는 단순한 기술적 개선을 넘어, 옵저버빌리티를 하나의 프로덕션 시스템으로 바라보는 관점의 전환을 보여줍니다.
핵심 원칙: 모니터링 시스템의 가용성은 모니터링 대상의 가용성을 반드시 초과해야 한다.
실무에 적용할 수 있는 체크리스트
- 의존성 지도 그리기: 내 모니터링 시스템이 어떤 인프라에 의존하는지 명시적으로 문서화하세요.
- 순환 의존성 찾기: 모니터링 대상이 되는 시스템이 모니터링 파이프라인의 필수 구성 요소인지 확인하세요.
- 장애 도메인 격리: 최소한 모니터링 전용 클러스터나 네트워크 경로를 하나는 확보하세요.
- 메타 모니터링 구축: '모니터가 살아있는지'를 확인하는 별도의 경로를 만들고, 데드맨 스위치로 최종 안전장치를 마련하세요.
함께 보면 좋은 글
- React 동적 폼, 컴포넌트 vs 스키마 실무에서 고민해야 할 선택지 — 인프라가 아닌 프론트엔드 영역에서의 의존성 관리 인사이트
- 스포티파이가 1,800개 파이프라인을 6개월 만에 옮긴 비결 Honk 에이전트와 Fleet Management 실전 사례 — 대규모 마이그레이션에서의 운영 신뢰성 확보 전략
다음 단계 학습 방향
- Prometheus Operator와 VictoriaMetrics를 활용한 메트릭 파이프라인 이중화
- Grafana Mimir 또는 Thanos를 이용한 장기 메트릭 저장소의 고가용성 설계
- OpenTelemetry로 트레이스/메트릭/로그를 통합 수집할 때의 의존성 관리 패턴
이 글이 도움이 되셨다면, 여러분의 프로젝트에서도 '모니터링의 모니터링'을 한 번 고민해보세요. 장애는 언제나 예상치 못한 순간에 찾아오니까요 😅