본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 02. 19:23

런북(Runbooks): 구조, 사례, 그리고 AI 실행 가능 형식

요약

효과적인 런북(Runbook)의 정의와 구조를 다룹니다. 런북은 하나의 특정 장애 모드에 대응하는 실행 가능한 절차여야 하며, 플레이북과 혼동하지 않고 AI 에이전트까지 실행할 수 있는 구조로 설계해야 합니다.

핵심 포인트

  • 런북은 하나의 특정 장애 모드와 하나의 경고에 대응해야 함
  • 플레이북은 의사결정 트리이며, 런북은 그 트리의 최종 실행 단계임
  • 서비스 단위가 아닌 장애 모드 단위로 문서를 분리해야 함
  • AI 에이전트가 읽고 실행할 수 있는 구조적 설계가 중요함

아무도 열어보지 않는 위키(Wiki) 페이지. 6개월 동안 방치된 Confluence 문서. 사후 분석(Postmortem) 때 한 번 읽히고 잊혀지는 Notion 항목. 대부분의 "런북(Runbook)"이 실패하는 이유는 특정한 누군가를 위해 작성되지 않았기 때문입니다. 새벽 3시에 당직을 서는 신입 엔지니어도, 시스템을 이미 잘 알고 있는 숙련된 엔지니어도, 혹은 첫 대응자가 될 수도 있는 AI 에이전트(AI Agent)도 아닙니다. 런북은 누구에게도 도움이 되지 않으며, 조용히 부패해 갑니다.

유용한 런북은 구체적이고 좁은 범위를 다룹니다. 즉, 하나의 알려진 장애를 하나의 알려진 복구로 전환하는, 범위가 엄격히 제한된 실행 가능한 절차(Executable procedure)입니다. 이 포스트에서는 런북이 실제로 무엇인지(그리고 무엇이 아닌지)를 정의하고, 좋은 런북이 포함해야 할 7가지 섹션을 보여주며, 그대로 복사해서 사용할 수 있는 실제 사례를 살펴봅니다. 마지막으로 런북을 AI 에이전트가 실행할 수 있게 만드는 구조에 대해 설명합니다. 왜냐하면 점점 더 AI가 런북을 가장 먼저 읽게 될 것이기 때문입니다.

런북이란 무엇인가 (그리고 무엇이 아닌가)

**런북(Runbook)**은 하나의 특정한 운영 상황을 처음부터 끝까지 어떻게 처리해야 하는지 알려주는 문서입니다. 런북을 확인하게 만드는 트리거(Trigger), 나타나야 할 증상(Symptoms), 무엇이 잘못되었는지 확인하는 명령어(Commands), 이를 해결하는 단계(Steps), 그리고 해결되었음을 증명하는 확인 절차(Checks)를 포함합니다. 하나의 런북은 하나의 장애 모드(Failure mode)를 다룹니다.

이는 사람들이 같은 용어로 묶어서 부르곤 하는 몇몇 인접 문서들과는 다릅니다:

문서범위 (Scope)대상 (Audience)찾아보는 시점
런북 (Runbook)하나의 특정 장애 모드 (예: "API p95 지연 시간이 SLO를 초과함")온콜러 (On-caller), AI 에이전트, 또는 활성 장애 상황에 호출된 팀원해당 경고 (Alert)가 발생했을 때
...

가장 흔한 실수는 런북 (Runbook)을 플레이북 (Playbook)과 혼동하는 것입니다. 플레이북은 질문의 트리 구조입니다 ("데이터베이스가 병목 지점인가요? 맞다면 런북 X로 이동하세요. 아니라면 Y를 확인하세요."). 런북은 그 트리의 잎 (Leaf)입니다. 즉, 어떤 장애를 보고 있는지 범위를 좁힌 후 수행하는 실제 복구 절차입니다. (PagerDuty의 장애 대응 가이드는 많은 런북 형태의 절차로 연결되는 플레이북의 좋은 예시입니다.) 만약 당신의 "런북"이 500줄 이상이거나 하나 이상의 장애 모드를 다룬다면, 그것은 플레이북이며, 그 플레이북이 연결해야 할 실제 런북들은 아직 존재하지 않는 것입니다.

두 번째로 흔한 실수는 서비스 (Service) 하나당 하나의 런북을 작성하는 것입니다. 하나의 서비스에는 수십 개의 장애 모드가 존재합니다. 이 모든 것을 하나의 문서에 몰아넣는다는 것은, 압박감이 심한 상황에서 아무도 관련 섹션을 찾을 수 없음을 의미합니다. 하나의 런북은 하나의 장애 모드, 하나의 경고 (Alert)와 대응해야 합니다. 느린 DNS 조회 (slow DNS lookup)SSL 인증서 오류 (SSL certificate error)는 서로 다른 두 개의 장애 모드입니다. 비록 이들이 동일한 로드 밸런서 (Load balancer) 상에서 작동하더라도, 각각 별도의 런북을 가져야 합니다.

유용한 런북의 구조 (Anatomy)

인터넷에서 찾을 수 있는 대부분의 런북 템플릿은 목적, 범위, 소유자, 의존성, 변경 이력, 관련 링크, 에스컬레이션 매트릭스 (Escalation matrix), 마지막 검토 날짜 등 수십 개의 섹션을 요구합니다. 하지만 경고 (Alert)가 울리는 긴박한 상황에서 이 중 유용한 것은 거의 없습니다. 독자는 30초 정도의 작업 기억 (Working memory)만을 가지고 있으며, 무엇을 해야 하는지를 찾고 있습니다.

좋은 런북은 정확히 일곱 개의 섹션으로 구성됩니다:

  1. Trigger (트리거) — 독자를 이곳으로 이끈 정확한 경고(Alert) 또는 신호입니다. "이것은 API 문제용입니다"가 아니라, _"이 런북은 api-latency-p95-high 경고가 발생했을 때 열립니다"_와 같이 작성해야 합니다.
  2. Symptoms (증상) — 독자가 지금 당장 확인할 수 있는 사항입니다. 구체적인 명령어와 예상 출력값을 포함합니다. "p95 지연 시간(latency) 패널이 5분 이상 1초를 초과함; 에러율(error-rate) 패널은 평탄함 (5xx 폭풍 가능성 배제)."
  3. Diagnosis (진단) — 장애를 확인하고 유사한 사례를 배제하기 위한 명령어들입니다. 각 명령어는 코드 블록(fenced code block) 안에 작성하며, 예상 출력값에 주석을 답니다.
  4. Mitigation steps (완화 단계) — 순서가 정해져 있고, 멱등성(Idempotent)을 가지며, 각 단계는 실행 가능한 명령어를 포함해야 합니다. 만약 특정 단계가 이전 단계의 성공 여부에 의존한다면 이를 명시합니다.
  5. Verification (검증) — 조치가 성공했음을 독자가 어떻게 알 수 있는지에 대한 내용입니다. 구체적인 확인 사항을 작성합니다: "http_request_duration_seconds p95가 10회 연속 스크랩(scrape) 간격 동안 500ms 미만으로 떨어짐."
  6. RTO and what data you lose (RTO 및 데이터 손실 범위) — 예상되는 복구 시간과 허용 가능한 데이터 손실 범위입니다. 독자가 상부에 보고할 수 있도록, 이것이 30초 만에 끝나는 수정인지 아니면 30분이 걸리는 복구(restore)인지 알아야 합니다.
  7. Escalation path (에스컬레이션 경로) — 단계별 조치가 작동하지 않을 때 언제, 누구에게 에스컬레이션해야 하는지입니다. "DBA 팀"과 같은 모호한 표현이 아니라, 실제 이름이나 당번(rotation) 참조 정보를 작성합니다.

이것이 전부입니다. 그 외의 모든 것(소유자, 관련 링크, 최종 검토 날짜)은 파일의 프론트매터(front-matter)나 리포지토리(repository) 메타데이터에 속해야 하며, 호출을 받은 담당자가 전화가 울리는 와중에 읽어야 하는 본문에 포함되어서는 안 됩니다. RTO가 성공 기준으로서 왜 중요한지에 대한 자세한 내용은 MTTR Full Form을 참조하세요.

실제 사례: API p95 지연 시간 런북

아래는 일반적인 SaaS 장애 모드에 대한 요약된 런북입니다. 에러율은 평탄하게 유지되면서 API 지연 시간이 SLO 임계값을 초과하는 경우(종종 완전한 중단이 아닌 포화(saturation) 또는 의존성(dependency) 저하 문제)를 다룹니다. 이름들은 예시일 뿐이므로, 귀하의 서비스 레이블과 메트릭(metric) 이름으로 교체하여 사용하십시오.

시나리오: API p95 지연 시간이 SLO를 초과함

트리거 (Trigger): api-latency-p95-high 경고 (Prometheus 규칙: 5분 동안 p95 > 1s

이것이 제대로 작동하려면, 에이전트(Agent)가 단계를 추출하고 그에 따라 행동할 수 있도록 런북(Runbook)이 구조화되어야 합니다. 앞서 언급한 7가지 섹션은 필수적이지만 그것만으로는 충분하지 않습니다. 다음의 5가지 추가 속성이 런북을 AI 실행 가능(AI-executable)하게 만듭니다:

  1. 트리거(Trigger)는 설명이 아닌 기계가 파싱 가능한 쿼리(Machine-parseable query)여야 합니다. "느려 보임"과 같은 표현은 텔레메트리(Telemetry)와 매칭될 수 없지만, histogram_quantile(0.95, rate(http_request_duration_seconds_bucket{job="api"}[5m])) > 1.0은 가능합니다.
  2. 명령어는 언어 태그가 포함된 코드 블록(Fenced code blocks) 내에 존재해야 합니다 (bash, sql, yaml). 에이전트(및 모든 마크다운 파서)가 무엇이 실행 가능한지 알 수 있도록 구조적 단서(Structural cues)가 필요합니다.
  3. 예상 출력(Expected output)이 명령어와 함께 배치되어야 합니다. 에이전트에게 성공의 모습이 어떠한지 알려주지 않은 채 "kubectl get pods를 실행하세요"라고 말하는 단계는 실행 불가능합니다. 다음 단계로 넘어가기 전에 해당 단계가 제대로 작동했는지 확인할 방법이 없기 때문입니다.
  4. 실패 모드(Failure modes)가 명시적으로 분기되어야 합니다. "상태가 UP이지만 p95가 여전히 높다면, 확인 단계 3(의존성 상태)으로 이동하고, 포드(Pods)가 Not Ready라면 확인 단계 2(롤백)로 이동하세요"는 실행 가능합니다. 반면 "필요한 경우 에스컬레이션(Escalate)하세요"는 실행 불가능합니다. 에이전트는 "필요한" 것이 무엇을 의미하는지 결정할 수 없습니다.
  5. 복구 본문(Recovery body)에 산문(Prose)으로만 구성된 섹션이 없어야 합니다. 모든 단계에는 실행 가능한 아티팩트(Artifact)나 검증 가능한 체크(Verifiable check)가 있어야 합니다. 배경 설명(Background narrative)은 에이전트가 이미 조치 중일 때 건너뛸 수 있도록 별도의 "발생 원인(Why this happens)" 섹션에 포함되어야 합니다.

인간 전용 버전의 단계:

_"지연 시간(Latency)이 여전히 높은지 확인하세요. Grafana에서 메트릭을 확인하거나, 헬스 엔드포인트(Health endpoint)에 curl 명령을 보낼 수 있습니다. 여전히 느리다면 왜 그런지 조사해야 합니다."

동일한 단계의 AI 실행 가능 버전:

확인 1 — API 성능이 여전히 저하되었는가?

curl -s http://api.internal/health | jq -r '.status'

예상 결과: UP. 그 다음 Prometheus에서 지연 시간을 확인합니다:

histogram_quantile(0.95, rate(http_request_duration_seconds_bucket{job="api"}[5m]))

예상 결과: 0.5(500ms) 미만. 만약 두 번의 연속된 평가에서 1.0을 초과한다면, 확인 단계 2(최근 배포)로 진행하십시오.

동일한 정보이지만, 에이전트(agent)가 이를 실행하고, 출력을 파싱(parse)하며, 다음 단계로 진행할지 여부를 결정할 수 있습니다. 그것이 기준점입니다.

런북 위생(Runbook hygiene): 어디에 저장하고, 새벽 3시에 어떻게 찾을 것인가

존재하지만 장애 발생 시 찾을 수 없는 런북은 런북이 없는 것보다 더 나쁩니다. 온콜러(on-caller)가 이를 찾는 동안 수 분의 시간이 낭비되기 때문입니다. 발견 가능성(discoverability) 문제의 대부분은 다음 세 가지 규칙으로 해결할 수 있습니다.

런북을 코드와 함께 Git에 저장하십시오. Confluence와 Notion은 두 가지 측면에서 실패합니다. 첫째, 해당 서비스들이 의존하는 서비스(동일한 DNS 제공업체, 동일한 인증 제공업체 등)가 중단될 때 함께 작동하지 않을 수 있습니다. 둘째, 오래된 콘텐츠를 잡아낼 수 있는 리뷰 워크플로우(review workflow)가 없습니다. runbooks/api-latency-p95-high.md에 있는 런북은 주변 서비스가 변경될 때마다 검토됩니다. 풀 리퀘스트(pull requests)를 통해 작성자는 런북을 업데이트하거나, 업데이트하지 않는 이유를 설명해야만 합니다.

모든 알람(alert)을 해당 런북에 연결하십시오. 알람 시스템이 제공하는 어노테이션(annotation) 필드를 사용하십시오. Prometheus / Grafana의 경우, 이는 runbook_url입니다:

- alert: ApiLatencyP95High
  expr: |
    histogram_quantile(0.95, rate(http_request_duration_seconds_bucket{job="api"}[5m])) > 1
...

페이저(pager)(및 실행 중인 AI 에이전트)에 도달하는 알람 페이로드(alert payload)에 URL이 포함됩니다. 온콜러의 첫 번째 클릭은 곧바로 올바른 절차로 이어집니다.

장애 모드(failure mode)당 하나의 런북을 작성하고, 장애 명칭에 맞춰 이름을 지정하십시오. api.md가 아니라 api-latency-p95-high.md여야 합니다. 페이저가 울릴 때 알람 이름과 파일 이름이 일치하므로 검색이 필요 없습니다.

노후화 관리(decay management)를 위해: 각 런북을 분기별로 검토하고, 90일 동안 조회수가 0인 런북은 아카이브(archive)하십시오. 또한 장애 도중 발견된 오래된 런북은 그 자체로 sev3(severity 3) 장애로 취급하십시오. 온콜러가 이를 수정하기 위한 티켓(ticket)을 발행해야 합니다. 그렇지 않으면 아무도 수정하지 않을 것입니다.

DevHelm이 귀하의 장애 대응 흐름에 런북을 통합하는 방법

DevHelm은 알람이 울리고 누군가(사람 또는 에이전트)에게 빠른 컨텍스트(context)가 필요한 순간을 위해 구축되었습니다. 현재 제공되는 기능은 다음과 같습니다:

  • Alert channels (PagerDuty, Slack, webhook, email)는 상위 시스템(upstream system)이 보내는 페이로드(payload)를 그대로 전달합니다. 만약 Prometheus 또는 Grafana 알림에 runbook_url 어노테이션(annotation)이 포함되어 있다면, DevHelm이 발송하는 알림에 해당 URL이 함께 포함될 수 있습니다.
  • 의존성 상태 페이지Vendor status context — 지연 시간(latency)이 상위 시스템의 문제처럼 보일 때, 런북의 "의존성 상태 확인" 단계는 일반적인 Google 검색 대신 구체적인 목적지를 제공합니다.
  • Resource groups (MTTR Full Form 참조)는 하나의 장애 모드(failure mode)를 공유하는 여러 모니터를 하나의 인시던트(incident)로 통합합니다. 따라서 알림에 포함된 런북 링크는 세 개의 중복된 페이지가 아닌 하나의 근본 원인(root cause)과 일치하게 됩니다.

아직 출시되지 않은 기능: DevHelm 모니터의 퍼스트 클래스(first-class) runbook_url 필드 — 모니터에 한 번만 설정하면 모든 알림과 MCP 도구 응답으로 자동 흐르게 할 수 있는 기능입니다. 그때까지는 모니터 설명(description)과 알림 템플릿(alert template)에 URL을 넣어두세요. Reliability page에는 우리가 자체 스택을 운영하는 방식이 설명되어 있습니다. 이 포스트의 패턴을 적용하기 위해 우리의 내부 런북 저장소(repo)가 반드시 필요한 것은 아닙니다.

시작하는 방법

가장 소음이 심한 반복적 알림 — 지난 분기에 누군가를 두 번이나 깨웠던 바로 그 알림 — 을 하나 골라 그것을 위한 런북을 하나 작성해 보세요. 7개의 섹션, 500라인 미만, Git에 저장, 알림 어노테이션(annotation)에서 링크 연결. 이것이 전부입니다.

만약 여러분이 느린 DNS 조회 (slow DNS lookups)SSL 인증서 오류 (SSL certificate errors)를 해결해 본 경험이 있다면, 여러분은 이미 대부분의 작업을 수행한 것입니다. 그러한 조사 과정은 위에서 설명한 '트리거(trigger) → 진단(diagnosis) → 수정(fix) → 검증(verify)'의 형태를 정확히 따르기 때문입니다. 이를 런북(runbook)으로 만드는 것은 여러분이 이미 알고 있는 내용을 형식을 갖추어 정리함으로써, 다음 사람(또는 에이전트(agent))이 이를 다시 발견할 필요가 없도록 만드는 일일 뿐입니다. 그리고 일단 런북이 존재하게 되면, 그것이 실제로 복구 시간을 단축하는지 측정하는 것이 바로 MTTR의 목적입니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0