연필로 그린 실패 지도: 한 장짜리 종이 위에 신뢰성 지형을 모두 펼쳐 보기
트레이스, 의존성, 소유 정보를 한데 모아 소프트웨어 시스템의 ‘실패 지도(Failure Atlas)’를 만드는 방법—어디서 문제가 나고, 어떻게 전파되며, 누가 고쳐야 하는지를 한눈에 보이게 한다.
연필로 그린 실패 지도: 한 장짜리 종이 위에 신뢰성 지형을 모두 펼쳐 보기
한 장짜리 종이에 온 세상을 욱여넣는 데에는 묘한 힘이 있습니다.
1960년대, 기계공학자 Theodor Tallian은 베어링과 기어가 어떻게 마모되고 망가지는지를 한 장에 정리한, 거의 손으로 그린 것 같은 촘촘한 지도인 Failure Atlas for Hertz Contact Machine Elements를 발표했습니다. 그 한 장짜리 도표 안에, 접촉면이 망가지는 온갖 방식—피팅(pitting), 크랙(cracking), 스폴링(spalling), 스커핑(scuffing) 등—이 모두 담겨 있었죠. 단순한 표가 아니라, “실패”에 대한 시각적 이론이었습니다.
이렇게 복잡한 것을 한 장짜리 “아틀라스(Atlas)”로 압축해, 무언가가 어떻게 망가지는지를 통째로 보여 주는 발상은, 오늘날 소프트웨어 신뢰성에도 그대로 필요합니다.
이 글에서는 다음을 이용해 여러분의 소프트웨어 시스템에 대한 "연필로 그린 실패 지도(Pencil-Drawn Failure Atlas)"를 만드는 방법을 살펴보겠습니다.
- OpenTelemetry 트레이스로부터 생성한 동적 서비스 의존성 그래프
- 소유권과 컨텍스트 레이어로서의 서비스 카탈로그
- 단층선을 표시해 주는 주석처럼 쓰이는 인시던트(장애) 이력
이 모든 것을 합치면, 무엇이 존재하고, 어떻게 연결되며, 어디서 어떻게 망가지고, 누가 고쳐야 하는지를 보여 주는 하나의 개념적 “한 장짜리”가 됩니다.
실패 지도(Failure Atlas)란 무엇인가?
Tallian의 연구에서 Failure Atlas란 다음을 의미합니다.
- 실패 모드를 담은 단일 시각적 지도
- 동작 조건, 재료, 하중별로 구성
- 지배적인 실패 메커니즘과 트레이드오프를 드러내도록 설계
모든 걸 한 장에 욱여넣는 순간, Tallian은 일종의 냉혹한 명료함을 강제했습니다.
- 모든 디테일을 다 적을 수 없으니, 정말 중요한 것에 우선순위를 둬야 합니다.
- 패턴이 보입니다: "이 구간의 대부분 실패는 이런 식으로 일어난다."
- "이 파라미터를 올리면, 가장 먼저 어디가 어떻게 깨질까?" 같은 질문에 쉽게 답할 수 있습니다.
이 아이디어를 소프트웨어에 그대로 옮겨올 수 있습니다. 표면과 응력 대신, 우리에게는 다음이 있습니다.
- 서비스와 그 사이의 의존성
- 레이턴시, 처리량, 리소스 한계
- 인시던트, 에러율, 연쇄 실패(cascading failures)
소프트웨어용 실패 지도는, 라이브 텔레메트리에 기반하고 소유 정보에 뿌리를 둔 시스템 전체 수준의 실패 지형도입니다.
베어링에서 마이크로서비스까지: 왜 ‘한 장’이 중요한가
현대 시스템은 다음과 같습니다.
- 분산되어 있고
- 여러 언어와 스택이 섞여 있으며
- 수많은 서드파티 의존성을 포함하고
- 끊임없이 변합니다.
그런데 우리가 신뢰성을 이해하는 방식은 보통 이렇게 쪼개져 있습니다.
- 메트릭을 위한 대시보드
- 다른 도구에 있는 로그
- 또 다른 곳에 있는 트레이스
- (어쩌면) 위키 어딘가에 있는 소유 정보
모두가 시스템의 일부분만 봅니다. 전체를 보는 사람은 거의 없습니다.
Failure Atlas는 이런 질문을 던질 수 있는, 하나의 개념적 ‘한 장’을 제공합니다.
- 지금 우리 시스템의 지배적인 실패 모드는 무엇인가?
- 한 서비스의 실패가 다른 서비스로 어떻게 전파되는가?
- 인시던트에서 단골로 등장하는 문제 구역은 어디인가?
- 각 취약 지점의 실제 소유자는 누구인가?
이건 대시보드를 모아 놓는다고 얻을 수 있는 게 아닙니다. 지도가 있어야 보입니다.
동적 의존성 그래프: 실패 지도의 살아 있는 골격
기계 분야에서 Tallian은 접촉면의 형상을 알고 있었습니다. 소프트웨어에서 우리의 "형상"은 서비스 간 통신입니다.
OpenTelemetry 트레이스는 정확히 이 정보를 제공합니다. 서비스에 인스트루먼테이션을 적용하고 트레이스를 수집하면, Failure Atlas의 살아 있는 골격 역할을 하는 동적 서비스 의존성 그래프를 만들 수 있습니다.
트레이스 기반 의존성 그래프가 보여 주는 것
OpenTelemetry 기반의 맵을 이용하면 다음을 볼 수 있습니다.
- 누가 누구를 호출하는지 – 서비스 간 모든 인바운드/아웃바운드 의존성
- 숨겨진 의존성 – 아무도 기억 못하던 “헬퍼” 서비스나 서드파티 API 호출
- 크리티컬 패스 – 사용자 요청의 핫 패스에 놓인 서비스 체인들
- 실시간 변화 – 시스템이 진화하면서 새 서비스와 새 경로가 등장하는 모습
이렇게 되면 개별 스팬의 집합에 불과하던 트레이스가 탐색 가능한 지형이 됩니다.
- “서비스 A에서 500 에러 스파이크가 났다”에서 끝나는 게 아니라, Service A → B → C를 보고, 실제로는 C가 타임아웃 중이라는 걸 알 수 있습니다.
- 어느 팀을 불러야 할지 짐작하는 대신, 콜 그래프에서 정확히 어느 가지가 실패했는지를 볼 수 있습니다.
즉, 의존성 그래프는 시스템의 산과 계곡, 도로를 그려 낸 연필 스케치와 같습니다.
실패 ‘증상’이 아니라, 실패 ‘전파’를 보기
의존성을 먼저 보는 관점의 가장 큰 이점은 실패가 어떻게 퍼지는지를 이해하는 데 있습니다.
간단한 시나리오를 생각해 보겠습니다.
- 백그라운드 잡 서비스가 서드파티 결제(billing) 프로바이더 호출에서 타임아웃이 나기 시작합니다.
- 그 결과 결제 파이프라인에 레이턴시가 붙습니다.
- 그 여파로 체크아웃 요청이 쌓여 갑니다.
- 프론트엔드 사용자는 느리거나 실패하는 체크아웃을 보게 됩니다.
서비스별 메트릭만 본다면, 이런 식으로 떨어져 있는 증상만 보입니다.
- 프론트엔드: 응답 시간 상승
- 체크아웃 API: 큐 길이 증가
- 빌링 워커: 타임아웃 증가
반면, 트레이스 데이터를 의존성 그래프 위에 얹어 보면, 실패가 하나의 경로로 보입니다.
Frontend → Checkout API → Billing worker → Billing provider
이제 Failure Atlas는 어디가 깨지는지만이 아니라, 깨짐이 어떻게 이동하는지까지 보여 줍니다.
좋은 지도라면 마땅히 그래야 하듯, 단순한 위치 목록이 아니라 경로의 네트워크가 되는 것입니다.
소유권을 더하기: 사람 레이어로서의 서비스 카탈로그
도로 지도는 유용합니다. 하지만 각 도로를 누가 관리하는지까지 적힌 지도는 훨씬 더 강력합니다.
여기에서 **서비스 카탈로그(service catalog)**가 등장합니다. (예: incident.io의 Catalog, 또는 내부에서 운영 중인 레지스트리 등) 서비스 카탈로그는 다음을 정의합니다.
- 무엇이 있는지 (서비스, 잡, 큐, 서드파티 시스템 등)
- 누가 소유하는지 (팀, 온콜 로테이션, 도메인)
- 어떻게 연락하는지 (Slack 채널, 에스컬레이션 경로, 런북)
OpenTelemetry로 만든 의존성 그래프와 서비스 카탈로그를 연결하면, 그래프 위의 모든 노드는 이렇게 변합니다.
- 명확한 소유자가 있는 서비스
- 메타데이터(티어, 환경, SLO 등)를 가진 객체
- 행동으로 이어지는 관문 (이 팀을 페이지, 이 런북 열기 등)
이제 Failure Atlas는 단순히 예쁜 그림이 아니라, 실제 운영에 쓰이는 산출물이 됩니다.
- 그래프의 빨간 엣지 하나? 어느 팀을 불러야 할지 바로 알 수 있습니다.
- 특정 서비스 주변에 인시던트 핫스팟이 생겼다면? 같은 팀 이름이 반복해서 보일 겁니다.
이렇게 서비스 카탈로그는 Failure Atlas의 소유권 레이어 역할을 하게 됩니다.
단층선 기록하기: 주석으로서의 인시던트 이력
지질도는 산만 그리지 않습니다. 지구가 반복적으로 갈라졌던 **단층선(fault line)**을 표시합니다.
여러분의 시스템에도 단층선이 있습니다.
- 분기마다 세 번씩 다운되는 결제 게이트웨이
- 정기적으로 다운스트림 처리를 지연시키는 플래키(불안정한) 크론 잡
- 트래픽 피크만 되면 병목이 되는 레거시 모놀리스
여러분의 서비스 카탈로그가 다음을 함께 관리하고 있다면:
- 서비스별 인시던트 이력
- 반복적으로 등장하는 공통 기여 요인(contributing factors)
- 과거 시정 조치 및 리디자인 기록
…그 자체로 시스템 전체의 반복되는 실패 패턴에 대한 로그가 됩니다.
이 정보를 의존성 그래프 위에 덧씌우면, Tallian의 Atlas와 꽤 비슷한 그림이 나옵니다.
- 서비스 색을 인시던트 빈도에 따라 칠하기: 진할수록 인시던트가 많음
- 과거 연쇄 실패가 있었던 엣지에 주석 달기
- “이 의존성은 고부하 시 자주 실패함” 같은 메모 추가
시간이 지나면서 서비스 카탈로그는 시스템의 구조적 취약점에 대한 단일 소스 오브 트루스(single source of truth), 즉 여러분만의 단층선 지도처럼 진화합니다.
모든 것을 합쳐 보기: 소프트웨어를 위한 연필로 그린 실패 지도
지금까지의 요소를 합치면 다음과 같습니다.
-
트레이스 기반 의존성 그래프(OpenTelemetry)
시스템의 살아 있는 구조. -
서비스 카탈로그(예: incident.io의 Catalog)
모든 노드와 엣지에 대한 소유권·메타데이터 레이어. -
인시던트 이력과 패턴
지도 곳곳에 표시된 단층선과 핫스팟 주석.
머릿속으로, 이것을 하나의 한 장짜리 종이로 그려 볼 수 있습니다.
- 각 노드: 소유자가 라벨링된 서비스
- 각 엣지: 상태나 불안정성을 색으로 표현한 의존성
- 각 영역: 자주 함께 실패하는 서비스들의 클러스터
- 각 주석: 과거 인시던트와 트레이드오프에 대한 메모
실제 구현은 여러 도구와 UI에 흩어져 있어도 상관없습니다. 중요한 것은 다음이 가능해지는 것입니다.
- 대시보드 단위가 아니라 시스템 전체를 하나로 바라보기
- 실패가 어떻게 발생하고 퍼지는지 시각화하기
- 책임 팀과 관련 이력을 빠르게 식별하기
이게 바로 소프트웨어 신뢰성을 위한 여러분의 연필로 그린 Failure Atlas입니다.
나만의 실패 지도 만들기: 어디서부터 시작할까
완벽한 구현이 아니어도 충분히 가치 있습니다. 작게 시작해도 됩니다.
-
핵심 경로를 OpenTelemetry로 인스트루먼트하기
- 대표 사용자 여정(예: 가입, 결제)부터 시작합니다.
- 서비스 전반에 걸친 엔드 투 엔드 트레이스가 수집되도록 합니다.
-
기본적인 의존성 그래프 생성하기
- 트레이스 데이터를 이용해 서비스 간 호출 관계를 자동으로 발견합니다.
- 시각화합니다. 거친 그래프라도 없는 것보다는 훨씬 낫습니다.
-
서비스 카탈로그 구축 또는 보강하기
- 서비스를 등록하고 각 서비스를 담당 팀과 매핑합니다.
- 최소한 연락 수단과 에스컬레이션 경로는 포함합니다.
-
인시던트를 서비스에 연결하기
- 인시던트가 발생할 때마다, 어떤 서비스가 관여했는지 기록합니다.
- 시간이 지나면서 반복 등장하는 문제 구역과 패턴을 찾아 냅니다.
-
정기적으로 Atlas를 리뷰하기
- 인시던트 리뷰 및 아키텍처 논의 자리에서 함께 활용합니다.
- *우리의 단층선은 어디인가? 어떤 트레이드오프를 감수하고 있는가?*를 자주 묻습니다.
목표는 완벽히 정확한 지도라기보다, 의사결정을 이끌기에 충분히 좋은 **공유된 정신 모델(shared mental model)**입니다.
결론: 신뢰성에는 메트릭이 아니라 ‘지도’가 필요하다
Tallian의 Failure Atlas가 강력했던 이유는, 복잡성을 한 평면 위에서 마주보게 만들었기 때문입니다. 따로따로 떨어진 리포트 뒤에 숨을 수 없고, 모든 것이 어떻게 맞물리는지 눈으로 봐야 했죠.
현대 소프트웨어도 다르지 않습니다. 로그, 메트릭, 트레이스는 필수지만, 이를 하나로 엮어 줄 지도가 없으면 여전히 조각난 채로 남습니다.
다음을 결합하면:
- OpenTelemetry 기반 의존성 그래프
- 풍부하고 정확한 서비스 카탈로그
- 인시던트 이력과 반복되는 실패 패턴
…여러분만의 연필로 그린 Failure Atlas를 만들 수 있습니다. 컴포넌트, 의존성, 소유자, 단층선이 한 장에 담긴 개념적 지도입니다.
이 지도가 손에 들어오면, 인시던트 대응은 더 이상 깜깜한 곳에서의 소방 활동이 아니라, 이미 여러 번 걸어 본 익숙한 지형을 주석 가득한 지도를 보며 탐험하는 것에 가까워집니다.