🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

복구 시나리오와 Runbook 완벽 가이드 - 슬라이드 1/7
A

AI Generated

2025. 12. 10. · 15 Views

복구 시나리오와 Runbook 완벽 가이드

서비스 장애 상황에서 30분 안에 시스템을 복구하는 방법을 배웁니다. make recover 명령어 설계부터 mkdocs 기반 정적 사이트 구축, runbook-plugin 활용법까지 실전에서 바로 쓸 수 있는 복구 문서화 전략을 다룹니다.


목차

  1. 복구_시나리오_유형_분류
  2. make_recover_명령어_설계
  3. 30분_복구_타이머_실습
  4. mkdocs_정적_사이트_설정
  5. runbook_plugin_활용법
  6. 복구_로그_자동_append_스크립트

1. 복구 시나리오 유형 분류

새벽 3시, 김개발 씨의 전화가 울렸습니다. 모니터링 시스템에서 알람이 터진 것입니다.

"데이터베이스 연결 실패, 서비스 응답 없음." 심장이 두근거렸습니다. 어디서부터 손을 대야 할까요?

복구 시나리오는 장애 상황을 유형별로 분류하고 각각의 해결 절차를 문서화한 것입니다. 마치 병원 응급실의 트리아지처럼, 장애의 심각도와 종류에 따라 우선순위를 정하고 대응합니다.

이를 제대로 정리해두면 긴급 상황에서도 당황하지 않고 체계적으로 대응할 수 있습니다.

다음 코드를 살펴봅시다.

# scenarios.yaml - 복구 시나리오 분류 체계
scenarios:
  database:
    severity: critical
    mttr: 15  # 목표 복구 시간(분)
    symptoms:
      - "Connection timeout"
      - "Too many connections"
    runbook: "docs/runbooks/db-recovery.md"

  api_gateway:
    severity: high
    mttr: 20
    symptoms:
      - "502 Bad Gateway"
      - "Rate limit exceeded"
    runbook: "docs/runbooks/api-recovery.md"

  cache:
    severity: medium
    mttr: 30
    symptoms:
      - "Cache miss rate > 80%"
      - "Redis connection failed"
    runbook: "docs/runbooks/cache-recovery.md"

김개발 씨는 입사 6개월 차 백엔드 개발자입니다. 처음으로 장애 대응 당번을 맡게 되었습니다.

선배들은 "장애는 언제든 발생할 수 있으니까 런북을 잘 읽어두세요"라고 조언했지만, 막상 위키에 들어가 보니 문서가 수백 개였습니다. "이걸 언제 다 읽지?" 막막함이 밀려왔습니다.

바로 그때 팀장 박시니어 씨가 다가왔습니다. "김개발 씨, 처음부터 다 읽을 필요는 없어요.

우리가 정리한 시나리오 분류 체계부터 보세요." 시나리오 분류가 왜 필요할까요? 응급실에 환자가 왔을 때를 떠올려봅시다. 의료진은 즉시 환자의 상태를 파악하고 중증도를 분류합니다.

생명이 위급한 환자는 즉시 치료하고, 경미한 환자는 대기실에서 순서를 기다립니다. 이것을 트리아지라고 부르죠.

서비스 장애도 똑같습니다. 모든 장애가 같은 심각도를 가진 것은 아닙니다.

데이터베이스가 다운되면 전체 서비스가 마비되지만, 캐시 서버 장애는 성능이 느려질 뿐 서비스는 계속 작동합니다. 분류 없이 대응하면 어떤 문제가 생길까요? 경험이 많지 않은 엔지니어는 장애 알람이 울릴 때마다 패닉 상태가 됩니다.

"뭐부터 해야 하지?" 하면서 구글 검색을 시작하거나, 여기저기 문서를 뒤지느라 소중한 시간을 낭비합니다. 더 큰 문제는 우선순위를 잘못 판단하는 것입니다.

사소한 로그 오류에 매달리다가 정작 심각한 데이터베이스 문제를 놓칠 수 있습니다. 실제로 한 스타트업에서는 캐시 장애를 해결하느라 1시간을 쓰다가, 진짜 원인인 데이터베이스 디스크 부족 문제를 너무 늦게 발견해서 3시간 장애로 이어진 사례가 있습니다.

체계적인 분류 시스템의 등장 이런 문제를 해결하기 위해 많은 기업들이 장애 시나리오 분류 체계를 도입했습니다. 위의 YAML 파일을 보면 세 가지 핵심 정보가 있습니다.

첫째, severity(심각도)는 장애가 비즈니스에 미치는 영향을 나타냅니다. critical은 전체 서비스 중단, high는 주요 기능 장애, medium은 성능 저하를 의미합니다.

둘째, mttr(Mean Time To Recovery)은 목표 복구 시간입니다. 데이터베이스는 15분 안에 복구해야 하지만, 캐시는 30분까지 허용됩니다.

이 숫자는 SLA와 연결되어 있습니다. 셋째, symptoms(증상)는 장애를 식별하는 단서입니다.

모니터링 알람에 "Connection timeout"이 뜨면 즉시 데이터베이스 시나리오를 떠올릴 수 있습니다. 실제 대응 과정은 어떻게 흘러갈까요? 새벽 3시에 알람을 받은 김개발 씨는 이제 당황하지 않습니다.

먼저 알람 메시지를 확인합니다. "Database connection timeout" 문구가 보입니다.

즉시 시나리오 분류 파일을 열어봅니다. database 섹션을 찾고, severity가 critical인 것을 확인합니다.

"15분 안에 복구해야 하는구나." 목표가 명확해집니다. runbook 경로를 따라 docs/runbooks/db-recovery.md 파일을 엽니다.

거기에는 단계별 복구 절차가 상세히 적혀 있습니다. 더 이상 구글 검색이 필요 없습니다.

유형별 분류 기준은 무엇일까요? 보통 시스템 아키텍처의 계층 구조를 따라 분류합니다. 인프라 계층(서버, 네트워크), 데이터 계층(데이터베이스, 캐시), 애플리케이션 계층(API, 백그라운드 잡), 외부 의존성(결제 게이트웨이, 외부 API) 등으로 나눕니다.

각 유형마다 담당 팀이 다를 수 있습니다. 데이터베이스는 DBA 팀, API는 백엔드 팀, 인프라는 SRE 팀이 관리합니다.

분류가 명확하면 에스컬레이션도 빨라집니다. 주의할 점도 있습니다 시나리오를 너무 세분화하면 오히려 복잡해집니다.

"PostgreSQL 버전 14.2의 리플리케이션 지연" 같은 식으로 나누면 관리할 문서가 너무 많아집니다. 적절한 추상화 수준을 유지해야 합니다.

또한 시나리오는 살아있는 문서입니다. 새로운 유형의 장애가 발생하면 즉시 추가해야 합니다.

분기마다 리뷰 세션을 열어서 실제 장애 사례를 반영하는 것이 좋습니다. 정리하며 김개발 씨는 이제 자신감이 생겼습니다.

다음 장애 대응 때는 체크리스트처럼 시나리오 분류부터 확인할 것입니다. 여러분도 지금 당장 팀의 시스템 구성을 보고 장애 시나리오를 분류해보세요.

증상, 심각도, 목표 복구 시간을 정의하는 것부터 시작하면 됩니다.

실전 팁

💡 - 시나리오는 5-10개 수준으로 유지: 너무 많으면 찾기 어렵습니다. 공통 패턴으로 묶으세요.

  • 실제 장애 사례로 검증: 분기마다 과거 장애를 리뷰하며 시나리오 분류가 적절했는지 확인하세요.
  • 증상을 정확히 기록: 모니터링 알람 메시지와 일치하도록 작성하면 검색이 쉬워집니다.


2. make recover 명령어 설계

박시니어 씨가 장애 대응 회고 미팅에서 말했습니다. "지난주 장애 때 복구 명령어를 찾느라 5분을 썼어요.

다들 터미널 히스토리를 뒤지고 있더라고요." 팀원들이 고개를 끄덕였습니다. 명령어를 표준화할 방법이 없을까요?

make recover는 복구 명령어를 Makefile로 표준화한 인터페이스입니다. 마치 리모컨의 전원 버튼처럼, 어떤 장애든 make recover-{type} 형태로 일관되게 실행할 수 있습니다.

복잡한 스크립트 경로나 파라미터를 외울 필요 없이, 읽기 쉬운 명령어 하나로 복구 절차를 실행합니다.

다음 코드를 살펴봅시다.

# Makefile - 복구 명령어 표준화
.PHONY: recover-db recover-api recover-cache

# 데이터베이스 복구 (15분 목표)
recover-db:
	@echo "🚨 Starting DB recovery..."
	@./scripts/recovery/db-health-check.sh
	@./scripts/recovery/db-restart.sh
	@./scripts/recovery/db-verify.sh
	@echo "✅ DB recovery completed"
	@./scripts/log-recovery.sh "database" "success" "$(USER)"

# API 게이트웨이 복구 (20분 목표)
recover-api:
	@echo "🚨 Starting API recovery..."
	@kubectl rollout restart deployment/api-gateway
	@kubectl wait --for=condition=ready pod -l app=api-gateway
	@./scripts/recovery/api-smoke-test.sh
	@./scripts/log-recovery.sh "api" "success" "$(USER)"

# 캐시 복구 (30분 목표)
recover-cache:
	@redis-cli FLUSHALL
	@./scripts/recovery/cache-warmup.sh
	@./scripts/log-recovery.sh "cache" "success" "$(USER)"

김개발 씨는 장애 대응 연습을 하고 있었습니다. 런북 문서를 보니 "데이터베이스 복구를 위해 다음 명령어를 실행하세요"라고 적혀 있었습니다.

그 아래에는 이런 명령어가 있었습니다. /opt/company/infrastructure/scripts/database/emergency/restart-with-backup-v2.sh --force --skip-validation "이걸 외워야 하나?" 김개발 씨는 한숨을 쉬었습니다.

왜 명령어 표준화가 필요할까요? 집에 있는 가전제품을 떠올려봅시다. TV, 에어컨, 세탁기 모두 전원 버튼이 있습니다.

위치는 조금씩 다르지만, "전원을 켜려면 전원 버튼을 누른다"는 인터페이스는 동일합니다. 만약 TV는 빨간 버튼을 3초간 누르고, 에어컨은 리모컨 뒷면의 스위치를 올리고, 세탁기는 특정 버튼 조합을 눌러야 한다면?

사용자는 매번 설명서를 봐야 할 것입니다. 복구 명령어도 마찬가지입니다.

데이터베이스는 /opt/scripts/db-restart.sh, API는 kubectl apply -f recovery.yaml, 캐시는 systemctl restart redis 같은 식으로 제각각이면 매번 문서를 찾아봐야 합니다. 표준화 없이 운영하면 생기는 문제 어느 스타트업에서는 복구 스크립트가 10개 이상이었습니다.

각 스크립트마다 위치도 다르고, 실행 방법도 달랐습니다. 어떤 것은 Python으로, 어떤 것은 Bash로, 어떤 것은 Go 바이너리로 작성되어 있었습니다.

장애가 발생하면 엔지니어들은 Slack에서 "DB 재시작 명령어 뭐였죠?"라고 물어봤습니다. 누군가 터미널 히스토리를 복사해서 붙여넣어 주면 그제야 실행할 수 있었습니다.

긴급 상황에서 이렇게 시간을 낭비하는 것은 치명적입니다. 더 큰 문제는 명령어를 잘못 실행하는 것입니다.

비슷한 이름의 스크립트가 여러 개 있으면 헷갈립니다. db-restart.shdb-restart-v2.sh 중 어떤 것이 최신일까요?

잘못된 버전을 실행하면 상황이 더 악화될 수 있습니다. Makefile이 해결책이 되는 이유 Make는 40년 넘게 사용된 빌드 도구입니다.

원래는 C 프로그램을 컴파일하기 위해 만들어졌지만, 지금은 태스크 러너로도 널리 쓰입니다. Makefile의 장점은 명확합니다.

첫째, 자기 문서화됩니다. make만 입력하면 사용 가능한 명령어 목록이 보입니다.

둘째, 탭 완성이 됩니다. make reco까지 입력하고 탭을 누르면 recover-db, recover-api 같은 옵션이 나타납니다.

셋째, 추상화가 가능합니다. 내부적으로 복잡한 스크립트를 실행하더라도, 사용자는 make recover-db만 입력하면 됩니다.

나중에 스크립트 경로가 바뀌어도 Makefile만 수정하면 됩니다. 코드를 단계별로 살펴봅시다 첫 줄의 .PHONY는 Make에게 이것들이 파일 이름이 아니라 명령어라고 알려줍니다.

이게 없으면 recover-db라는 파일이 존재할 때 명령어가 실행되지 않습니다. recover-db 타겟을 보면 여러 스크립트를 순차적으로 실행합니다.

먼저 헬스체크로 현재 상태를 파악하고, 재시작을 실행하고, 검증을 통해 복구가 성공했는지 확인합니다. 마지막으로 로그를 남깁니다.

@ 기호는 명령어 자체를 출력하지 않게 합니다. 없으면 터미널에 ./scripts/recovery/db-health-check.sh 같은 내용이 먼저 출력되어 지저분해집니다.

@echo 문으로 사용자에게 친화적인 메시지만 보여줍니다. 실무에서는 어떻게 활용할까요? 새벽 3시에 장애 알람을 받은 김개발 씨는 이제 간단합니다.

런북 문서를 열어서 복구 시나리오를 확인합니다. 문서에는 이렇게 적혀 있습니다.

"데이터베이스 복구: make recover-db를 실행하세요." 더 이상 긴 경로를 복사하거나 파라미터를 확인할 필요가 없습니다. 그냥 명령어를 입력하면 끝입니다.

스크립트가 자동으로 단계를 진행하고, 친절한 메시지로 진행 상황을 알려줍니다. 팀의 신입 엔지니어도 쉽게 사용할 수 있습니다.

"복구 명령어가 뭐예요?"라고 물어보면 "make만 쳐보세요"라고 답하면 됩니다. 모든 복구 명령어가 일목요연하게 나타납니다.

더 나아가기 Makefile에 의존성을 추가할 수도 있습니다. 예를 들어 API 복구를 하려면 먼저 데이터베이스가 정상이어야 한다면, recover-api: check-db-health 같은 식으로 의존 관계를 정의합니다.

또한 파라미터를 받을 수도 있습니다. make recover-db ENV=production처럼 환경 변수를 넘겨서 프로덕션과 스테이징을 구분할 수 있습니다.

주의할 점 Makefile의 들여쓰기는 반드시 을 사용해야 합니다. 스페이스로 하면 에러가 납니다.

에디터 설정에서 Makefile만 탭으로 저장하도록 설정하세요. 또한 너무 복잡한 로직을 Makefile에 넣지 마세요.

조건문이나 반복문이 필요하면 별도 스크립트로 분리하고, Makefile은 인터페이스 역할만 하게 하는 것이 좋습니다. 정리하며 박시니어 씨는 팀에 Makefile 기반 복구 시스템을 도입했습니다.

이제 장애 대응 시간이 평균 5분 줄었습니다. 명령어를 찾는 시간이 사라졌기 때문입니다.

여러분도 팀의 복구 스크립트를 Makefile로 정리해보세요. make recover-* 패턴으로 통일하면 누구나 쉽게 사용할 수 있습니다.

실전 팁

💡 - help 타겟 추가: make help로 모든 명령어와 설명을 보여주는 타겟을 만드세요.

  • dry-run 모드 제공: make recover-db-dryrun처럼 실제 실행 없이 단계만 보여주는 명령어를 추가하세요.
  • 에러 핸들링: 스크립트가 실패하면 즉시 중단되도록 set -e를 사용하세요.


3. 30분 복구 타이머 실습

장애 대응 훈련 시간이었습니다. 팀장이 말했습니다.

"오늘은 실전처럼 해봅시다. 타이머를 켜고 30분 안에 복구하세요." 김개발 씨는 시계를 보며 긴장했습니다.

시간은 빠르게 흐르는데, 어디까지 진행된 건지 알 수가 없었습니다.

복구 타이머는 각 단계의 소요 시간을 측정하고 목표 시간 내 복구를 유도하는 장치입니다. 마치 요리할 때 타이머를 맞춰두는 것처럼, 복구 과정의 각 단계에 시간 제한을 두고 진행 상황을 모니터링합니다.

이를 통해 병목 구간을 찾아내고 복구 속도를 개선할 수 있습니다.

다음 코드를 살펴봅시다.

#!/bin/bash
# recovery-timer.sh - 복구 시간 측정 스크립트

SCENARIO=$1
TARGET_TIME=$2  # 목표 시간(분)
START_TIME=$(date +%s)

echo "⏱️  Recovery started: $(date)"
echo "🎯 Target: $TARGET_TIME minutes"

# 단계별 시간 측정
step() {
    local step_name=$1
    local step_start=$(date +%s)
    echo ""
    echo "📍 Step: $step_name"

    # 실제 복구 작업 실행 (예시)
    shift
    "$@"

    local step_end=$(date +%s)
    local step_duration=$((step_end - step_start))
    echo "✓ Completed in ${step_duration}s"

    # 누적 시간 계산
    local total_elapsed=$((step_end - START_TIME))
    local total_minutes=$((total_elapsed / 60))
    local remaining=$((TARGET_TIME - total_minutes))

    if [ $remaining -lt 0 ]; then
        echo "⚠️  Over time by ${remaining#-} minutes!"
    else
        echo "⏳ Time remaining: $remaining minutes"
    fi
}

# 복구 단계 실행
step "Health Check" ./scripts/health-check.sh
step "Service Restart" ./scripts/restart.sh
step "Verification" ./scripts/verify.sh

END_TIME=$(date +%s)
TOTAL_DURATION=$(( (END_TIME - START_TIME) / 60 ))

if [ $TOTAL_DURATION -le $TARGET_TIME ]; then
    echo "✅ Recovery completed in $TOTAL_DURATION minutes (Target: $TARGET_TIME)"
else
    echo "❌ Recovery took $TOTAL_DURATION minutes (Over by $((TOTAL_DURATION - TARGET_TIME)) minutes)"
fi

김개발 씨는 복구 연습을 시작했습니다. 첫 번째 단계인 헬스체크를 실행했습니다.

5분이 지났습니다. 두 번째 단계인 재시작을 했습니다.

10분이 더 지났습니다. "지금 몇 분 지났지?" 김개발 씨는 계산기를 꺼냈습니다.

이미 15분이 흘렀습니다. 목표는 30분인데 절반을 써버렸습니다.

남은 단계를 생각하니 불안해졌습니다. 왜 시간 측정이 중요할까요? 마라톤 선수를 떠올려봅시다.

42.195km를 달리는 동안 중간 지점마다 시계를 확인합니다. 5km 지점에서 예상보다 느리면 페이스를 높이고, 빠르면 조금 여유를 둡니다.

이런 페이스 조절 없이 무작정 달리면 끝까지 완주하기 어렵습니다. 복구 작업도 똑같습니다.

전체 목표 시간이 30분인데, 첫 단계에서 20분을 써버리면 나머지는 불가능해집니다. 하지만 실시간으로 시간을 확인하지 않으면 이런 상황을 뒤늦게 깨닫습니다.

시간 측정 없이 복구하면 생기는 문제 실제 사례가 있습니다. 한 팀에서는 데이터베이스 복구 목표가 15분이었습니다.

그런데 실제로 측정해보니 평균 25분이 걸렸습니다. 왜 그랬을까요?

알고 보니 헬스체크 스크립트가 모든 테이블을 스캔하느라 12분이나 걸렸습니다. 복구의 80%가 진단에 소비되고 있었던 것입니다.

시간 측정을 하지 않았다면 이 병목을 발견하지 못했을 것입니다. 또 다른 문제는 심리적 압박입니다.

시간이 얼마나 지났는지 모르면 막연한 불안감에 휩싸입니다. "이거 너무 오래 걸리는 거 아냐?" 하면서 중간에 다른 방법을 시도하다가 더 꼬이는 경우도 있습니다.

타이머 스크립트는 어떻게 작동할까요? 위 코드를 보면 START_TIME에 복구 시작 시각을 기록합니다. Bash에서 date +%s는 유닉스 타임스탬프(초 단위)를 반환합니다.

step 함수가 핵심입니다. 각 단계를 실행하기 전에 step_start를 기록하고, 실행 후 step_end와의 차이로 소요 시간을 계산합니다.

그리고 전체 시작 시각과 비교해서 누적 시간을 보여줍니다. remaining 변수는 남은 시간입니다.

목표 30분에서 현재까지 경과한 시간을 빼면 됩니다. 만약 음수가 나오면 "이미 목표 시간을 초과했다"는 경고를 보여줍니다.

마지막에 전체 복구 시간을 분 단위로 계산해서 목표와 비교합니다. 성공하면 초록색 체크, 실패하면 빨간색 엑스를 보여줍니다.

실전에서는 어떻게 사용할까요? 김개발 씨는 이제 타이머 스크립트를 사용합니다. 복구를 시작하면 이렇게 입력합니다.

./recovery-timer.sh database 30 화면에 "Target: 30 minutes"라고 표시됩니다. 첫 번째 단계인 헬스체크가 시작됩니다.

5분 후에 완료되고 "Time remaining: 25 minutes"라고 나타납니다. 두 번째 단계인 재시작이 시작됩니다.

예상보다 오래 걸리고 있습니다. 12분이 지났습니다.

화면에 "Time remaining: 13 minutes"이 보입니다. 김개발 씨는 긴장합니다.

"마지막 검증 단계가 남았는데 13분 안에 끝낼 수 있을까?" 다행히 검증은 5분 만에 끝났습니다. 최종 메시지가 나타납니다.

"Recovery completed in 22 minutes (Target: 30)" 목표 안에 성공했습니다! 복구 훈련에 활용하기 많은 팀들이 정기적으로 게임데이를 엽니다.

실제 장애를 시뮬레이션하고 복구 연습을 하는 것입니다. 이때 타이머를 켜고 진행하면 훈련의 질이 크게 올라갑니다.

연습할 때마다 시간을 기록하면 개선 추이를 볼 수 있습니다. 처음에는 40분 걸리던 것이 연습을 거듭하며 30분, 25분으로 줄어듭니다.

어떤 단계가 병목인지도 명확히 보입니다. 또한 여러 엔지니어의 복구 시간을 비교할 수도 있습니다.

어떤 사람은 20분에 끝내고, 어떤 사람은 35분 걸린다면? 빠른 사람의 방법을 배워서 표준 절차에 반영합니다.

더 정교한 측정 시스템 타이머 스크립트를 확장해서 결과를 데이터베이스에 저장할 수도 있습니다. 날짜, 시나리오, 담당자, 각 단계별 소요 시간을 기록하면 나중에 분석할 수 있습니다.

그래프로 시각화하면 더 좋습니다. "지난 3개월간 데이터베이스 복구 시간 추이"를 차트로 만들면 개선 효과가 한눈에 보입니다.

주의할 점 너무 촉박한 목표는 역효과를 냅니다. 15분 안에 끝내야 한다는 압박에 검증 단계를 건너뛰면 더 큰 문제가 생길 수 있습니다.

목표 시간은 충분히 안전하면서도 긴박한 수준으로 설정하세요. 또한 타이머는 도구일 뿐입니다.

시간에 쫓겨서 무리하게 명령어를 입력하다가 실수하면 안 됩니다. "천천히 정확하게"가 더 빠를 때도 있습니다.

정리하며 김개발 씨는 복구 훈련을 거듭하며 자신감이 생겼습니다. 타이머를 보면서 페이스를 조절하는 법을 배웠습니다.

실제 장애 상황에서도 당황하지 않고 침착하게 대응할 수 있게 되었습니다. 여러분도 복구 절차에 타이머를 추가해보세요.

목표 시간을 정하고, 각 단계의 소요 시간을 측정하세요. 반복 연습을 통해 점점 빨라질 것입니다.

실전 팁

💡 - 단계별 목표 시간도 설정: 전체 30분 중 헬스체크 5분, 재시작 15분 같은 식으로 세분화하세요.

  • 알람 기능 추가: 목표 시간의 80%가 지나면 소리나 알림을 보내도록 설정하세요.
  • 평균 시간 비교: "이번 복구는 평균보다 5분 빨랐습니다" 같은 메시지를 추가하면 동기부여가 됩니다.


4. mkdocs 정적 사이트 설정

팀의 런북 문서가 50개를 넘어섰습니다. Confluence 위키에 흩어져 있어서 찾기가 힘들었습니다.

박시니어 씨가 제안했습니다. "런북만 모아서 전용 사이트를 만들면 어떨까요?

검색도 되고 보기도 편하게요."

MkDocs는 마크다운 문서를 깔끔한 정적 사이트로 변환해주는 도구입니다. 마치 책을 출판하듯이, 여러 개의 마크다운 파일을 하나의 웹사이트로 만들어줍니다.

코드 하이라이팅, 검색 기능, 내비게이션이 자동으로 생성되어 런북을 관리하기에 최적입니다.

다음 코드를 살펴봅시다.

# mkdocs.yml - MkDocs 런북 사이트 설정
site_name: Runbook Documentation
site_description: Emergency recovery procedures and runbooks
site_url: https://runbook.company.com

theme:
  name: material
  palette:
    primary: red  # 긴급 상황을 나타내는 색상
    accent: orange
  features:
    - navigation.tabs
    - navigation.sections
    - search.suggest
    - search.highlight

plugins:
  - search
  - runbook  # 복구 시간 추적 플러그인 (다음 섹션에서 설명)

nav:
  - Home: index.md
  - Database:
      - Connection Failure: runbooks/db-connection.md
      - Disk Full: runbooks/db-disk.md
      - Replication Lag: runbooks/db-replication.md
  - API Gateway:
      - 502 Error: runbooks/api-502.md
      - Rate Limiting: runbooks/api-rate-limit.md
  - Cache:
      - Redis Down: runbooks/cache-redis.md
      - Cache Warmup: runbooks/cache-warmup.md

markdown_extensions:
  - admonition  # 경고 박스
  - codehilite  # 코드 하이라이팅
  - pymdownx.superfences  # 코드 블록 향상
  - pymdownx.tabbed  # 탭 기능

김개발 씨는 Confluence를 열었습니다. 검색창에 "database recovery"를 입력했습니다.

결과가 30개나 나왔습니다. 어떤 것이 최신 문서인지 알 수 없었습니다.

클릭해서 열어보니 "이 문서는 2년 전에 작성되었습니다"라는 배너가 떠 있었습니다. 다른 문서를 열었더니 링크가 깨져 있었습니다.

세 번째 문서를 열었더니 드디어 찾던 내용이었습니다. 여기까지 10분이 걸렸습니다.

위키의 한계는 무엇일까요? Confluence나 Notion 같은 위키는 협업에는 좋지만, 런북 관리에는 단점이 있습니다. 첫째, 버전 관리가 어렵습니다.

누가 언제 무엇을 수정했는지 추적하기 힘듭니다. Git처럼 diff를 보거나 롤백하는 기능이 제한적입니다.

둘째, 문서 구조가 흐트러지기 쉽습니다. 누구나 아무 곳에나 페이지를 만들 수 있어서, 시간이 지나면 계층이 뒤죽박죽이 됩니다.

"이 문서 어디 있었지?" 하며 찾아 헤매게 됩니다. 셋째, 리뷰 프로세스가 없습니다.

런북은 잘못 작성되면 장애를 악화시킬 수 있습니다. 코드처럼 PR 리뷰를 거쳐야 하는데, 위키는 누구나 바로 편집할 수 있어서 품질 관리가 어렵습니다.

정적 사이트 방식의 장점 정적 사이트란 서버 없이 HTML/CSS/JS 파일만으로 작동하는 웹사이트입니다. Jekyll, Hugo, MkDocs 같은 도구가 마크다운을 HTML로 변환해줍니다.

MkDocs의 가장 큰 장점은 Git 기반이라는 점입니다. 런북 문서를 Git 저장소에 마크다운으로 작성하고, PR을 통해 리뷰합니다.

병합되면 자동으로 사이트가 빌드되어 배포됩니다. 코드와 똑같은 워크플로우입니다.

둘째, 구조가 명확합니다. mkdocs.yml 파일에 모든 문서의 계층이 정의되어 있습니다.

새로운 런북을 추가하려면 이 파일을 수정하고 PR을 보내면 됩니다. 아무렇게나 문서가 추가되지 않습니다.

셋째, 검색이 강력합니다. MkDocs는 전체 문서를 인덱싱해서 빠른 검색을 제공합니다.

타이핑하는 동안 실시간으로 결과가 나타납니다. 설정 파일을 뜯어봅시다 mkdocs.yml 파일이 MkDocs의 설정 파일입니다.

YAML 형식으로 작성합니다. theme: material은 구글의 Material Design을 적용한 테마입니다.

깔끔하고 모던한 UI를 제공합니다. primary: red는 런북의 긴급성을 나타내기 위해 빨간색을 메인 컬러로 설정한 것입니다.

features 섹션에서 유용한 기능들을 활성화합니다. navigation.tabs는 상단에 탭 메뉴를 만들고, search.suggest는 검색어 자동완성을 제공합니다.

nav 섹션이 핵심입니다. 여기서 사이트의 구조를 정의합니다.

Database, API Gateway, Cache 같은 카테고리를 만들고, 그 아래에 세부 런북을 배치합니다. 이 구조가 좌측 사이드바에 그대로 나타납니다.

markdown_extensions는 마크다운의 기능을 확장합니다. admonition을 쓰면 경고 박스를 만들 수 있습니다.

!!! warning 같은 문법으로 눈에 띄는 경고를 표시합니다.

실제로 사이트를 만들어봅시다 먼저 MkDocs를 설치합니다. Python이 필요합니다.

pip install mkdocs mkdocs-material 프로젝트 디렉토리를 만들고 초기화합니다. mkdocs new runbook-site mkdocs.yml 파일을 위의 내용대로 편집합니다.

그리고 docs/ 디렉토리에 런북 마크다운 파일들을 작성합니다. 로컬에서 미리보기를 실행합니다.

mkdocs serve 브라우저에서 http://localhost:8000을 열면 사이트가 보입니다. 파일을 수정하면 즉시 반영됩니다.

배포는 어떻게 할까요? 가장 간단한 방법은 GitHub Pages입니다. MkDocs는 한 줄 명령어로 GitHub Pages에 배포할 수 있습니다.

mkdocs gh-deploy 이 명령은 사이트를 빌드해서 gh-pages 브랜치에 푸시합니다. 몇 분 후 https://yourorg.github.io/runbook-site에서 접속할 수 있습니다.

회사 내부망에서만 접근해야 한다면 NginxS3에 배포할 수도 있습니다. mkdocs build 명령으로 site/ 디렉토리에 HTML이 생성되고, 이것을 웹서버에 올리면 됩니다.

CI/CD와 통합하기 GitHub Actions를 설정하면 런북이 자동으로 배포됩니다. PR이 머지될 때마다 사이트가 업데이트됩니다.

yaml name: Deploy Runbook on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - run: pip install mkdocs mkdocs-material - run: mkdocs gh-deploy --force 이제 런북을 수정하고 PR을 보내면, 리뷰를 거쳐 머지되고, 자동으로 사이트가 업데이트됩니다. 코드와 똑같은 프로세스입니다.

실무 활용 사례 많은 회사들이 MkDocs로 런북 사이트를 운영합니다. 넷플릭스의 카오스 엔지니어링 문서도 MkDocs 기반입니다.

오픈소스 프로젝트들도 많이 사용합니다. 어떤 팀은 런북 사이트를 대시보드에 즐겨찾기로 등록해 두었습니다.

장애가 발생하면 모두가 이 사이트를 열고 해당 런북을 찾습니다. 검색창에 에러 메시지를 입력하면 바로 관련 런북이 나타납니다.

주의할 점 마크다운 파일 이름을 함부로 바꾸면 안 됩니다. mkdocs.ymlnav 섹션과 일치해야 하기 때문입니다.

파일명을 변경하면 설정도 함께 수정해야 합니다. 또한 이미지 경로도 주의해야 합니다.

마크다운에서 ![alt](../images/diagram.png) 같은 상대 경로를 사용하면, 빌드 시 제대로 표시되지 않을 수 있습니다. docs/images/ 디렉토리를 만들고 절대 경로처럼 참조하는 것이 안전합니다.

정리하며 박시니어 씨는 MkDocs 런북 사이트를 팀에 도입했습니다. 이제 누구나 런북을 쉽게 찾을 수 있습니다.

Git 기반이라 리뷰도 철저히 하고, 변경 이력도 명확합니다. 여러분도 흩어진 런북 문서를 MkDocs로 통합해보세요.

마크다운으로 작성하고, Git으로 관리하고, 정적 사이트로 배포하세요. 장애 대응 속도가 크게 향상될 것입니다.

실전 팁

💡 - 사이트 내 검색 테스트: 실제 에러 메시지로 검색해보고 원하는 런북이 나오는지 확인하세요.

  • 다크모드 추가: palette 설정에 scheme: slate를 넣으면 다크모드가 활성화됩니다. 야간 장애 대응 시 눈이 편합니다.
  • 최근 업데이트 표시: Git 커밋 정보를 파싱해서 "최종 수정일: 2025-12-01" 같은 메타데이터를 자동으로 표시하는 플러그인을 사용하세요.


5. runbook plugin 활용법

MkDocs 사이트가 완성되었습니다. 하지만 박시니어 씨는 아쉬웠습니다.

"런북을 봤는지, 얼마나 자주 쓰이는지 알 수가 없네요. 복구 시간도 추적하고 싶은데." 커스텀 기능이 필요한 순간이었습니다.

MkDocs 플러그인은 문서 빌드 과정에 커스텀 로직을 추가하는 확장 기능입니다. 마치 워드프레스 플러그인처럼, 기본 기능에 없는 것을 추가할 수 있습니다.

런북 플러그인은 각 문서에 복구 시간, 사용 빈도, 최근 실행 로그 같은 메타데이터를 자동으로 삽입합니다.

다음 코드를 살펴봅시다.

# mkdocs_runbook_plugin.py - 런북 메타데이터 플러그인
from mkdocs.plugins import BasePlugin
import json
import os
from datetime import datetime

class RunbookPlugin(BasePlugin):

    config_scheme = (
        ('log_file', mkdocs.config.config_options.Type(str, default='recovery_logs.json')),
    )

    def on_page_markdown(self, markdown, page, config, files):
        """각 페이지의 마크다운 처리"""

        # 런북 페이지인지 확인
        if not page.file.src_path.startswith('runbooks/'):
            return markdown

        # 복구 로그 읽기
        log_file = self.config['log_file']
        if os.path.exists(log_file):
            with open(log_file, 'r') as f:
                logs = json.load(f)
        else:
            logs = []

        # 현재 런북과 관련된 로그 필터링
        runbook_name = page.file.name
        runbook_logs = [log for log in logs
                        if log.get('runbook') == runbook_name]

        # 통계 계산
        total_uses = len(runbook_logs)
        avg_recovery_time = (
            sum(log.get('duration', 0) for log in runbook_logs) / total_uses
            if total_uses > 0 else 0
        )
        last_used = (
            max(log.get('timestamp') for log in runbook_logs)
            if runbook_logs else 'Never'
        )

        # 메타데이터 박스 생성
        meta_box = f"""
!!! info "Runbook Metrics"
    - **Total Uses**: {total_uses}
    - **Avg Recovery Time**: {avg_recovery_time:.1f} minutes
    - **Last Used**: {last_used}
    - **Success Rate**: {self._calculate_success_rate(runbook_logs):.1f}%
"""

        # 마크다운 상단에 메타데이터 삽입
        return meta_box + "\n\n" + markdown

    def _calculate_success_rate(self, logs):
        """성공률 계산"""
        if not logs:
            return 0.0
        successes = sum(1 for log in logs if log.get('status') == 'success')
        return (successes / len(logs)) * 100

김개발 씨는 런북 사이트를 열었습니다. "Database Connection Failure" 문서를 클릭했습니다.

문서 상단에 파란색 박스가 보였습니다. "Total Uses: 12회, Avg Recovery Time: 18.5분, Last Used: 2025-12-08" "오, 이거 어떻게 나온 거지?" 김개발 씨는 신기했습니다.

플러그인이 왜 필요할까요? MkDocs는 기본적으로 마크다운을 HTML로 바꿔주는 역할만 합니다. 하지만 런북은 단순한 문서가 아닙니다.

살아있는 운영 도구입니다. 실제로 얼마나 자주 쓰이는지, 복구 시간은 얼마나 걸리는지, 성공률은 어떤지 알아야 합니다.

이런 데이터가 없으면 어떤 런북이 중요한지, 어떤 런북을 개선해야 하는지 알 수 없습니다. 수동으로 관리하면 생기는 문제 어떤 팀은 런북 문서 상단에 수동으로 메타데이터를 적었습니다.

"최근 사용: 2025-11-15, 복구 시간: 약 20분" 같은 식이었습니다. 문제는 이것을 업데이트하는 사람이 아무도 없다는 것입니다.

장애가 발생하면 복구에 집중하느라 문서 업데이트는 잊어버립니다. 시간이 지나면 정보가 오래되고, 결국 아무도 믿지 않게 됩니다.

플러그인의 작동 원리 MkDocs 플러그인은 빌드 과정의 특정 시점에 실행되는 후크 함수입니다. on_page_markdown은 각 페이지의 마크다운이 HTML로 변환되기 전에 호출됩니다.

위 코드를 보면 먼저 page.file.src_path로 현재 페이지가 runbooks/ 디렉토리에 있는지 확인합니다. 런북 페이지가 아니면 그냥 넘어갑니다.

그다음 recovery_logs.json 파일을 읽습니다. 이 파일에는 과거 복구 작업의 로그가 JSON 형태로 저장되어 있습니다.

각 로그는 런북 이름, 시작/종료 시각, 소요 시간, 성공 여부 같은 정보를 담고 있습니다. 현재 페이지의 런북 이름과 일치하는 로그만 필터링합니다.

예를 들어 db-connection.md 페이지라면 runbook: db-connection인 로그들만 추립니다. 이 로그들로 통계를 계산합니다.

전체 사용 횟수는 로그 개수이고, 평균 복구 시간은 소요 시간들의 평균입니다. 성공률은 성공한 로그의 비율입니다.

메타데이터 박스 생성 계산한 통계를 보기 좋게 표시하기 위해 admonition 문법을 사용합니다. `!!!

info "Runbook Metrics"`는 파란색 정보 박스를 만듭니다. 이 박스를 마크다운 문서의 맨 위에 붙입니다.

return meta_box + "\n\n" + markdown 부분이 이 역할을 합니다. 원래 마크다운 내용 앞에 메타데이터가 추가되는 것입니다.

플러그인 설치와 사용 플러그인 파일을 프로젝트 디렉토리에 저장합니다. 예를 들어 plugins/mkdocs_runbook_plugin.py 같은 경로입니다.

mkdocs.yml에 플러그인을 등록합니다. yaml plugins: - search - runbook: log_file: data/recovery_logs.json 이제 mkdocs build를 실행하면 플러그인이 작동합니다.

각 런북 페이지 상단에 메트릭 박스가 자동으로 추가됩니다. 로그는 어떻게 쌓일까요? 복구 스크립트를 수정해야 합니다.

복구가 끝날 때마다 recovery_logs.json에 데이터를 추가하도록 합니다. bash # 복구 완료 후 echo "{ \"runbook\": \"db-connection\", \"timestamp\": \"$(date -Iseconds)\", \"duration\": $TOTAL_MINUTES, \"status\": \"success\", \"operator\": \"$USER\" }" >> data/recovery_logs.json 이렇게 하면 복구 작업마다 로그가 쌓이고, 다음 빌드 때 통계가 업데이트됩니다.

실시간 업데이트는 가능할까요? 정적 사이트이므로 실시간은 아닙니다. 하지만 CI/CD를 설정하면 거의 실시간에 가깝습니다.

복구 스크립트가 로그를 추가하고 Git에 커밋하면, GitHub Actions가 자동으로 사이트를 재빌드합니다. 몇 분 안에 업데이트된 통계가 사이트에 반영됩니다.

더 발전시키기 플러그인에 트렌드 차트를 추가할 수도 있습니다. Chart.js 같은 라이브러리로 지난 30일간의 복구 시간 추이를 그래프로 보여줄 수 있습니다.

또한 알림 기능도 가능합니다. 특정 런북의 성공률이 80% 아래로 떨어지면 Slack에 메시지를 보내서 "이 런북을 점검해야 합니다"라고 알려줄 수 있습니다.

주의할 점 로그 파일이 너무 커지지 않도록 관리해야 합니다. 오래된 로그는 아카이브하고, 최근 90일 정도만 유지하는 것이 좋습니다.

또한 플러그인 코드에 버그가 있으면 빌드가 실패합니다. 충분히 테스트하고, 에러 핸들링을 잘 해야 합니다.

로그 파일이 없거나 형식이 잘못되어도 빌드는 계속 진행되도록 만드세요. 정리하며 박시니어 씨는 런북 플러그인을 만들어서 팀에 배포했습니다.

이제 런북 사이트를 열면 실제 사용 데이터가 보입니다. 어떤 런북이 자주 쓰이는지, 어떤 런북이 오래 걸리는지 한눈에 파악할 수 있습니다.

여러분도 런북 사이트에 커스텀 기능이 필요하다면 플러그인을 만들어보세요. MkDocs 문서를 읽고, 간단한 후크 함수부터 시작하면 됩니다.

실전 팁

💡 - 로그 스키마 검증: JSON Schema로 로그 형식을 정의하고, 플러그인에서 검증하세요. 잘못된 로그가 들어와도 에러 없이 처리됩니다.

  • 캐싱 활용: 로그 파일을 매번 파싱하면 빌드가 느려집니다. 변경되지 않았으면 캐시를 사용하세요.
  • 테스트 작성: 플러그인 코드에도 단위 테스트를 작성하세요. 샘플 로그로 통계 계산이 정확한지 검증합니다.


6. 복구 로그 자동 append 스크립트

김개발 씨가 복구를 마쳤습니다. "이제 로그를 기록해야 하는데..." 수동으로 JSON 파일을 열어서 편집하려니 번거로웠습니다.

실수로 JSON 형식을 망가뜨릴 수도 있었습니다. 자동화할 방법이 없을까요?

로그 자동 기록 스크립트는 복구 작업이 끝날 때 메타데이터를 자동으로 수집하고 로그 파일에 추가하는 도구입니다. 마치 일기를 자동으로 쓰는 것처럼, 복구 시나리오, 소요 시간, 결과를 빠짐없이 기록합니다.

이를 통해 수동 입력 실수를 방지하고 데이터 품질을 높입니다.

다음 코드를 살펴봅시다.

#!/usr/bin/env python3
# log-recovery.py - 복구 로그 자동 기록 스크립트

import json
import sys
from datetime import datetime
from pathlib import Path

LOG_FILE = Path("data/recovery_logs.json")

def append_recovery_log(scenario, status, operator, duration=None, notes=None):
    """복구 로그를 추가합니다."""

    # 로그 엔트리 생성
    log_entry = {
        "timestamp": datetime.now().isoformat(),
        "scenario": scenario,
        "runbook": f"{scenario.replace('_', '-')}.md",
        "status": status,  # success, failed, partial
        "operator": operator,
        "duration_minutes": duration,
        "notes": notes,
        "version": "1.0"
    }

    # 기존 로그 읽기 (없으면 빈 리스트)
    if LOG_FILE.exists():
        with open(LOG_FILE, 'r') as f:
            logs = json.load(f)
    else:
        logs = []
        LOG_FILE.parent.mkdir(parents=True, exist_ok=True)

    # 새 로그 추가
    logs.append(log_entry)

    # 로그 파일 저장 (예쁘게 포맷)
    with open(LOG_FILE, 'w') as f:
        json.dump(logs, f, indent=2, ensure_ascii=False)

    print(f"✅ Recovery log saved: {scenario} ({status})")

    # 통계 출력
    print_statistics(logs, scenario)

def print_statistics(logs, scenario):
    """현재 시나리오의 통계를 출력합니다."""
    scenario_logs = [log for log in logs if log['scenario'] == scenario]

    if len(scenario_logs) < 2:
        return

    total = len(scenario_logs)
    successes = sum(1 for log in scenario_logs if log['status'] == 'success')
    success_rate = (successes / total) * 100

    durations = [log['duration_minutes'] for log in scenario_logs
                 if log['duration_minutes']]
    avg_duration = sum(durations) / len(durations) if durations else 0

    print(f"\n📊 Statistics for {scenario}:")
    print(f"   Total executions: {total}")
    print(f"   Success rate: {success_rate:.1f}%")
    print(f"   Average duration: {avg_duration:.1f} minutes")

if __name__ == "__main__":
    if len(sys.argv) < 3:
        print("Usage: log-recovery.py <scenario> <status> [duration] [notes]")
        sys.exit(1)

    scenario = sys.argv[1]
    status = sys.argv[2]
    duration = int(sys.argv[3]) if len(sys.argv) > 3 else None
    notes = sys.argv[4] if len(sys.argv) > 4 else None
    operator = os.getenv("USER", "unknown")

    append_recovery_log(scenario, status, operator, duration, notes)

김개발 씨는 데이터베이스 복구를 마쳤습니다. 이제 로그를 남겨야 합니다.

텍스트 에디터로 recovery_logs.json을 열었습니다. 파일 끝에 쉼표를 추가하고, 새 객체를 입력하기 시작했습니다.

{"timestamp": "2025-12-... 어라, 날짜 형식이 뭐였지? ISO 8601?

타임존은 어떻게 표시하지? 타이핑 중 실수로 중괄호를 빠뜨렸습니다.

파일을 저장했습니다. 다음 빌드 때 JSON 파싱 에러가 발생했습니다.

사이트가 깨졌습니다. 수동 로그 입력의 문제점 사람은 실수를 합니다.

JSON 같은 구조화된 형식은 작은 실수에도 깨지기 쉽습니다. 쉼표 하나, 따옴표 하나가 잘못되면 전체 파일이 무용지물이 됩니다.

또한 일관성을 유지하기 어렵습니다. 어떤 사람은 날짜를 "2025-12-10"으로 쓰고, 어떤 사람은 "12/10/2025"로 씁니다.

시나리오 이름도 "db_connection"과 "database-connection"처럼 제각각입니다. 무엇보다 귀찮습니다.

새벽 4시에 장애를 복구하고 나면 기진맥진합니다. "로그는 나중에 쓰지 뭐" 하고 넘어가기 쉽습니다.

그러다 영영 잊어버립니다. 자동화 스크립트의 등장 해결책은 스크립트로 자동화하는 것입니다.

사람이 JSON 구조를 신경 쓸 필요 없이, 간단한 명령어만 입력하면 됩니다. ./log-recovery.py database success 18 "Restarted master node" 이 한 줄이면 끝입니다.

시나리오는 "database", 결과는 "success", 소요 시간은 18분, 메모는 "Restarted master node"입니다. 스크립트가 알아서 타임스탬프를 추가하고, 올바른 JSON 형식으로 로그 파일에 추가합니다.

코드를 단계별로 살펴봅시다 append_recovery_log 함수가 핵심입니다. 먼저 datetime.now().isoformat()으로 현재 시각을 ISO 8601 형식으로 가져옵니다.

2025-12-10T03:45:23.123456 같은 형태입니다. scenario를 기반으로 runbook 파일명을 생성합니다.

"database"는 "database.md"가 됩니다. 언더스코어는 하이픈으로 변환합니다.

기존 로그 파일을 읽습니다. 파일이 없으면 빈 리스트로 시작합니다.

LOG_FILE.parent.mkdir()으로 필요한 디렉토리도 자동으로 생성합니다. 새 로그를 리스트에 추가하고, json.dump()로 파일에 저장합니다.

indent=2는 예쁘게 포맷하기 위한 것입니다. ensure_ascii=False는 한글 같은 유니코드 문자를 그대로 저장하게 합니다.

통계를 즉시 보여주기 로그를 저장한 후 print_statistics 함수를 호출합니다. 현재 시나리오의 과거 로그들을 필터링해서 통계를 계산합니다.

전체 실행 횟수, 성공률, 평균 소요 시간을 계산해서 화면에 출력합니다. 복구를 마친 엔지니어는 즉시 피드백을 받을 수 있습니다.

"이번 복구는 18분 걸렸는데, 평균은 22분이네. 평소보다 빨랐구나!" 같은 식으로 자신의 성과를 확인할 수 있습니다.

Makefile과 통합하기 이전에 만든 Makefile과 통합하면 더욱 편리합니다. makefile recover-db: @START=$$(date +%s) @./scripts/db-recovery.sh @END=$$(date +%s) @DURATION=$$(( (END - START) / 60 )) @./log-recovery.py database success $$DURATION 이제 make recover-db만 입력하면 복구 실행과 로그 기록이 자동으로 이루어집니다.

사용자는 아무것도 신경 쓸 필요가 없습니다. 실패한 복구도 기록하기 성공한 복구만 기록하면 안 됩니다.

실패한 경우도 중요한 데이터입니다. 성공률을 정확히 측정하려면 실패도 기록해야 합니다.

스크립트에 에러 핸들링을 추가합니다. bash if ./scripts/db-recovery.sh; then ./log-recovery.py database success $DURATION else ./log-recovery.py database failed $DURATION "Check logs for details" fi 이렇게 하면 복구가 실패해도 로그가 남습니다.

나중에 "이 시나리오는 성공률이 60%밖에 안 되네? 런북을 개선해야겠다"라고 판단할 수 있습니다.

로그 분석하기 로그가 쌓이면 다양한 분석이 가능합니다. Python 스크립트로 recovery_logs.json을 파싱해서 리포트를 생성할 수 있습니다.

"지난 달 가장 많이 발생한 장애 시나리오는 database(15회), api(8회), cache(3회)입니다." "database 시나리오의 평균 복구 시간이 지난 달 25분에서 이번 달 18분으로 개선되었습니다." 이런 인사이트는 시스템 개선의 방향을 알려줍니다. 로그 보관 정책 로그가 무한정 쌓이면 파일이 커집니다.

주기적으로 오래된 로그를 아카이브해야 합니다. 매월 말에 현재 로그를 recovery_logs_2025_12.json 같은 이름으로 백업하고, 새 로그 파일을 시작하는 식입니다.

혹은 최근 90일 로그만 유지하고 나머지는 삭제할 수도 있습니다. 주의할 점 동시에 여러 복구 작업이 실행되면 로그 파일 쓰기 충돌이 발생할 수 있습니다.

파일 락을 사용하거나, 각 로그를 별도 파일로 저장한 후 주기적으로 머지하는 방법을 고려하세요. 또한 민감한 정보(비밀번호, API 키 등)가 로그에 포함되지 않도록 주의하세요.

notes 필드에 들어가는 내용을 검증하는 로직을 추가하면 좋습니다. 정리하며 김개발 씨는 이제 복구 후 로그 기록을 걱정하지 않습니다.

스크립트가 알아서 처리해주기 때문입니다. 손쉽게 명령어 한 줄이면 끝입니다.

시간이 지나자 로그가 쌓였습니다. 팀장은 이 데이터로 분기 리포트를 만들었습니다.

"우리 팀은 이번 분기에 평균 복구 시간을 30% 단축했습니다." 구체적인 숫자로 증명할 수 있었습니다. 여러분도 복구 로그 자동화 스크립트를 만들어보세요.

수동 입력의 번거로움을 없애고, 정확한 데이터로 시스템을 개선하세요.

실전 팁

💡 - Slack 알림 추가: 복구가 완료되면 Slack에 메시지를 보내서 팀에 공유하세요. curl로 Webhook을 호출하면 됩니다.

  • Git 자동 커밋: 로그 파일이 업데이트되면 자동으로 Git에 커밋하고 푸시하세요. CI/CD가 사이트를 재빌드합니다.
  • CSV 내보내기 기능: 로그를 CSV로 변환하는 스크립트를 추가하면 엑셀로 분석하기 편합니다.

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#DevOps#Runbook#MkDocs#복구자동화#문서화#DevOps,문서화,자동화

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.