콘텐츠로 이동

SRE Practices

분류: Layer 6 - 운영 심화: 관측성 & 복원력 | 선수지식: Logs / Metrics / Traces | 티어: MUST

SRE(Site Reliability Engineering)는 서비스 신뢰성을 엔지니어링 문제로 다루는 운영 규율이다. 로그, 메트릭, 트레이스가 “무슨 일이 보이는가”를 알려준다면, SRE는 그 신호를 이용해 얼마나 신뢰할 수 있어야 하는가, 얼마나 실패해도 되는가, 지금 배포해도 되는가, 사고 뒤 무엇을 바꿀 것인가를 결정한다.

여기서 신뢰성(reliability)은 서버가 항상 켜져 있다는 뜻만이 아니다. 사용자가 중요한 작업을 제때 성공시키고, 실패가 발생해도 영향 범위가 제한되며, 같은 사고가 반복되지 않는 상태를 말한다.

2. 선행 한계: 관측 도구만으로는 운영 결정을 내릴 수 없다

섹션 제목: “2. 선행 한계: 관측 도구만으로는 운영 결정을 내릴 수 없다”

Logs / Metrics / Traces를 갖추면 장애를 더 잘 볼 수 있다. 하지만 관측성만으로는 아래 질문에 답하지 못한다.

  • 결제 API 에러율 0.3%는 지금 배포를 멈출 정도인가?
  • p99 지연시간이 900ms로 올랐을 때 SEV1인가 SEV2인가?
  • 이번 달 장애가 많았으니 기능 개발을 줄이고 안정화에 투자해야 하는가?
  • 롤백으로 복구된 뒤 어떤 개선 항목을 반드시 끝내야 하는가?

SRE는 이 질문을 감이 아니라 수치와 정책으로 다룬다. 핵심 흐름은 사용자 영향 SLI -> 내부 목표 SLO -> 허용 실패량 Error Budget -> 사고 대응과 개선 정책이다.

메트릭 수집의 한계 -> SRE가 등장한 이유

섹션 제목: “메트릭 수집의 한계 -> SRE가 등장한 이유”

CPU 80% 알람은 원인 후보일 수 있지만, 사용자가 실제로 실패를 겪고 있다는 뜻은 아닐 수 있다. 반대로 CPU가 낮아도 결제 승인 외부 API가 느려져 사용자 결제는 실패할 수 있다. 그래서 SRE는 “시스템 내부가 바쁜가”보다 “사용자가 기대한 일을 성공했는가”를 먼저 본다.

SRE의 철학은 두 가지다.

  1. 신뢰성은 사용자에게 보이는 제품 품질이다. 기능이 많아도 중요한 요청이 실패하면 제품 품질은 낮다.
  2. 신뢰성은 무한히 높일 목표가 아니라 명시적으로 선택할 trade-off다. 99.9%와 99.99%는 숫자 0.09%p 차이가 아니라 비용, 배포 속도, 조직 운영 방식의 차이다.

프론트엔드의 Core Web Vitals도 “사용자 경험을 측정 가능한 지표로 바꾼다”는 점에서 SLI의 짧은 예시가 될 수 있다.

관측성 이후 SRE가 답하는 질문

무엇을 측정할까

CPU나 메모리보다 사용자의 성공, 지연, 정확성을 측정한다.

대시보드는 많지만 어떤 숫자가 사용자 품질인지 모를 때

어디까지 허용할까

완벽한 가용성 대신 서비스별로 현실적인 SLO와 Error Budget을 둔다.

장애와 배포 속도 사이에서 매번 감으로 결정할 때

장애 중 무엇을 먼저 할까

원인 분석보다 사용자 영향 완화를 먼저 두고, 역할과 에스컬레이션을 정한다.

알람은 울렸지만 누가 무엇을 결정할지 불분명할 때

사고 뒤 무엇이 남을까

Postmortem과 Action Items로 같은 실패를 덜 일어나게 만든다.

장애 회고는 있는데 같은 장애가 반복될 때

”9가 몇 개인가”는 비용과 속도의 문제다

섹션 제목: “”9가 몇 개인가”는 비용과 속도의 문제다”

가용성 목표는 추상적인 품질 선언이 아니라 허용 다운타임을 정하는 숫자다. 30일 기준으로 계산하면 감각이 더 선명하다.

가용성 목표30일 기준 허용 다운타임연간 기준 허용 다운타임의미
99%약 7.2시간약 87.6시간초기 서비스에서 관측과 복구 루프를 만드는 수준
99.9%약 43.2분약 8.76시간일반 사용자 서비스가 자주 시작하는 현실적 목표
99.99%약 4.32분약 52.6분결제, 인증, 핵심 API처럼 높은 비용을 감수하는 목표
99.999%약 26초약 5.26분전용 고가용성 설계와 강한 운영 체계 없이는 어렵다

99.9%는 “한 달에 약 43분까지 실패를 허용한다”는 말이다. 이 숫자를 모르면 배포 여부, 알람 심각도, 장애 후 투자 우선순위가 모두 사람의 느낌에 맡겨진다.

SRE 문서는 약어가 많다. 아래 용어는 이후 절에서 계속 쓰이므로 첫 의미를 먼저 잡는다.

용어첫 정의왜 필요한가
SRESite Reliability Engineering. 신뢰성을 소프트웨어 엔지니어링과 운영 정책으로 관리하는 규율운영을 개인 영웅담이 아니라 반복 가능한 시스템으로 만들기 위해
SLIService Level Indicator. 서비스 수준을 나타내는 측정 지표”좋다/나쁘다”를 측정 가능한 값으로 바꾸기 위해
SLOService Level Objective. SLI에 대한 내부 목표값배포, 알람, 안정화 투자를 결정하는 기준으로 쓰기 위해
SLAService Level Agreement. 고객이나 파트너와 맺는 외부 계약위반 시 크레딧, 환불, 계약 리스크가 생기는 약속을 구분하기 위해
Error BudgetSLO가 허용하는 실패량안정성과 변경 속도 사이의 공통 언어를 만들기 위해
Burn RateError Budget을 태우는 속도”언젠가 위험”이 아니라 “이 속도면 언제 소진”을 판단하기 위해
Incident현재 사용자 영향이 있거나 곧 생길 수 있는 사고지금 당장 완화와 커뮤니케이션이 필요한 사건을 구분하기 위해
Problem반복 사고의 근본 원인이나 구조적 결함사고를 끄는 것에서 끝나지 않고 재발을 줄이기 위해
Severity사고 심각도 등급누구를 깨우고, 얼마나 빨리 대응하며, 어디까지 보고할지 정하기 위해
Escalation더 높은 책임자나 전문 담당자에게 대응을 넘기는 절차한 사람이 멈췄을 때 대응도 같이 멈추지 않게 하기 위해
Runbook특정 증상에서 확인할 관찰 포인트와 완화 선택지를 적은 운영 문서장애 중 기억에 의존하지 않고 빠르게 복구하기 위해
Postmortem사고 후 타임라인, 원인, 개선 항목을 정리하는 회고같은 종류의 장애가 반복되지 않게 조직 학습을 남기기 위해
Blameless개인 비난보다 시스템 조건을 분석하는 태도실수를 숨기지 않고 재발 방지 조건을 찾기 위해
Toil수동적, 반복적, 자동화 가능, 장기 가치가 낮은 운영 작업사람 시간을 장애 처리에서 시스템 개선으로 옮기기 위해
Alert Fatigue알람이 너무 많아 실제 장애 알람까지 무시되는 상태알람 체계 자체가 신뢰성을 해치지 않게 하기 위해
MTTRMean Time To Recovery. 평균 복구 시간사고가 났을 때 얼마나 빨리 사용자 영향을 줄이는지 보기 위해
MTTFMean Time To Failure. 정상 상태에서 다음 장애까지 평균 시간장애가 얼마나 자주 나는지 보기 위해
MTBFMean Time Between Failures. 장애와 장애 사이의 평균 간격장애 빈도와 복구 시간을 함께 보는 장기 신뢰성 지표로 쓰기 위해

첫 회독에서 붙잡을 것과 미뤄도 되는 것

섹션 제목: “첫 회독에서 붙잡을 것과 미뤄도 되는 것”

SRE는 도구 이름이 많아서 처음 읽을 때 범위를 잃기 쉽다. 이 문서의 첫 회독 목표는 모든 운영 도구를 설정하는 것이 아니라, 관측 신호가 어떻게 의사결정으로 바뀌는지 설명하는 것이다.

첫 회독에서 반드시 잡을 것:

  • SLI, SLO, SLA의 계층 차이를 말할 수 있다.
  • 99.9% 월간 SLO가 약 43.2분의 허용 다운타임이라는 감각을 가진다.
  • Error Budget이 배포 속도와 안정화 우선순위를 정하는 기준임을 이해한다.
  • Incident 중에는 원인 분석보다 사용자 영향 완화가 먼저라는 우선순위를 안다.
  • Postmortem의 목적이 비난이 아니라 재발 가능성을 줄이는 시스템 개선임을 안다.
  • Toil과 Alert Fatigue가 운영 체계의 건강도 신호임을 안다.

첫 회독에서 미뤄도 되는 것:

  • 특정 제품의 콘솔 클릭 경로.
  • CloudFormation이나 Terraform으로 SLO 리소스를 선언하는 세부 문법.
  • PagerDuty, Slack, Jira/Linear 같은 도구별 자동화 설정.
  • Google SRE 조직 구조나 대규모 플랫폼 팀의 운영 모델.

도구 설정은 나중에 바뀐다. 하지만 SLI를 잘못 고르면 어떤 도구를 써도 잘못된 결정을 내린다. 그래서 처음에는 이름보다 측정 대상, 분모, 목표, 정책 연결을 먼저 익힌다.

4. SLI / SLO / SLA: 측정, 목표, 계약

섹션 제목: “4. SLI / SLO / SLA: 측정, 목표, 계약”

SLI, SLO, SLA는 같은 숫자를 다른 위치에서 쓰는 것이 아니다. 계층이 다르다.

SLI = 실제 측정값
SLO = 내부 운영 목표
SLA = 외부 계약 약속

예를 들어 결제 API에 대해 아래처럼 말할 수 있다.

SLI: 30일 동안 성공한 결제 요청 / 전체 결제 요청
SLO: 위 SLI가 99.9% 이상이어야 한다
SLA: 고객에게 월간 99.5% 이상을 계약으로 약속한다

SLO는 SLA보다 엄격해야 한다. 내부 목표가 외부 계약보다 낮으면, 팀이 위험을 알아차렸을 때는 이미 계약 위반에 가까워진다.

SLI는 사용자 경험에 가까워야 한다

섹션 제목: “SLI는 사용자 경험에 가까워야 한다”

좋은 SLI는 사용자가 실제로 겪는 성공과 실패에 가깝다.

SLI 후보좋은가이유
2xx/3xx 응답 수 / 전체 요청 수좋음요청 성공률을 직접 보여준다
300ms 이하 응답 수 / 전체 요청 수좋음사용자가 느끼는 속도와 연결된다
주문 생성 후 결제 승인까지 10초 이내 완료율좋음비동기 흐름의 실제 사용자 결과를 본다
CPU 사용률보조 지표원인 후보일 뿐 사용자 성공률이 아니다
로그 라인 수보조 지표장애 시 단서지만 품질 목표 자체는 아니다

SLI를 고를 때는 먼저 “사용자가 이 기능이 성공했다고 느끼는 조건은 무엇인가”를 묻는다. 그 다음에 ALB 로그, 애플리케이션 메트릭, CloudWatch Application Signals, synthetic monitoring 중 어디서 가장 일관되게 측정할지 고른다.

서비스마다 같은 SLI를 쓰면 안 된다. 사용자가 기대하는 결과가 다르기 때문이다.

SLI 패턴질문예시주의점
Availability요청이 성공했는가?2xx/3xx / 전체 HTTP 요청4xx 중 사용자 입력 오류를 실패로 볼지 결정해야 한다
Latency충분히 빨랐는가?300ms 이하 응답 / 전체 요청평균보다 p95, p99가 사용자 불만과 더 잘 맞을 때가 많다
Freshness데이터가 충분히 최신인가?5분 이내 동기화된 상품 / 전체 상품비동기 시스템에서는 성공보다 지연이 더 중요한 품질일 수 있다
Correctness결과가 맞는가?정산 금액 불일치 없는 주문 / 전체 주문측정 비용이 높아 샘플링이나 배치 검증이 필요할 수 있다
Durability저장한 데이터가 사라지지 않는가?유실 없이 저장된 이벤트 / 전체 이벤트낮은 빈도라도 영향이 크면 별도 severity 기준이 필요하다
Coverage감시가 실제 여정을 덮는가?synthetic probe 성공 / 전체 probeprobe가 실제 사용자와 다른 경로를 타면 false confidence가 생긴다

예를 들어 queue 기반 주문 처리에서는 HTTP 200만으로는 부족하다. API가 202 Accepted를 반환해도 worker가 30분 동안 처리하지 못하면 사용자는 주문이 멈춘 것으로 느낀다. 이 경우 SLI는 “주문 생성 요청 성공률”과 별도로 “주문 생성 후 5분 이내 처리 완료율”을 둬야 한다.

나쁜 SLI는 장애를 숨기거나, 정상 상태를 장애로 보이게 한다.

잘못된 SLI: worker 프로세스 CPU 사용률 < 70%
실제 사용자 품질: 주문이 5분 안에 처리되는 비율

CPU가 30%여도 외부 결제 API timeout 때문에 주문 처리가 막힐 수 있다. 반대로 CPU가 85%여도 주문이 모두 1분 안에 처리된다면 지금 깨워야 할 사고가 아닐 수 있다. SLI는 내부 자원 상태가 아니라 사용자 결과와 연결되어야 한다.

SLO는 목표값보다 측정 방식이 먼저다

섹션 제목: “SLO는 목표값보다 측정 방식이 먼저다”

SLO를 처음 정할 때 흔한 실수는 99.99% 같은 숫자를 먼저 고르는 것이다. 순서는 반대다.

  1. SLI를 정한다. 예: 결제 API 요청 성공률, p99 지연시간, 주문 처리 완료율.
  2. 측정 지점을 정한다. 예: ALB, 애플리케이션, 클라이언트, synthetic probe.
  3. 2주에서 30일 정도 기준선(baseline)을 본다.
  4. 사용자 영향과 비용을 보고 첫 SLO를 정한다.
  5. SLO 위반 시 어떤 정책이 발동되는지 문서화한다.

측정 지점이 다르면 SLO 숫자도 달라진다. ALB는 서버가 응답한 요청을 잘 보지만 DNS 실패나 사용자의 네트워크 실패는 놓칠 수 있다. 클라이언트 측 측정은 실제 사용자 체감에 가깝지만 앱 버전, 네트워크, 디바이스 편차가 섞인다. 어느 쪽이 맞는지가 아니라, 그 SLO가 어떤 의사결정에 쓰이는지에 맞춰 일관된 소스를 고르는 것이 중요하다.

SLO 문장은 네 가지를 가져야 한다

섹션 제목: “SLO 문장은 네 가지를 가져야 한다”

SLO는 “99.9%“라고 쓰면 불완전하다. 측정 대상, 좋은 이벤트의 정의, 윈도우, 정책 연결이 있어야 한다.

payment-api의 결제 승인 요청 중
HTTP 2xx를 반환하고 1초 이내 완료된 요청 비율이
rolling 30일 동안 99.9% 이상이어야 하며,
Error Budget 잔여량이 25% 미만이면 고위험 배포를 중단한다.

이 문장에는 네 가지가 들어 있다.

  • 대상: payment-api의 결제 승인 요청.
  • 좋은 이벤트: HTTP 2xx이면서 1초 이내 완료.
  • 윈도우: rolling 30일.
  • 정책: budget 25% 미만이면 고위험 배포 중단.

이 네 가지 중 하나가 빠지면 해석이 흔들린다. 특히 윈도우가 없으면 5분 장애와 한 달 품질을 같은 방식으로 이야기하게 된다.

Worked Example: 결제 API SLO를 처음 정하기

섹션 제목: “Worked Example: 결제 API SLO를 처음 정하기”

30일 동안 결제 API 요청이 3,000,000건 있었고, 성공한 요청이 2,997,235건이라고 하자.

가용성 SLI = 2,997,235 / 3,000,000
= 0.9990783...
= 약 99.91%

이 서비스에 바로 99.99% SLO를 걸면 한 달 허용 실패는 300건뿐이다.

99.99% SLO의 허용 실패 = 3,000,000 * 0.0001 = 300건
실제 실패 = 2,765건
결과 = 이미 SLO를 크게 위반

반대로 99.9% SLO를 걸면 한 달 허용 실패는 3,000건이다.

99.9% SLO의 허용 실패 = 3,000,000 * 0.001 = 3,000건
실제 실패 = 2,765건
남은 Error Budget = 235건

99.9%도 여유롭지는 않다. 하지만 이 숫자는 “이번 달은 큰 배포보다 실패 원인 제거가 우선”이라는 실무 판단으로 연결된다. 좋은 SLO는 팀을 마비시키는 숫자가 아니라, 위험을 보고 배포 속도를 조절하게 만드는 숫자다.

SLO는 무엇을 분모로 삼느냐에 따라 느낌이 달라진다.

방식계산잘 맞는 대상주의점
Request-based좋은 요청 / 전체 요청결제 API, 로그인 API, 검색 API내부 테스트나 봇 트래픽을 분모에 섞으면 사용자 품질을 왜곡한다
Period-based좋은 시간 구간 / 전체 시간 구간배치 창, 스트리밍 처리, 운영 대시보드짧은 장애가 많은 요청을 망쳤는데도 한 구간으로만 집계될 수 있다

결제처럼 요청 단위 성공/실패가 명확하면 request-based SLO가 자연스럽다. “5분마다 집계가 정상적으로 끝났는가”처럼 시간 창이 더 중요한 시스템은 period-based SLO가 읽기 쉽다.

SLO가 높을수록 항상 좋은 것은 아니다.

설정겉보기 장점실제 위험
너무 높은 SLO품질에 강한 팀처럼 보인다작은 배포나 짧은 외부 장애에도 budget이 소진되어 팀이 멈춘다
너무 낮은 SLO배포 속도가 빠르고 위반이 적다사용자가 불편해도 정책이 발동하지 않아 SLO가 장식이 된다
기준선 기반 SLO현실적인 시작점이 된다기준선이 나쁜 상태면 낮은 품질을 정당화할 수 있으므로 상향 계획이 필요하다

첫 SLO는 보통 현재 기준선보다 약간 느슨하게 잡고, 반복 장애와 사용자 불만이 줄어드는지 보면서 상향한다. 반대로 핵심 결제, 인증, 권한 시스템은 낮은 목표로 오래 머무르면 제품 리스크가 커진다.

Worked Example: latency SLO는 평균이 아니라 꼬리를 본다

섹션 제목: “Worked Example: latency SLO는 평균이 아니라 꼬리를 본다”

응답 시간이 아래처럼 분포한다고 하자.

구간요청 수
0~100ms70,000
100~300ms20,000
300ms~1s8,000
1s 초과2,000

전체 요청은 100,000건이고, 300ms 이내 요청은 90,000건이다.

300ms latency SLI = 90,000 / 100,000 = 90%
1s latency SLI = 98,000 / 100,000 = 98%

평균이 180ms라고 해도 2,000명의 요청이 1초를 넘었다면 일부 사용자는 분명히 느리다고 느낀다. latency SLO는 평균보다 “몇 퍼센트의 사용자가 기준 안에 들어왔는가”로 잡는 편이 사용자 경험에 가깝다.

이 예시에서 99% of requests under 1s를 SLO로 둔다면 현재 98%이므로 위반이다. 반대로 95% under 1s라면 달성 중이다. 목표값은 “사용자에게 중요한 꼬리 지연을 어디까지 허용할 것인가”라는 제품 결정이다.

처음부터 서비스당 SLO를 10개 만들면 팀은 무엇을 보고 움직일지 모른다. 초반에는 핵심 사용자 여정 하나에 2~3개면 충분하다.

좋은 시작 조합:

  • Availability: 핵심 요청 성공률.
  • Latency: p95 또는 p99가 사용자 기대 안에 들어오는 비율.
  • Freshness 또는 completion: 비동기 처리 결과가 약속 시간 안에 끝나는 비율.

나중에 데이터 유실, 정확성, 지역별 품질처럼 더 중요한 위험이 보이면 추가한다. SLO는 대시보드 항목 수를 늘리는 일이 아니라 의사결정 기준을 줄이는 일이다.

Error Budget은 SLO가 허용하는 실패량이다.

Error Budget = 1 - SLO

SLO가 99.9%라면 Error Budget은 0.1%다. 30일 동안 3,000,000건의 요청이 있다면 허용 실패는 3,000건이다. 시간 기준으로 보면 30일은 43,200분이므로 0.1%는 43.2분이다.

30일 * 24시간 * 60분 = 43,200분
43,200분 * 0.001 = 43.2분

이 숫자는 “장애가 나도 괜찮다”는 면죄부가 아니다. 완벽한 시스템은 없으니, 허용 실패량을 넘기기 전에 배포 속도와 안정화 투자를 조절하자는 약속이다.

Burn Rate는 예산을 태우는 속도다

섹션 제목: “Burn Rate는 예산을 태우는 속도다”

Burn rate는 Error Budget이 예상보다 얼마나 빠르게 줄어드는지 보는 지표다. 30일 SLO라면 하루에 전체 budget의 약 1/30, 즉 3.33% 정도를 쓰는 것이 균등한 속도다.

Worked example:

월간 Error Budget = 실패 3,000건
월 5일 현재 사용량 = 실패 2,000건
현재 사용률 = 2,000 / 3,000 = 66.7%
5일 시점의 균등 사용률 = 5 / 30 = 16.7%
Burn rate = 66.7 / 16.7 = 약 4배

이 서비스는 “아직 33.3% 남았다”가 아니라 “현재 속도면 약 7.5일 만에 월간 budget을 다 쓴다”로 읽어야 한다.

하루 평균 실패 = 2,000 / 5 = 400건
예산 소진 예상일 = 3,000 / 400 = 7.5일

Burn rate가 좋은 이유는 절대 잔여량보다 행동을 빨리 결정하게 해준다는 점이다. 월 초에 budget 60%가 남아 있어도 burn rate가 8배라면 지금 배포를 멈추고 원인을 봐야 한다.

Burn rate는 하나의 창만 보면 오해할 수 있다.

관찰의미행동
5분 burn rate가 매우 높고 1시간 burn rate는 낮다짧은 스파이크일 수 있다즉시 관찰하되 자동 페이지는 조건을 더 본다
5분과 1시간 burn rate가 모두 높다현재 진행 중인 사용자 영향 가능성이 높다incident 선언과 완화 조치를 준비한다
6시간 burn rate가 높고 5분은 낮다이미 지나간 장애가 budget을 많이 태웠다postmortem과 배포 정책 조정이 필요하다
3일 burn rate가 꾸준히 높다만성 품질 저하가 있다기능 배포보다 구조적 안정화가 우선이다

짧은 창은 빠른 탐지에 좋고, 긴 창은 지속 영향을 확인하는 데 좋다. 그래서 실제 알람은 보통 “짧은 창에서 급격히 나쁘고, 긴 창에서도 의미 있게 나쁘다” 같은 조합을 쓴다.

손계산 예시:

30일 Error Budget = 3,000건
1시간 균등 예산 = 3,000 / (30 * 24) = 약 4.17건
최근 1시간 실패 = 50건
1시간 burn rate = 50 / 4.17 = 약 12배

1시간 burn rate가 12배라면 그 상태가 오래 지속될 수 없다는 뜻이다. 단순히 “현재 에러율 1%“라고 보는 것보다, SLO 기간 전체 예산을 얼마나 빠르게 쓰는지 보는 편이 행동으로 연결된다.

Error Budget 정책 예시

50% 이상

정상 구간이다. 카나리 배포와 일반 기능 배포를 계속할 수 있다.

Burn rate가 낮고 최근 사고의 Action Items가 밀리지 않을 때

25~50%

주의 구간이다. 큰 변경은 리뷰하고, 고위험 배포는 나눈다.

배포 직후 오류가 늘었거나 외부 의존성이 불안정할 때

25% 미만

위험 구간이다. 신규 기능보다 안정화, 롤백 준비, 알람 정비를 우선한다.

이 속도면 SLO 기간 안에 budget이 소진될 때

0% 이하

소진 구간이다. 일반 배포를 멈추고 SLO 회복 계획을 먼저 실행한다.

사용자 영향이 이미 허용치를 넘었고 계약 리스크까지 가까울 때

정책은 팀 상황에 맞게 조정할 수 있지만, 중요한 것은 기준이 미리 정해져 있어야 한다는 점이다. 장애가 난 뒤 “이번 배포는 예외로 하자”를 반복하면 Error Budget은 갈등을 줄이는 도구가 아니라 또 다른 회의 주제가 된다.

Error Budget Policy에는 예외도 적어야 한다

섹션 제목: “Error Budget Policy에는 예외도 적어야 한다”

정책이 너무 단순하면 실제 운영에서 바로 우회된다.

예시:

Budget 상태기본 행동허용 예외
50% 이상일반 배포 허용없음
25~50%고위험 변경 리뷰보안 긴급 패치, 장애 완화 변경
25% 미만신규 기능 동결데이터 유실 방지, 법적 기한 패치
0% 이하모든 비필수 변경 동결CTO 또는 incident commander 승인 긴급 변경

예외를 적는 이유는 정책을 약하게 만들기 위해서가 아니다. 예외가 명문화되어 있어야 사고 중 임의 판단이 줄어든다. 특히 보안 패치, 데이터 보전, 장애 완화 변경은 일반 신규 기능과 다른 위험을 가진다.

반례: 사용자 실패가 아닌 트래픽을 분모에 넣으면 정책이 깨진다

섹션 제목: “반례: 사용자 실패가 아닌 트래픽을 분모에 넣으면 정책이 깨진다”

부하 테스트, 보안 스캔, 내부 배치 재처리, synthetic probe 실패를 실제 사용자 요청과 같은 분모에 넣으면 서비스가 건강한데도 SLO가 깨질 수 있다. 이 상태에서 배포를 동결하면 SRE 정책이 제품 개발을 부당하게 막는다.

반대로 실제 모바일 앱 사용자의 timeout을 서버 5xx가 아니라는 이유로 빼면 사용자는 실패했는데 SLO는 정상으로 보인다. 따라서 SLO가 이상하게 보일 때는 목표값보다 먼저 분모와 측정 지점을 확인한다.

6. Incident Response: 원인 분석보다 사용자 영향 완화가 먼저다

섹션 제목: “6. Incident Response: 원인 분석보다 사용자 영향 완화가 먼저다”

Incident는 현재 사용자 영향이 있거나 곧 생길 수 있는 사고다. Incident response의 첫 목표는 완벽한 원인 분석이 아니라 영향 축소다.

장애 중에는 시간이 품질이다. 원인을 정확히 찾느라 40분을 쓰는 것보다, 최근 배포 롤백으로 10분 만에 에러율을 낮추고 나중에 원인을 분석하는 편이 사용자에게 낫다.

Severity는 대응 속도와 커뮤니케이션 범위를 정한다

섹션 제목: “Severity는 대응 속도와 커뮤니케이션 범위를 정한다”
등급정의첫 대응 목표보통 필요한 행동
SEV1전체 서비스 중단, 결제/로그인 불가, 데이터 유실 위험즉시Incident Commander 지정, 경영진/고객 커뮤니케이션, 변경 동결
SEV2핵심 기능 장애 또는 큰 성능 저하30분 이내담당팀 호출, 완화 조치, 상태 공유
SEV3일부 사용자 영향, 우회 가능, 성능 저하업무 시간 내담당자 배정, 원인 조사, 추적 이슈 생성
SEV4경미한 결함, 내부 도구 불편백로그일반 이슈로 처리

Severity는 누가 더 잘못했는지를 나타내지 않는다. 사용자 영향, 데이터 위험, 매출 영향, 대응 긴급도를 정렬하는 언어다.

Severity는 낮게 잡는 것이 안전하지 않다

섹션 제목: “Severity는 낮게 잡는 것이 안전하지 않다”

팀은 종종 SEV를 낮게 잡고 싶어 한다. 낮은 SEV는 덜 시끄럽고 부담이 적기 때문이다. 하지만 심각도를 낮게 잡으면 필요한 사람이 늦게 호출되고, 커뮤니케이션도 늦어진다.

반대로 모든 일을 SEV1로 잡아도 실패한다. 조직이 피로해지고 실제 긴급 사고의 신호가 약해진다. 좋은 severity 기준은 아래 질문으로 정한다.

  • 사용자가 핵심 여정을 완료할 수 있는가?
  • 데이터 유실이나 보안 위험이 있는가?
  • 우회 경로가 있는가?
  • 영향 범위가 일부 고객인가, 대부분 고객인가?
  • 해결이 지연될수록 비용이 급격히 커지는가?

예를 들어 관리자 페이지의 일부 필터가 느린 것은 보통 SEV3이다. 하지만 같은 느림이 결제 승인 경로에서 발생해 결제 성공률을 떨어뜨리면 SEV1 또는 SEV2가 된다. 같은 기술 증상이라도 사용자 영향이 다르면 severity도 달라진다.

Incident Response 흐름

  1. 탐지

    알람, synthetic probe, 사용자 제보, 로그/메트릭 이상으로 사고 후보를 발견한다.

  2. 분류

    사용자 영향, 범위, 데이터 위험을 보고 severity와 담당 역할을 정한다.

  3. 완화

    롤백, 기능 플래그 OFF, 트래픽 우회, rate limit, 스케일 아웃처럼 영향을 줄이는 행동을 먼저 한다.

  4. 해결

    근본 원인을 수정하고 SLI가 정상 범위로 돌아왔는지 확인한다.

  5. 학습

    Postmortem으로 타임라인과 Action Items를 남기고 다음 사고 가능성을 줄인다.

역할이 없으면 사람은 많은데 결정이 늦다

섹션 제목: “역할이 없으면 사람은 많은데 결정이 늦다”

큰 사고에서는 “다 같이 원인 찾기”가 오히려 느릴 수 있다. 최소 역할을 분리하면 커뮤니케이션 비용이 줄어든다.

역할책임
Incident Commander전체 판단, 우선순위, 종료 선언을 맡는다
Operations Lead롤백, 스케일 조정, 기능 플래그 등 실제 완화 조치를 실행한다
Communications LeadSlack, 고객 공지, 이해관계자 업데이트를 정리한다
Scribe시간순 사건, 결정, 관찰값을 기록한다

작은 팀에서는 한 사람이 여러 역할을 겸할 수 있다. 그래도 “누가 최종 결정을 하는가”와 “누가 기록하는가”는 분리하는 편이 좋다.

장애 중에는 모든 선택지가 그럴듯해 보인다. 아래 표는 원인 확정 전에도 쓸 수 있는 완화 기준이다.

관찰먼저 고려할 완화
최근 배포 직후 에러율 급증롤백, feature flag OFF원인 분석 없이도 이전 정상 상태로 돌아갈 가능성이 높다
특정 엔드포인트만 실패해당 기능 우회, rate limit, 라우팅 차단전체 서비스를 내리지 않고 영향 범위를 줄인다
외부 API timeout 급증timeout 단축, fallback, circuit breaker대기 중인 요청이 내부 리소스를 고갈시키는 것을 막는다
queue backlog 급증producer 제한, worker 증설, 우선순위 분리적체가 다른 작업으로 전파되는 것을 막는다
DB connection pool 고갈트래픽 제한, 느린 쿼리 차단, 롤백단순 task 재시작은 재발 가능성이 높다

완화는 임시 조치다. 하지만 임시 조치가 사용자 영향 시간을 줄이면 MTTR이 내려간다. 근본 수정은 사고가 안정화된 뒤 더 차분하게 한다.

Worked Example: 결제 API 에러율이 35%로 급증했다

섹션 제목: “Worked Example: 결제 API 에러율이 35%로 급증했다”

상황: 오후 2시, 결제 API 5xx 비율이 평소 0.1%에서 35%로 올랐다. 10분 전 새 버전이 배포됐다.

첫 15분의 좋은 판단은 아래와 같다.

  1. SEV1 또는 SEV2를 선언한다. 결제는 핵심 사용자 여정이므로 낮게 잡지 않는다.
  2. 최근 배포와 에러율 상승의 시간 상관관계를 확인한다.
  3. 원인 분석을 깊게 하기 전에 롤백 또는 기능 플래그 OFF 가능성을 본다.
  4. 롤백 후 5xx, 결제 성공률, p99 지연시간이 SLO 범위로 돌아오는지 확인한다.
  5. 정상화 뒤 Postmortem에서 왜 스테이징이나 카나리에서 잡히지 않았는지 본다.

여기서 나쁜 대응은 “정확한 SQL 원인을 찾을 때까지 롤백하지 않는다”다. 사용자가 결제를 못 하는 동안에는 원인 규명보다 영향 완화가 먼저다.

Runbook은 절차가 아니라 사고 중 의사결정 보조물이다

섹션 제목: “Runbook은 절차가 아니라 사고 중 의사결정 보조물이다”

좋은 Runbook은 긴 명령어 모음이 아니다. 장애 중 판단에 필요한 질문, 관찰 포인트, 완화 선택지를 짧게 연결한다.

증상: p99 latency가 2초를 넘고 Error Budget burn rate가 5배 이상이다.
먼저 볼 것:
- 최근 배포가 있었는가?
- 특정 엔드포인트만 느린가, 전체가 느린가?
- DB connection pool, 외부 API timeout, queue backlog 중 무엇이 같이 움직이는가?
완화 선택지:
- 최근 배포와 강하게 연결되면 롤백한다.
- 특정 기능만 느리면 feature flag로 끈다.
- 외부 API timeout이면 fallback 또는 circuit breaker를 확인한다.
- queue backlog면 producer rate와 worker 처리량을 같이 본다.

Runbook은 자주 바뀐다. Postmortem Action Item으로 Runbook이 업데이트되지 않으면, 다음 사고 때 같은 빈칸을 다시 겪는다.

Escalation은 실패가 아니라 안전장치다

섹션 제목: “Escalation은 실패가 아니라 안전장치다”

Escalation은 담당자가 무능하다는 뜻이 아니다. 사고가 커질수록 정보, 권한, 전문성이 더 필요해진다는 뜻이다.

좋은 escalation 기준:

  • 15분 안에 owner가 응답하지 않으면 secondary on-call 호출.
  • 30분 안에 사용자 영향이 줄지 않으면 incident commander가 상위 severity 검토.
  • 데이터 유실 가능성이 있으면 즉시 DB owner와 보안/법무 담당 경로 확인.
  • 고객 커뮤니케이션이 필요한 경우 communications lead를 별도 지정.

Escalation 기준이 없으면 사람들은 너무 늦게 도움을 요청한다. 늦은 escalation은 MTTR을 늘리고, 사고 후에는 “왜 더 빨리 부르지 않았나”라는 비난으로 흐르기 쉽다.

7. Postmortem과 Blameless: 사고를 조직 학습으로 바꾸기

섹션 제목: “7. Postmortem과 Blameless: 사고를 조직 학습으로 바꾸기”

Postmortem은 사고 후 작성하는 학습 문서다. 목적은 책임자를 찾아내는 것이 아니라, 사고가 발생하고 커진 조건을 시스템 개선으로 바꾸는 것이다.

Blameless는 “아무도 책임지지 않는다”가 아니다. 개인을 공격하지 않되, 개선 항목에는 담당자, 기한, 검증 방법을 반드시 둔다. 분석 단계에서는 “왜 이 행동이 합리적으로 보였는가”를 묻고, 실행 단계에서는 “누가 언제까지 무엇을 바꿀 것인가”를 정한다.

항목IncidentProblem
초점지금 발생한 사용자 영향반복되는 근본 원인
목표빠른 완화와 복구재발 가능성 감소
시간 범위분, 시간 단위일, 주, 분기 단위
예시결제 API 5xx 35%결제 API DB connection pool 설정과 테스트 부재

Incident 대응이 잘 끝나도 Problem을 남겨두면 같은 장애는 다시 온다. Postmortem은 Incident를 Problem 관리로 연결하는 다리다.

Worked Example: 좋은 Action Item과 나쁜 Action Item

섹션 제목: “Worked Example: 좋은 Action Item과 나쁜 Action Item”

장애 원인: 신규 배포에서 DB 인덱스가 빠져 p99 지연시간이 120ms에서 4,200ms로 증가했고, 롤백으로 복구했다.

나쁜 Action Item왜 나쁜가좋은 Action Item
모니터링 강화무엇을 어디에 추가할지 알 수 없다user-api의 p99 latency와 DB slow query count를 같은 대시보드에 추가한다. 담당자와 기한을 둔다
코드 리뷰 잘하기행동이 추상적이다DB migration PR template에 인덱스 영향, explain 결과, rollback plan 체크박스를 추가한다
다시는 실수하지 않기시스템 개선이 아니다스테이징에서 대표 쿼리 5개를 배포 전 자동 실행하고 p95가 기준선을 넘으면 배포를 막는다

좋은 Action Item은 세 가지를 가진다.

  • 담당자: 누가 끝낼지 명확하다.
  • 기한: 언제까지 끝낼지 명확하다.
  • 검증 방법: 끝났다고 판단할 수 있는 관찰값이 있다.

5 Whys는 사람 탓으로 끝나면 실패다

섹션 제목: “5 Whys는 사람 탓으로 끝나면 실패다”

예시:

1. 왜 응답이 느렸나? -> 대표 조회 쿼리가 full scan을 했다.
2. 왜 full scan을 했나? -> 새 필터 컬럼에 인덱스가 없었다.
3. 왜 인덱스가 없었나? -> migration 리뷰에서 쿼리 경로를 확인하지 않았다.
4. 왜 확인하지 않았나? -> PR template과 리뷰 체크리스트에 DB 성능 항목이 없었다.
5. 왜 없었나? -> 배포 전 성능 기준선을 관리하는 소유자가 없었다.

마지막 답이 “누가 실수했다”로 끝나면 다음 행동이 비난이나 교육으로만 흐른다. 마지막 답이 시스템 조건으로 끝나야 도구, 체크리스트, 테스트, 소유권 개선으로 이어진다.

긴 템플릿을 외우는 것보다 어떤 정보가 빠지면 학습이 사라지는지 아는 것이 중요하다.

요약:
- 2026-07-03 11:15~11:52 KST 동안 user-api p99 latency가 120ms에서 4.2s로 증가했다.
- 전체 사용자 중 약 18%가 검색 결과 로딩 지연을 경험했다.
- 최근 배포 롤백 후 latency가 정상 범위로 돌아왔다.
타임라인:
- 11:10 v1.4.2 배포 완료
- 11:15 p99 latency 급증 시작
- 11:17 latency SLO burn rate 6배 알람
- 11:22 SEV2 선언
- 11:30 slow query에서 신규 필터 full scan 확인
- 11:40 롤백 시작
- 11:52 SLI 정상화
원인:
- 신규 필터 컬럼에 인덱스가 없었다.
- migration 리뷰에서 대표 쿼리 explain을 확인하지 않았다.
- PR template에 성능 영향 확인 항목이 없었다.
Action Items:
- migration PR template에 explain 결과 첨부 항목 추가. 담당 A, 기한 2026-07-10.
- staging에서 대표 검색 쿼리 p95 기준선을 넘으면 배포를 막는 CI job 추가. 담당 B, 기한 2026-07-17.
- user-api SLO 대시보드에 최근 배포 마커를 표시. 담당 C, 기한 2026-07-12.

이 예시는 긴 문서가 아니지만 학습에 필요한 핵심을 갖고 있다. 사용자 영향, 시간, 완화, 원인, 시스템 개선 항목이 모두 남아 있기 때문이다.

좋은 postmortem은 읽는 사람이 다음 질문에 답할 수 있게 한다.

  • 언제부터 언제까지 사용자 영향이 있었는가?
  • 어떤 SLI가 얼마나 나빠졌는가?
  • 어떤 완화가 효과가 있었고, 어떤 시도는 효과가 없었는가?
  • 사고가 커진 구조적 조건은 무엇인가?
  • 다음에 같은 조건을 더 빨리 발견하거나 막는 변경은 무엇인가?

아래 신호가 있으면 postmortem이 기록으로는 남았지만 학습으로는 약하다.

  • 타임라인이 “오후쯤”, “나중에”처럼 모호하다.
  • 사용자 영향이 “일부 장애”처럼 정성적으로만 적혀 있다.
  • Action Item이 모두 “문서화”, “교육”, “주의”다.
  • 담당자와 기한이 없다.
  • 이전 같은 유형 사고와 연결하지 않는다.

8. Toil: 사람 시간을 시스템 개선으로 돌리기

섹션 제목: “8. Toil: 사람 시간을 시스템 개선으로 돌리기”

Toil은 수동적이고, 반복적이고, 자동화 가능하며, 장기 가치가 낮은 운영 작업이다. 알람을 보고 매번 서버를 재시작하는 일은 toil이다. 서버가 스스로 교체되도록 health check와 auto healing을 만드는 일은 엔지니어링이다.

작업Toil인가이유
매주 같은 순서로 수동 배포반복적이고 자동화 가능하며 장기 가치가 낮다
알람이 울릴 때마다 ECS task 수동 재시작근본 원인 해결 없이 사람 개입으로만 복구한다
처음 해보는 데이터 마이그레이션 설계보통 아님일회성 판단과 설계가 필요하다
장애 뒤 자동 롤백 파이프라인 구현아님앞으로의 toil과 MTTR을 줄이는 엔지니어링 작업이다

Google SRE에서 자주 언급되는 기준은 SRE 시간이 toil에 50% 이상 쓰이면 위험하다는 것이다. 숫자 자체보다 중요한 것은 추세다. 주 40시간 중 20시간 이상을 수동 복구, 반복 승인, 로그 추출에 쓴다면 신뢰성 개선에 쓸 시간이 사라진다.

Worked Example: 어떤 toil을 먼저 자동화할까

섹션 제목: “Worked Example: 어떤 toil을 먼저 자동화할까”

반복 작업이 세 개 있다고 하자.

항목주당 소요자동화 비용회수 기간판단
수동 배포2시간16시간8주중요하지만 비용이 크다
알람 후 ECS task 수동 재시작3시간4시간약 1.3주먼저 자동화할 가치가 높다
슬로우 쿼리 로그 수동 추출1시간8시간8주반복 요청이 더 늘 때 자동화한다

이 경우 첫 자동화 후보는 ECS task 수동 재시작이다. 회수 기간이 짧고, 장애 중 사람 개입을 줄여 MTTR도 낮출 수 있기 때문이다. Toil 자동화 우선순위는 단순히 “귀찮은 일”이 아니라 시간 절감, 장애 영향, 재발 가능성을 같이 보고 정한다.

자동화 우선순위는 회수 기간만으로 정하지 않는다

섹션 제목: “자동화 우선순위는 회수 기간만으로 정하지 않는다”

회수 기간이 짧아도 위험한 자동화가 있다. 예를 들어 장애 때 DB를 자동으로 재시작하는 스크립트는 사람 시간을 줄일 수 있지만, 원인 분석 없이 데이터베이스를 반복 재시작해 장애를 키울 수 있다.

자동화 후보는 아래 네 축을 함께 본다.

기준질문높은 점수의 의미
시간 절감주당 몇 시간을 줄이는가?반복 업무가 많고 회수 기간이 짧다
장애 영향자동화가 MTTR이나 사용자 영향을 줄이는가?사고 중 복구 시간이 줄어든다
안전성잘못 실행돼도 피해가 제한되는가?dry-run, 승인, rollback이 있다
학습 효과자동화가 원인을 더 잘 보이게 하는가?로그, 메트릭, audit trail이 남는다

좋은 자동화는 일을 숨기지 않는다. 사람이 하던 행동을 기계가 대신하더라도, 언제 왜 실행됐고 어떤 결과가 있었는지 관측 가능해야 한다.

Toil은 쌓이면 운영 부채가 된다. 기능 개발 부채가 코드 변경을 느리게 만들듯, 운영 부채는 사고 대응과 배포를 느리게 만든다.

운영 부채의 전형적인 모습:

  • 배포 전 확인해야 할 수동 체크가 너무 많아 배포가 늦어진다.
  • 알람이 많아 on-call이 계속 피로하다.
  • 장애 후 같은 대시보드 캡처를 매번 손으로 만든다.
  • 권한 요청, 리소스 생성, 로그 추출이 모두 특정 사람에게 몰린다.

이런 부채는 팀 규모가 커질수록 더 비싸진다. 한 명이 주 1시간 하던 일이 10개 팀으로 퍼지면 조직 전체에서는 큰 비용이 된다.

  • On-call 주간의 수동 조치 시간이 줄었는가?
  • 같은 알람에 대한 반복 ACK와 재시작이 줄었는가?
  • Runbook 실행 대신 자동 복구가 성공한 비율이 늘었는가?
  • Postmortem Action Items가 “문서 작성”보다 “자동 감지/자동 완화”로 이어졌는가?

Toil을 줄이는 목적은 사람을 덜 일하게 만드는 데서 끝나지 않는다. 남은 시간을 SLO 개선, 배포 안전성, 테스트, 자동화에 재투자해 다음 장애 가능성을 낮추는 것이다.

Alert Fatigue는 알람이 너무 많아 실제 중요한 알람까지 무시되는 상태다. 신뢰성 체계에서 알람은 많을수록 좋은 것이 아니다. 조치 가능한 알람이 좋은 알람이다.

나쁜 알람:

CPU > 60% 이면 즉시 PagerDuty 호출

좋은 알람:

결제 API 5xx 비율이 10분 동안 1% 초과
그리고 Error Budget burn rate가 4배 초과

CPU가 높아도 사용자가 성공하고 있다면 페이지를 걸지 않아도 될 수 있다. 반대로 CPU가 낮아도 외부 결제 승인 API가 실패하면 사용자는 결제를 못 한다. SRE 알람은 내부 원인보다 사용자 증상에 먼저 붙인다.

알람은 조치 수준을 구분해야 한다

섹션 제목: “알람은 조치 수준을 구분해야 한다”

모든 이상 신호가 사람을 깨워야 하는 것은 아니다.

신호알림 채널이유
결제 성공률 급락, burn rate 10배PagerDuty즉시 사용자 영향이 있고 budget 소진 속도가 빠르다
p99 latency가 30분 동안 SLO 근처Slack 경고대응 준비는 필요하지만 즉시 깨울 수준은 아닐 수 있다
CPU 80% 단독 상승대시보드 또는 ticket사용자 영향 없이 원인 지표만 오른 상태일 수 있다
Postmortem Action Item 기한 초과주간 리뷰사고 중 호출보다 계획 조정이 맞다
synthetic probe 1회 실패재시도 후 경고일시 네트워크 문제일 수 있다

좋은 알람 체계는 “깨워야 하는 알람”, “업무 시간에 볼 알람”, “대시보드에서 추세로 볼 신호”를 나눈다. 이 구분이 없으면 on-call은 모든 알람을 같은 강도로 받아 결국 무시하게 된다.

한 달 동안 PagerDuty 알람이 180건 울렸고, 실제 조치가 필요했던 알람이 18건이었다고 하자.

조치 필요 비율 = 18 / 180 = 10%
불필요하거나 중복된 알람 = 90%

이 상태에서는 중요한 알람도 신뢰를 잃는다. 목표가 반드시 100%일 필요는 없지만, pager를 울리는 알람은 대부분 조치 가능해야 한다. 조치 필요 비율이 낮다면 임계값을 높이는 것보다 먼저 중복 알람, 원인 기반 알람, non-actionable 알람을 분리한다.

실패 신호의미먼저 의심할 개념
SLO 대시보드는 있지만 배포 판단에 쓰지 않는다SLO가 목표가 아니라 장식이 됐다Error Budget Policy
알람의 대부분이 조치 없이 ACK된다알람 신뢰도가 낮다Alert Fatigue
장애 때마다 “누가 결정하나”가 새로 논의된다역할과 에스컬레이션이 없다Incident Response
Postmortem은 쓰지만 같은 장애가 반복된다Action Items가 실행되지 않는다Problem 관리
SLO가 자주 깨지는데 기능 배포가 계속된다예산과 정책이 연결되지 않았다Error Budget
SLO가 너무 높아 작은 변경도 모두 막힌다목표가 기준선과 비용을 반영하지 못했다SLO 설정
On-call이 매주 같은 수동 복구를 한다toil이 엔지니어링 시간을 잠식한다Toil 관리
SEV1이 너무 자주 선언된다severity 기준이 사용자 영향과 맞지 않다Severity 분류

실패 신호는 처방이 아니다. 하지만 어떤 개념이 깨졌는지 빠르게 좁혀준다.

항목SLOSLA
대상내부 팀외부 고객, 파트너
성격목표와 운영 기준계약과 페널티
위반 시 결과배포 제한, 안정화 작업, Postmortem크레딧, 환불, 계약 리스크
권장 관계SLA보다 엄격해야 한다SLO보다 느슨해야 한다

SLA가 99.9%라면 내부 SLO는 99.95%처럼 더 엄격하게 둘 수 있다. 그래야 계약 위반 전에 내부 경보가 울린다.

DevOps는 개발과 운영의 협업 문화와 방향성에 가깝다. SRE는 그 방향성을 SLO, Error Budget, toil 관리, incident response 같은 구체적 운영 메커니즘으로 구현하는 방법에 가깝다.

항목DevOpsSRE
초점협업 문화, 자동화, 빠른 피드백신뢰성 목표와 운영 정책
대표 지표배포 빈도, 변경 실패율, 리드타임, MTTRSLI, SLO, Error Budget, toil
질문개발과 운영이 어떻게 같이 일할까어느 정도의 실패를 허용하고 어떻게 통제할까

작은 팀은 “SRE 팀”이라는 조직 없이도 SRE 프랙티스를 사용할 수 있다. 중요한 것은 직함이 아니라 신뢰성을 측정하고 정책으로 연결하는 습관이다.

Runbook이 많아도 복구가 느릴 수 있다

섹션 제목: “Runbook이 많아도 복구가 느릴 수 있다”

Runbook 수가 많다는 것은 운영 지식이 많다는 뜻일 수 있지만, 사고 중에는 오히려 찾기 어려울 수 있다. 좋은 runbook 체계는 증상에서 출발한다.

나쁜 구조:

ECS 운영 절차
RDS 운영 절차
ALB 운영 절차
CloudWatch 운영 절차

좋은 구조:

결제 API 5xx 급증
결제 API p99 latency 급증
주문 queue backlog 증가
로그인 성공률 하락

사고 중 사람은 “RDS 문서 어디 있지”보다 “결제 p99가 급증했다면 무엇을 먼저 보지”를 찾는다. 도구별 문서는 참고 자료이고, runbook은 증상별 진입점이어야 한다.

MTTR, MTTF, MTBF는 서로 다른 개선 방향을 가리킨다

섹션 제목: “MTTR, MTTF, MTBF는 서로 다른 개선 방향을 가리킨다”
지표나쁠 때 우선 볼 것
MTTR장애 발생 후 복구까지 걸리는 평균 시간Runbook, 롤백 자동화, incident role, 관측성
MTTF정상 상태에서 다음 장애까지 걸리는 평균 시간테스트, 코드 품질, 배포 안전성, 의존성 격리
MTBF장애와 장애 사이 평균 간격반복 사고 제거, Problem 관리

MTTR이 높으면 “빨리 복구하는 능력”이 약한 것이다. MTTF가 낮으면 “장애가 덜 나게 만드는 능력”이 약한 것이다. 둘 다 나쁘면 신규 기능보다 안정화 스프린트가 먼저다.

Blameless는 accountability-free가 아니다

섹션 제목: “Blameless는 accountability-free가 아니다”

Blameless의 반대는 책임 있는 실행이 아니라 개인 비난이다. 개인을 비난하지 않는다고 해서 Action Item의 담당자와 기한을 빼면 postmortem은 효과를 잃는다.

좋은 문장:

위험한 설정이 리뷰에서 누락될 수 있는 프로세스였고,
이를 막기 위해 migration PR template과 staging 성능 검사를 추가한다.
담당자는 A, 기한은 다음 금요일, 검증은 CI job 통과다.

나쁜 문장:

A가 설정을 놓쳤다. 앞으로 조심한다.

Error Budget은 품질을 포기하는 장치가 아니다

섹션 제목: “Error Budget은 품질을 포기하는 장치가 아니다”

Error Budget은 “이만큼 실패해도 된다”가 아니라 “이만큼 실패하면 속도를 줄인다”는 정책이다. budget이 남았다고 위험한 배포를 무조건 해도 되는 것은 아니다. 데이터 유실, 보안 사고, 법적 리스크처럼 SLO 숫자로만 표현할 수 없는 위험은 별도 중단 조건을 가져야 한다.

SRE를 처음 도입할 때 모든 것을 한 번에 만들 필요는 없다. 한 서비스, 두세 개의 SLI, 하나의 Error Budget Policy로 시작하면 충분하다.

SRE 운영 루프
flowchart TD
Service["핵심 서비스 선택"] --> SLI["사용자 중심 SLI 정의"]
SLI --> Baseline["2주~30일 기준선 수집"]
Baseline --> SLO["현실적인 SLO 설정"]
SLO --> Budget["Error Budget 계산"]
Budget --> Policy["배포/알람/안정화 정책 연결"]
Policy --> Incident["Incident Response"]
Incident --> Postmortem["Postmortem과 Action Items"]
Postmortem --> Toil["Toil 제거와 자동화"]
Toil --> SLI
기간목표산출물
1주차핵심 사용자 여정 1개를 고른다예: 로그인, 결제, 주문 생성
2주차SLI 2~3개를 정하고 측정 지점을 통일한다성공률, p99 지연시간, 처리 완료율
3주차기준선을 보고 첫 SLO를 정한다30일 rolling window 99.9% 같은 목표
4주차Error Budget Policy와 알람 기준을 붙인다budget 25% 미만이면 고위험 배포 제한

이때 긴 CloudFormation 템플릿이나 복잡한 대시보드부터 만들 필요는 없다. 먼저 팀이 같은 숫자를 보고 같은 행동을 하게 만드는 것이 목표다.

서비스 유형시작 SLO 예시판단 기준
결제, 인증, 권한99.9%~99.99%사용자와 매출 영향이 직접적이며 복구 지연 비용이 크다
일반 CRUD API99.5%~99.9%일부 실패는 재시도와 우회가 가능하다
비동기 worker99%~99.5%즉시 성공보다 일정 시간 내 처리 완료가 중요하다
내부 관리자 도구99% 전후외부 사용자 영향이 낮고 업무 시간 대응이 가능하다

이 표는 정답표가 아니다. 같은 결제라도 초기 스타트업의 첫 서비스와 대규모 금융 서비스의 계약 서비스는 목표가 다르다. 기준선, 사용자 기대, 계약, 비용을 함께 봐야 한다.

SRE 시각에서 새 시스템 도입 전에 묻는 질문

섹션 제목: “SRE 시각에서 새 시스템 도입 전에 묻는 질문”

새 queue, cache, 외부 API, 내부 플랫폼을 도입할 때 아래 질문을 먼저 묻는다.

  1. 이 시스템이 잘 동작한다는 SLI는 무엇인가?
  2. 실패하면 어느 사용자 여정과 어느 팀에 영향을 주는가?
  3. 장애 중 자동 완화가 가능한가, 사람이 개입해야 하는가?
  4. 도입 후 toil이 줄어드는가, 새로운 반복 작업이 생기는가?
  5. 사고가 나면 postmortem으로 남길 수 있는 책임 경계가 있는가?

이 질문에 답하지 못하면 도입 자체가 나쁘다는 뜻은 아니다. 다만 운영 비용을 아직 측정하지 못하고 있다는 뜻이다.

플랫폼 팀은 각 서비스 팀이 SLI와 SLO를 쉽게 정의하도록 템플릿, 대시보드, 알람 라우팅, 배포 정책을 제공한다. 목표는 “모든 팀 대신 운영해주기”가 아니라, 각 팀이 자기 서비스의 신뢰성을 같은 언어로 관리하게 만드는 것이다.

예를 들어 신규 서비스 템플릿에 아래 항목을 포함할 수 있다.

  • 기본 SLI: availability, p99 latency, request count.
  • 기본 알람: 사용자 영향 기반 5xx rate, latency SLO burn rate.
  • 기본 대시보드: SLO attainment, Error Budget remaining, 최근 배포 표시.
  • 기본 Runbook 링크: 롤백, feature flag, 외부 의존성 장애 확인.

보안 패치도 Error Budget 사고를 빌려올 수 있다. 예를 들어 Critical CVE는 72시간, High CVE는 7일 안에 패치한다는 내부 SLO를 둘 수 있다. 기한 초과가 누적되면 신규 기능보다 base image 갱신 자동화와 dependency update 파이프라인을 먼저 처리한다.

여기서 핵심은 “보안도 SRE처럼 보자”가 아니라, 허용 지연량을 수치로 정하고 초과하면 속도를 조절한다는 구조다.

제품 팀에게 SRE는 “운영팀의 별도 업무”가 아니다. 사용자는 기능이 존재하는지보다 기능이 제때 성공하는지를 체감한다. 따라서 핵심 사용자 여정별 SLI를 제품 지표와 함께 보는 것이 좋다.

예시:

  • 회원가입 완료율이 떨어졌는데, API 성공률 SLI도 같이 떨어졌는가?
  • 결제 전환율이 하락했는데, p99 latency와 외부 결제 승인 timeout이 같이 올랐는가?
  • 검색 사용량이 줄었는데, 검색 API 오류보다 결과 품질이나 latency SLI가 문제인가?

SRE 지표는 제품 지표를 대체하지 않는다. 제품 지표가 나빠졌을 때 기술 신뢰성이 원인인지 구분하는 보조 축이다.

13. 선택 부록: 손으로 해보는 작은 연습

섹션 제목: “13. 선택 부록: 손으로 해보는 작은 연습”

이 절은 긴 운영 런북이 아니라 개념을 확인하기 위한 짧은 연습이다.

서비스 A는 월 1,200,000건의 요청이 있고 SLO는 99.9%다.

허용 실패 = 1,200,000 * 0.001 = 1,200건
30일 기준 허용 다운타임 = 43.2분

월 10일에 실패가 900건이라면:

현재 사용률 = 900 / 1,200 = 75%
균등 사용률 = 10 / 30 = 33.3%
burn rate = 75 / 33.3 = 약 2.25배

아직 25%가 남았지만 이 속도면 월말 전에 소진된다. 다음 큰 배포는 원인 분석 뒤로 미루는 것이 합리적이다.

아래 요청을 모두 결제 API SLI 분모에 넣어야 할까?

요청포함 여부이유
실제 사용자의 결제 승인 요청포함사용자 여정의 핵심 결과다
내부 부하 테스트 요청보통 제외실제 사용자 실패가 아니며 SLO를 왜곡할 수 있다
synthetic canary 결제 요청별도 SLI 권장운영 감지에는 유용하지만 실제 사용자 분모와 섞으면 해석이 어려워진다
모바일 앱 timeout포함 검토서버가 200을 반환했어도 사용자는 실패했을 수 있다

SLI 분모는 정책을 바꾼다. 분모가 잘못되면 좋은 팀도 잘못된 결정을 내린다.

연습 3: Postmortem Action Item 다듬기

섹션 제목: “연습 3: Postmortem Action Item 다듬기”

나쁜 항목:

알람을 강화한다.

좋은 항목:

결제 API의 5xx rate가 10분 동안 1%를 넘고 burn rate가 4배를 넘으면 SEV2 알람을 보낸다.
담당: 플랫폼 A
기한: 2026-07-15
검증: staging에서 synthetic failure를 주입해 Slack 알람과 incident channel 생성을 확인한다.

좋은 Action Item은 누가 읽어도 완료 여부를 판단할 수 있다.

SRE 기본 체계 확인

  • 핵심 사용자 여정마다 사용자 관점의 SLI가 2~3개 정의되어 있다.
  • SLO 목표값은 기준선, 사용자 영향, 비용을 보고 정했다.
  • SLA와 SLO가 구분되어 있고, 내부 SLO가 외부 SLA보다 엄격하다.
  • Error Budget 잔여량과 burn rate가 배포 판단에 쓰인다.
  • Budget 구간별 행동 정책이 팀 문서에 명시되어 있다.
  • SEV1~SEV4 기준이 사용자 영향과 데이터 위험 기준으로 정의되어 있다.
  • Incident Commander, Communications, Scribe 역할이 사고 중에 빠르게 정해진다.

후속 개선과 운영 건강도 확인

  • Postmortem Action Items에는 담당자, 기한, 검증 방법이 있다.
  • 같은 유형 장애가 재발하면 기존 postmortem의 미완료 항목과 연결한다.
  • Runbook은 긴 명령어보다 관찰 포인트와 완화 선택지를 먼저 제공한다.
  • On-call 알람 중 실제 조치가 필요했던 비율을 주기적으로 본다.
  • 주간 toil 비율을 추적하고 50% 이상이면 자동화 후보를 우선한다.
  • SLO가 너무 높아 팀을 마비시키거나 너무 낮아 사용자 불편을 숨기지 않는지 재검토한다.
  • Google SRE Book: SRE 원칙, SLO, Error Budget, Postmortem 문화의 원전 격인 공개 자료.
  • Google SRE Workbook: SLO 구현, Error Budget Policy, 알람 설계처럼 실무 절차가 더 많은 자료.
  • OpenSLO: SLO를 YAML 같은 코드 형태로 정의해 버전 관리하려는 표준.
  • DORA Metrics: 배포 빈도, 변경 실패율, 리드타임, MTTR을 보는 개발 생산성/운영 성과 지표.
  • Chaos Engineering: 장애를 의도적으로 주입해 복원력과 Runbook을 검증하는 접근.
  • Synthetic Monitoring: 실제 사용자 요청을 흉내 내는 주기적 probe로 SLI를 관찰하는 방식.
  1. SRE는 관측 신호를 신뢰성 목표와 운영 정책으로 바꾸는 엔지니어링 규율이다.
  2. SLI는 측정값, SLO는 내부 목표, SLA는 외부 계약이며, SLO는 SLA보다 엄격해야 한다.
  3. Error Budget은 허용 실패량이고 burn rate는 그 예산을 태우는 속도다.
  4. Incident response는 원인 분석보다 사용자 영향 완화를 먼저 하고, postmortem으로 재발 가능성을 줄인다.
  5. Toil, alert fatigue, 미완료 Action Items는 SRE 체계가 건강하지 않다는 중요한 실패 신호다.