들어가며: 장애가 오히려 모니터링을 멈추게 한다면?

운영 중인 시스템에 장애가 발생하면, 엔지니어가 가장 먼저 하는 일은 대시보드를 켜고 알람을 확인하는 것입니다. 그런데 만약 그 대시보드와 알람 시스템이 지금 다운된 바로 그 인프라에 의존하고 있다면 어떨까요? 모니터링이 블라인드 되는 순간, 원인 분석은 커녕 현재 상황조차 파악할 수 없게 됩니다.

에어비앤비(Airbnb)의 옵저버빌리티 팀은 바로 이 문제에 직면했습니다. 수천 개의 서비스가 공유 쿠버네티스(Kubernetes)와 Istio 서비스메시 위에서 동작하는 환경에서, 메트릭 파이프라인이 바로 그 공유 인프라에 의존하고 있었기 때문입니다.

이 글에서는 에어비앤비가 어떻게 이 '순환 의존성(circular dependency)'을 식별하고, 컴퓨팅/네트워킹/메타 모니터링 세 가지 레이어에서 단계적으로 해결했는지 상세히 소개합니다. 단순한 아키텍처 개선이 아니라, '모니터링은 모니터링 대상보다 더 높은 가용성을 가져야 한다' 는 원칙을 실천한 사례입니다.

근거자료: Airbnb Engineering Blog 원문

Airbnb observability metrics pipeline architecture with circular dependency diagram

순환 의존성: 옵저버빌리티의 숨은 리스크

에어비앤비의 플랫폼 팀은 개발자들이 최소한의 마찰로 서비스를 배포/운영할 수 있도록 공유 인프라(쿠버네티스, 서비스메시 등)를 제공합니다. 문제는 옵저버빌리티 스택 자체가 그 공유 인프라 위에 구축되어 있었다는 점입니다.

graph TD
    A[서비스 A] -->|메트릭 전송| B[공유 쿠버네티스]
    C[서비스 B] -->|메트릭 전송| B
    D[모니터링 시스템] -->|메트릭 수집| B
    B -->|장애 발생| D
    D -->|알람 중단| E[엔지니어]
    E -->|장애 원인 파악 불가| F[블라인드]

이 구조의 문제는 명확합니다: 모니터링 시스템이 다운된 인프라의 도움을 받아야만 동작할 수 있다면, 장애 상황에서 가장 필요한 순간에 시야를 잃게 됩니다.

해결 원칙: 단순하지만 강력한

에어비앤비 팀의 접근법은 원칙적으로 단순했습니다.

모든 내부 고객(internal customer)에게 중복된(redundant), 고가용성의 메트릭 수집 경로를 제공하라.

단, 여기서 '내부 고객'의 범위를 명확히 했습니다. 자신들이 보장해야 할 시스템(옵저버빌리티 팀이 직접 관리하는 서비스)에 대해서만 중복성을 설계하고, 외부 장애 도메인(fault domain)까지 책임지려 하지 않았습니다.

1. 컴퓨팅 레이어 분리: 전용 클러스터의 절충점

에어비앤비 클라우드 팀은 전체 쿠버네티스 클러스터를 관리합니다. 옵저버빌리티 팀은 자신의 워크로드를 어디에서 실행할지 두 가지 극단적인 선택지 사이에서 고민했습니다.

선택지장점단점
공용 프로덕션 클러스터에서 실행운영 부담 최소화모니터링 대상과 강결합 → 순환 의존성
자체 쿠버네티스 클러스터 운영완벽한 격리깊은 운영 전문성 필요, 유지보수 부담

에어비앤비가 선택한 '딱 맞는' 해결책은 전용 쿠버네티스 클러스터였습니다.

  • 이 클러스터는 프로덕트나 다른 인프라 애플리케이션과 공유되지 않습니다.
  • 하지만 여전히 클라우드 팀이 관리합니다. 즉, 운영 부담은 클라우드 팀이 지되, 장애 도메인은 분리된 것입니다.

변경 관리도 철저히 했습니다. 한 번에 하나의 주요 변경만 적용하고, 낮은 우선순위 클러스터에서 먼저 검증한 뒤 운영 클러스터에 반영했습니다. 국내 SI/클라우드 환경에서도 '전용 클러스터'를 두는 것은 추가 비용이 들 수 있지만, 장애 상황에서의 가시성(visibility)을 비용으로 환산하면 충분히 투자할 가치가 있는 영역입니다.

Engineer monitoring distributed system with multiple Kubernetes clusters and service mesh Development Concept Image

2. 네트워킹 레이어 분리: 서비스메시에서 벗어나기

옵저버빌리티 트래픽은 일반 비즈니스 트래픽과 성격이 완전히 다릅니다.

  • 볼륨: 옵저버빌리티 데이터가 비즈니스 트래픽보다 훨씬 많습니다.
  • 우선순위: 장애 상황에서 메트릭은 가장 중요한 데이터 중 하나입니다.

에어비앤비는 Istio를 서비스메시로 사용하고 있었는데, 두 가지 문제가 있었습니다.

  1. 순환 의존성: 서비스메시의 메트릭을 수집하기 위해 동일한 서비스메시에 의존해야 함.
  2. 트래픽 혼잡: 텔레메트리 스파이크가 공유 대역폭을 점유하여 비즈니스 트래픽까지 영향.

해결: 커스텀 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"

동작 방식:

  1. Prometheus가 정상적으로 스크래핑 중이면 DeadMansSwitch 알림이 항상 발생(firing) 합니다.
  2. Alertmanager는 이 알림을 지속적으로 AWS SNS 토픽으로 전송합니다.
  3. CloudWatch 알람이 SNS 메시지 수신률을 모니터링합니다.
  4. 메시지가 중단되면(Prometheus 다운, 스크래핑 중단, Alertmanager 장애 등) 온콜(on-call) 엔지니어에게 페이지가 전송됩니다.

이 구조는 단순하지만, '모니터링의 모니터링'이 침묵하는 장애(silent failure)에 빠지는 것을 방지합니다.

Dead man switch meta-monitoring alerting system for observability stack Algorithm Concept Visual

결론: 모니터링을 프로덕션 시스템으로 대우하라

에어비앤비의 사례는 단순한 기술적 개선을 넘어, 옵저버빌리티를 하나의 프로덕션 시스템으로 바라보는 관점의 전환을 보여줍니다.

핵심 원칙: 모니터링 시스템의 가용성은 모니터링 대상의 가용성을 반드시 초과해야 한다.

실무에 적용할 수 있는 체크리스트

  1. 의존성 지도 그리기: 내 모니터링 시스템이 어떤 인프라에 의존하는지 명시적으로 문서화하세요.
  2. 순환 의존성 찾기: 모니터링 대상이 되는 시스템이 모니터링 파이프라인의 필수 구성 요소인지 확인하세요.
  3. 장애 도메인 격리: 최소한 모니터링 전용 클러스터나 네트워크 경로를 하나는 확보하세요.
  4. 메타 모니터링 구축: '모니터가 살아있는지'를 확인하는 별도의 경로를 만들고, 데드맨 스위치로 최종 안전장치를 마련하세요.

함께 보면 좋은 글

다음 단계 학습 방향

  • Prometheus Operator와 VictoriaMetrics를 활용한 메트릭 파이프라인 이중화
  • Grafana Mimir 또는 Thanos를 이용한 장기 메트릭 저장소의 고가용성 설계
  • OpenTelemetry로 트레이스/메트릭/로그를 통합 수집할 때의 의존성 관리 패턴

이 글이 도움이 되셨다면, 여러분의 프로젝트에서도 '모니터링의 모니터링'을 한 번 고민해보세요. 장애는 언제나 예상치 못한 순간에 찾아오니까요 😅

본 콘텐츠는 신뢰할 수 있는 출처를 바탕으로 AI 도구를 활용하여 초안이 작성되었으며, 편집자의 검토를 거쳐 발행되었습니다. 전문가의 조언을 대체하지 않습니다.