콘텐츠로 이동

SRE Practices

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

SRE(Site Reliability Engineering)는 “무엇을 관측하고, 어떤 기준으로 판단하고, 장애에 어떻게 대응하는가”를 체계화한 운영 방법론이다.

CloudWatch로 메트릭을 수집하는 것과 “그 데이터로 의사결정하는 것”은 완전히 다른 역량이다. 관측성 도구를 갖추는 것(L6 기존 토픽)과 SRE 프랙티스를 실행하는 것은 층위가 다르다.

“9가 몇 개인가”의 비즈니스 임팩트

가용성연간 다운타임의미
99% (2 nines)약 87.6시간스타트업 초기
99.9% (3 nines)약 8.7시간일반 서비스
99.99% (4 nines)약 52분결제/핵심 서비스
99.999% (5 nines)약 5분금융·의료

99%에서 99.9%로 올리는 것은 쉽지만, 99.99%에서 99.999%로 올리는 것은 수십 배의 비용이 든다. SRE는 이 트레이드오프를 수치로 관리한다.

실제 사고가 증명하는 SRE의 필요성

AWS는 업계에서 SRE를 가장 체계적으로 적용하는 조직 중 하나임에도, 대규모 장애가 반복적으로 발생한다.

  • 2025년 10월 AWS us-east-1 15시간 장애: DynamoDB의 DNS Enactor가 지연된 상태에서 오래된 DNS 정보를 덮어씀 → DNS Planner가 이를 “불필요한 항목”으로 판단해 us-east-1 전체 DynamoDB IP 레코드를 삭제 → EC2, Lambda, SQS 등 141개 AWS 서비스에 연쇄 장애. **근본 원인은 자동화 시스템 간 경쟁 조건(race condition)**이었으며, 복구 자동화가 오히려 장애를 심화시켰다.
  • 2017년 S3 us-east-1 4시간 장애: 운영자가 디버깅 명령어에 잘못된 인수를 입력 → 의도보다 훨씬 많은 서버 인스턴스 삭제 → S3 전체 불가. 피해 규모: S&P 500 기업의 54곳이 영향을 받았고, 아마존 주가는 0.5%($17억) 하락.

두 사고 모두 Postmortem → Action Items → 시스템 개선이라는 SRE 사이클이 없었다면 같은 유형의 장애가 더 빨리 재발했을 것이다. 특히 2025년 사고는 “자동화가 안전하다는 가정”을 검증하지 않은 것이 핵심 원인이었다.

플랫폼 엔지니어가 SRE를 알아야 하는 이유: 플랫폼 팀은 다른 개발팀의 인프라를 책임진다. 팀에 SRE 프랙티스가 없으면 “배포했더니 서비스가 느려졌다”는 말을 듣고도 어디서 시작해야 할지 모른다. SLI/SLO 체계가 있으면 “p99 응답시간이 500ms를 초과했다”처럼 대화할 수 있다.

프론트→플랫폼 브릿지: 프론트엔드에서 체감하던 “사이트가 느려요”는 정성적 불만이다. SRE는 이것을 Core Web Vitals(LCP, FID, CLS)처럼 SLI로 정량화한다. 프론트 경험이 있으면 사용자 관점의 SLI를 설계하는 데 유리하다.

Google SRE 팀이 내린 핵심 전제는 “완벽한 시스템은 없다” 는 것이다. 따라서 “얼마나 믿을 수 있는 시스템인가”를 수치로 정의하고, 그 수치를 기반으로 운영 의사결정을 내리는 프레임워크가 필요했다. SLI → SLO → SLA는 측정 → 목표 → 계약의 계층 구조로 설계됐다.

SLI (Service Level Indicator): 측정 지표

섹션 제목: “SLI (Service Level Indicator): 측정 지표”

SLI는 사용자가 실제로 경험하는 것을 측정하는 지표다. 서버 CPU 사용률이 아니라 “내 요청이 성공했는가?”, “응답이 빠른가?”처럼 사용자 관점에서 정의한다.

가용성 SLI = 성공 요청 수 / 전체 요청 수
지연시간 SLI = 300ms 이내 응답한 요청 비율
에러율 SLI = HTTP 5xx 응답 수 / 전체 요청 수

비유: 병원 응급실에서 의사가 환자 상태를 파악하려면 혈압, 맥박, 체온을 잰다. SLI는 서비스의 “바이탈 사인”이다.

SLO (Service Level Objective): 내부 목표값

섹션 제목: “SLO (Service Level Objective): 내부 목표값”

SLO는 SLI의 목표값이다. 예를 들어 “API 가용성 SLI가 한 달간 99.9% 이상이어야 한다”가 SLO다.

왜 100%가 아닌가?

  • 100% 가용성을 달성하려면 배포도 못 하고, 변경도 못 한다
  • 중복화·페일오버 등 비용이 기하급수적으로 증가한다
  • 사용자도 100%를 기대하지 않는다 (네트워크, 클라이언트 장애 등 자체 원인 존재)
  • 100%는 달성 불가능한 목표이므로, 달성 가능한 목표를 정하고 그 안에서 혁신하는 것이 SRE의 철학이다.

SLA (Service Level Agreement): 외부 계약

섹션 제목: “SLA (Service Level Agreement): 외부 계약”

SLA는 고객·파트너와의 계약이다. SLA를 위반하면 환불이나 서비스 크레딧 등 페널티가 발생한다.

핵심 관계: SLA < SLO

내부 목표(SLO)가 외부 계약(SLA)보다 엄격해야 한다. 예를 들어 SLA가 99.9%라면 내부 SLO는 99.95%로 설정한다. 내부에서 더 높은 목표를 달성해야 계약 위반을 예방할 수 있다.

SLA = 99.9% (외부 계약, 위반 시 페널티)
SLO = 99.95% (내부 목표, 위반 시 개선 액션)
SLI = 측정값 (예: 이번 달 실제 가용성 = 99.97%)

AWS CloudWatch Application Signals로 SLO 설정

섹션 제목: “AWS CloudWatch Application Signals로 SLO 설정”

AWS는 CloudWatch Application Signals에서 SLO를 직접 관리할 수 있다.

AWS 콘솔 → CloudWatch → Application Signals → Service Level Objectives
// CloudFormation으로 SLO 정의 예시
{
"Type": "AWS::ApplicationSignals::ServiceLevelObjective",
"Properties": {
"Name": "api-availability-slo",
"Description": "API 가용성 99.9% 목표",
"Sli": {
"SliMetric": {
"MetricType": "AVAILABILITY"
}
},
"Goal": {
"AttainmentGoal": 99.9,
"WarningThreshold": 99.95,
"Interval": {
"RollingInterval": {
"Duration": 30,
"DurationUnit": "DAY"
}
}
}
}
}

예상 출력 (CloudWatch Application Signals 대시보드):

Service: payment-api
SLO: api-availability-slo
Attainment: 99.97% (Goal: 99.9%) ✅
Error Budget Remaining: 87.3%
Requests: 2,847,293 (30 days)
Failed: 765

📖 더 보기: Amazon CloudWatch Application Signals SLO — AWS 공식 문서, SLO 생성부터 알람 설정까지

Core Web Vitals도 SLI의 일종이다: 프론트엔드에서 보던 LCP(Largest Contentful Paint) < 2.5초, FID < 100ms, CLS < 0.1 같은 기준도 SLI + SLO 구조 그대로다.


Error Budget — 혁신과 안정의 균형

섹션 제목: “Error Budget — 혁신과 안정의 균형”

전통적으로 개발팀과 운영팀은 항상 충돌한다.

  • 개발팀: “빨리 배포하자, 새 기능 내야 해”
  • 운영팀: “안 된다, 배포하면 장애 난다”

이 갈등의 근본 원인은 “얼마나 위험해도 되는가”에 대한 공통 언어가 없기 때문이다. Error Budget은 이를 수치로 해결한다.

Error Budget = 1 - SLO
예시:
SLO = 99.9%
Error Budget = 0.1%
월간 요청 수 = 3,000,000건
허용 가능한 실패 요청 = 3,000건
허용 가능한 다운타임 = 약 43.8분 (30일 기준 0.1%)

월간 허용 다운타임 계산:

30일 × 24시간 × 60분 = 43,200분
43,200분 × 0.1% = 43.2분

Error Budget 상태에 따른 행동 규칙

섹션 제목: “Error Budget 상태에 따른 행동 규칙”
Error Budget 잔여상태팀 행동
50% 이상🟢 여유공격적 배포, 신규 기능 실험 가능
25~50%🟡 주의현재 버닝 원인 점검, 리스크 낮은 배포만 허용
25% 미만🔴 위험신규 기능 개발 중단, 안정화 집중
0% 이하 (소진)⛔ 정지배포 동결, 경영진 보고, Error Budget Policy 발동

SLO 위반 시 자동으로 발동되는 규칙을 명문화한 것이다. 예를 들어:

Error Budget Policy (예시):
- Error Budget 소진 시: 모든 신규 기능 배포 즉시 동결
- SRE와 개발팀 장이 공동 서명해야 예외 배포 가능
- 소진 후 2주 내 RCA(Root Cause Analysis) + 재발 방지 계획 제출 의무

이 정책이 있으면 “배포해도 되냐”를 사람이 판단하지 않고 수치가 판단한다. 개발팀/운영팀 갈등이 “수치를 어떻게 관리할 것인가”로 전환된다.

NestJS + CloudWatch로 Error Budget 추적

섹션 제목: “NestJS + CloudWatch로 Error Budget 추적”
// NestJS에서 Custom Metric으로 가용성 SLI 전송 예시
import { CloudWatch } from "@aws-sdk/client-cloudwatch";
const cloudwatch = new CloudWatch({ region: "ap-northeast-2" });
// 요청 완료 시 성공/실패 메트릭 전송
async function recordRequestMetric(success: boolean) {
await cloudwatch.putMetricData({
Namespace: "MyApp/SLI",
MetricData: [
{
MetricName: "RequestSuccess",
Value: success ? 1 : 0,
Unit: "Count",
Dimensions: [{ Name: "Service", Value: "payment-api" }],
},
],
});
}
# CloudWatch Metric Math로 가용성 SLI 계산
AVAILABILITY = SUM(RequestSuccess) / SUM(TotalRequests) * 100
# 예상 결과 (CloudWatch Metrics 쿼리 결과)
Period: 2025-04-01 ~ 2025-04-30
SUM(RequestSuccess) = 2,997,235
SUM(TotalRequests) = 3,000,000
AVAILABILITY = 99.91% ← SLO(99.9%) 달성 ✅
Error Budget Used = 9% (43.2분 중 3.9분 사용)

📖 더 보기: SRE Error Budgets - A Complete Guide — SRE School, 에러 버짓 개념부터 정책 수립까지 단계별 설명


Incident Response — 장애 대응 프로세스

섹션 제목: “Incident Response — 장애 대응 프로세스”
등급정의대응 시간에스컬레이션
SEV1전체 서비스 중단, 데이터 유실 위험즉시 (15분 내)경영진 보고
SEV2주요 기능 장애 (결제, 로그인 등)30분 내팀장 보고
SEV3부분 기능 저하, 성능 저하업무 시간 내담당팀 내부
SEV4경미한 이슈, UI 버그 등백로그 처리없음
탐지 (Detection)
└─ CloudWatch 알람 → PagerDuty → On-call 담당자 호출
분류 (Triage)
└─ 심각도 결정, 영향 범위 파악, Incident Commander 지정
완화 (Mitigation) ← 가장 중요: 원인 파악보다 영향 줄이기 우선
└─ 롤백, 트래픽 차단, 스케일 아웃, 기능 플래그 OFF
해결 (Resolution)
└─ 근본 원인 수정, 검증, 서비스 정상화 확인
후속 조치 (Follow-up)
└─ Postmortem 작성, Action Items 추적

완화(Mitigation)가 핵심인 이유: 장애 중에 원인을 분석하다 보면 시간이 지나고 사용자 피해가 커진다. “일단 롤백해서 서비스를 살린 다음 원인을 찾는다”가 SRE의 우선순위다.

1차 담당자 (Primary On-call)
└─ 15분 내 응답 없으면 자동 에스컬레이션
2차 담당자 (Secondary / Escalation)
└─ 추가 15분 내 응답 없으면
팀장 / 관리자 에스컬레이션
# Runbook: API 응답시간 급증 (SEV2)
## 증상
CloudWatch 알람: `api-latency-p99-alert` 발화
p99 응답시간 > 2000ms (정상: 200ms 이하)
## 즉시 확인 사항
1. AWS 콘솔 → ECS → 서비스 상태 확인
2. RDS → 쿼리 성능 인사이트 확인 (느린 쿼리 여부)
3. CloudWatch → Logs → ERROR 로그 급증 여부
## 완화 옵션
- DB 연결 풀 고갈 시: ECS 태스크 재시작
- 특정 엔드포인트 문제 시: ALB 라우팅 규칙으로 트래픽 차단
- 전반적 부하 시: ECS Auto Scaling 수동 트리거

비난 문화(Blame Culture)에서는 두 가지 일이 벌어진다:

  1. 실수를 숨긴다 → 같은 장애가 반복된다
  2. 책임을 회피한다 → 아무도 위험한 작업을 하지 않는다

Blameless란 “누가 실수했나”가 아니라 “시스템이 왜 이 실수를 허용했나”에 집중하는 것이다. 예를 들어 “A씨가 잘못된 명령어를 실행했다” 대신 “프로덕션에 위험한 명령어가 실행될 수 있는 시스템 설계 문제가 있었다”로 접근한다.

# Postmortem: [서비스명] [날짜] 장애
## 요약
- 발생 시각: 2025-04-01 14:23 KST
- 감지 시각: 2025-04-01 14:25 KST (자동 알람)
- 해결 시각: 2025-04-01 15:10 KST
- 총 영향 시간: 47분
- 영향 범위: 결제 API 100% 불가, 약 1,200명 영향
## 타임라인
- 14:20 - 배포 완료 (v2.3.1)
- 14:23 - 에러율 0.1% → 45% 급증
- 14:25 - CloudWatch 알람 → PagerDuty 호출
- 14:28 - On-call 담당자 확인, SEV1 선언
- 14:35 - 롤백 결정 (v2.3.0)
- 14:52 - 롤백 완료, 에러율 0.1% 복구
- 15:10 - 모니터링 안정화 확인, 장애 종료
## 근본 원인 (5 Whys)
1. 왜 결제가 실패했나? → DB 연결 에러
2. 왜 DB 연결이 실패했나? → 연결 풀 고갈
3. 왜 연결 풀이 고갈됐나? → 쿼리 타임아웃이 무한대로 설정됨
4. 왜 무한대로 설정됐나? → 코드 리뷰에서 미검토
5. 왜 코드 리뷰에서 놓쳤나? → DB 타임아웃 설정 체크리스트 없음
## 무엇이 잘 됐나
- 자동 알람이 2분 만에 발화
- 롤백 절차가 명확해서 신속하게 실행됨
## 무엇이 잘 안 됐나
- 코드 리뷰에 DB 설정 관련 체크리스트 없음
- 스테이징 환경에서 부하 테스트 미실시
## Action Items
| 항목 | 담당자 | 기한 |
| ------------------------------------------ | ------ | ---------- |
| DB 타임아웃 설정 코드 리뷰 체크리스트 추가 | 홍길동 | 2025-04-08 |
| 스테이징 환경 부하 테스트 파이프라인 구축 | 김철수 | 2025-04-22 |
| DB 연결 풀 모니터링 대시보드 추가 | 이영희 | 2025-04-15 |

📖 더 보기: Google SRE Book - Postmortem Culture — Google 공식 SRE Book, Blameless 문화 구축 방법


특징설명예시
수동적사람이 직접 해야 함서버에 직접 SSH로 접속해 로그 정리
반복적같은 작업이 계속 발생매주 월요일 수동 배포
자동화 가능스크립트/도구로 대체 가능인증서 갱신 (ACM으로 자동화 가능)
장기 가치 없음해도 시스템이 개선되지 않음알람이 울려서 서비스 재시작

Toil vs 엔지니어링 작업 구분:

  • Toil: 서비스를 재시작하는 것 (반복될 것임)
  • 엔지니어링: 서비스가 자동 재시작되도록 Health Check + Auto Healing 구현

SRE 엔지니어 시간의 50% 이상이 Toil이면 경고 신호다. 나머지 50%는 반드시 엔지니어링(자동화, 도구 개선)에 써야 한다.

주간 업무 추적 예시:

주간 Toil 비율 측정 (예시):
총 업무 시간: 40시간
Toil 항목:
- 수동 배포: 4시간
- CloudWatch 알람 확인 및 수동 처리: 3시간
- 로그 분석 요청 대응: 2시간
- 인증서 갱신: 1시간
소계: 10시간 (25%) ✅ 정상
엔지니어링 항목:
- CI/CD 파이프라인 개선: 8시간
- SLO 대시보드 구축: 6시간
...

플랫폼 엔지니어의 존재 이유는 “다른 팀의 Toil을 줄여주는 것”이다.

개발팀 Toil → 플랫폼팀 자동화 → 개발팀 해방
예시:
Before: 개발자가 매번 IAM Role, VPC, RDS 수동 프로비저닝 (3~4시간)
After: Terraform 모듈 + 내부 CLI로 10분 내 완료

플랫폼 엔지니어링 팀이 SRE 프랙티스를 도입하면 아래 흐름으로 운영된다.

[서비스 배포]
[SLI 수집]──────────────────────────────────────────────────────────────┐
ALB 액세스 로그 │
CloudWatch Application Signals │
NestJS Custom Metrics (CloudWatch SDK) │
│ │
▼ │
[SLO/Error Budget 계산] │
Application Signals → SLO 달성률 집계 │
Metric Math → AVAILABILITY = 성공 / 전체 │
Error Budget 잔여량 = (SLI - SLO) / (1 - SLO) × 100 │
│ │
├─ Budget 정상 (>50%) ────────────────→ 정상 배포 허용 │
├─ Budget 주의 (25~50%) ──────────────→ 배포 전 SRE 리뷰 필수 │
└─ Budget 위험 (<25%) ───────────────→ 배포 동결, 안정화 스프린트 │
[알람 탐지] │
CloudWatch Alarm → SNS → PagerDuty/Slack │
On-call 담당자 호출 (2주 로테이션) │
│ │
▼ │
[Incident Response] │
탐지 → 분류(SEV1~4) → 완화(롤백 우선) → 해결 → Postmortem │
│ │
▼ │
[Postmortem → Action Items → Toil 감소]──────────────────────────────────┘
Action Items → Jira 티켓 → 스프린트 반영
반복 작업 자동화 → SLI 안정화 → Error Budget 확보

서비스별 SLO 대시보드 운영

  • AWS CloudWatch Application Signals에서 서비스별 SLO 페이지 생성
  • 주요 SLI(가용성, 지연시간, 에러율) 자동 집계
  • Error Budget 잔여량 시각화 — 팀 Slack 채널에 매주 자동 리포트

주간 Error Budget 리뷰 미팅

  • 매주 SLO 달성 여부 + Error Budget 소진 속도 점검
  • Budget이 50% 미만이면 다음 주 배포 계획 재검토
  • Budget 소진 원인 Top 3를 매주 팀에 공유

On-call 로테이션

  • PagerDuty 또는 AWS SNS + Lambda로 알람 라우팅
  • 2주 단위 로테이션으로 담당자 번아웃 방지
  • On-call 주간 종료 후 “On-call 일지” 작성 → Toil 항목 발굴

장애 발생 시 Postmortem

  • 장애 해결 후 48시간 내 초안 작성
  • 1주일 내 팀 전체 공유 및 Action Items 추적 시작
  • SEV1/SEV2는 작성 의무, SEV3 이하는 선택

Toil 자동화 우선순위

  • 분기별 Toil 항목 목록화 → ROI 계산 → 자동화 프로젝트 스프린트에 반영
  • 플랫폼팀 목표: 다른 팀의 Toil을 줄이는 내부 CLI/Terraform 모듈 제공

시나리오 1: 신규 서비스에 SLO를 처음 도입하는 경우

섹션 제목: “시나리오 1: 신규 서비스에 SLO를 처음 도입하는 경우”

상황: NestJS로 만든 결제 API를 AWS ECS에 배포했다. SLO가 없어서 “서비스가 얼마나 잘 동작하는지”를 수치로 말할 수 없는 상태다.

Step 1. 측정 가능한 SLI 결정 (30분)
→ 가용성(5xx 에러율), 지연시간(p99), 에러율 3개 선정
→ 측정 소스: ALB 액세스 로그 또는 CloudWatch Application Signals
Step 2. 기준선(Baseline) 데이터 수집 (1~2주)
→ 배포 전 CloudWatch 메트릭 조회로 현재 실제 값 확인
aws cloudwatch get-metric-statistics \
--namespace "AWS/ApplicationELB" \
--metric-name "HTTPCode_Target_5XX_Count" \
--start-time "2025-03-01T00:00:00Z" \
--end-time "2025-03-31T23:59:59Z" \
--period 2592000 --statistics Sum
→ 현재 가용성이 99.95%라면 SLO는 99.9%로 설정 (기준선보다 약간 낮게)
Step 3. CloudWatch Application Signals에 SLO 생성 (30분)
AWS 콘솔 → CloudWatch → Application Signals
→ Service Level Objectives → Create SLO
→ SLI Metric: AVAILABILITY, Goal: 99.9%, Window: 30 days
Step 4. Error Budget 알람 설정 (20분)
→ Application Signals → SLO 선택 → Alarms 탭
→ "Error Budget 소진 25% 초과" 알람 생성 → SNS → Slack 연동
Step 5. Error Budget Policy 문서화 (1시간)
→ 팀 위키에 정책 작성:
"Budget 25% 미만 → 배포 전 SRE 리뷰 필수"
"Budget 소진 → 배포 동결, 안정화 스프린트 전환"
→ 팀 전체 공유 및 온보딩 문서에 포함
Step 6. 2주 후 SLO 현실성 검토 (1시간)
→ SLO가 너무 낮으면 상향 조정, 너무 자주 위반되면 하향 조정
→ "처음부터 완벽하게" 말고 "일단 시작, 점진적 상향"이 현실적

예상 소요 시간: 초기 설정 3시간 + 2주 데이터 수집 + 검토 1시간


시나리오 2: 프로덕션 장애 발생 시 실시간 대응 흐름

섹션 제목: “시나리오 2: 프로덕션 장애 발생 시 실시간 대응 흐름”

상황: 오후 2시, CloudWatch 알람이 울렸다. payment-api-5xx-rate 알람 발화. 에러율이 0.1% → 35%로 급증했다.

[T+0분] 알람 수신
→ PagerDuty 호출 → 담당자(On-call) 확인
→ Slack: "SEV1 선언 — 결제 API 에러율 35%, Incident Commander: 홍길동"
[T+3분] 영향 범위 파악 (Triage)
→ AWS 콘솔 → CloudWatch → Dashboards → 서비스 대시보드 확인
→ 어느 엔드포인트에서 에러 발생인지 확인:
aws logs filter-log-events \
--log-group-name "/ecs/payment-api" \
--filter-pattern "ERROR" \
--start-time $(date -d '10 minutes ago' +%s000)
[T+8분] 원인 후보 좁히기
→ 최근 배포 여부 확인: AWS 콘솔 → ECS → Service → Deployments 탭
→ RDS 상태 확인: CloudWatch → RDS → DatabaseConnections 메트릭 급증 여부
→ 배포 이력 있음 → 롤백 우선 결정
[T+12분] 완화 조치 (Mitigation) — 원인 분석보다 복구 우선
→ ECS 콘솔 → Service → Update Service → 이전 Task Definition 선택
→ 또는 CodePipeline에서 이전 배포 버전 재실행
[T+25분] 에러율 정상화 확인
→ CloudWatch 에러율 메트릭 0.1%대로 복귀 확인
→ Slack: "SEV1 완화 완료. 모니터링 지속 중"
[T+48시간 이내] Postmortem 초안 작성
→ 위 타임라인 재구성
→ 5 Whys 분석
→ Action Items 3개 이상 (담당자 + 기한 포함)

시나리오 3: Error Budget이 빠르게 소진되는 상황 대응

섹션 제목: “시나리오 3: Error Budget이 빠르게 소진되는 상황 대응”

상황: 월 초인데 Error Budget 잔여량이 이미 40%밖에 남지 않았다. 이대로면 월말 전에 소진된다.

Step 1. 소진 원인 분석 (2시간)
→ CloudWatch → Application Signals → SLO → Error Budget 탭
→ 어느 시간대에 에러가 집중됐는지 그래프 확인
→ 에러 로그 패턴 분석:
aws logs insights query:
fields @timestamp, @message
| filter @message like /ERROR/
| stats count() by bin(1h)
| sort by bin(1h) desc
| limit 20
Step 2. 원인 분류
→ 배포 관련 에러: 특정 배포 이후 에러 급증 → 배포 프로세스 개선
→ 외부 의존성: 써드파티 API 장애 → 타임아웃 + 폴백 처리 강화
→ 트래픽 급증: 특정 시간대 과부하 → Auto Scaling 임계값 조정
Step 3. 단기 조치 (이번 달 Budget 보호)
→ 리스크 높은 배포 다음 주로 연기
→ 알람 임계값 낮춰서 조기 탐지 강화:
aws cloudwatch put-metric-alarm \
--alarm-name "payment-api-error-rate-early-warning" \
--threshold 0.5 \ ← 기존 1%에서 낮춤
--evaluation-periods 2
Step 4. 중기 조치 (다음 달 Budget 확보)
→ Postmortem Action Items 중 미완료 항목 우선 처리
→ 알람 Composite 조건 추가 (Alert Fatigue 방지)
→ 스테이징 환경 부하 테스트 파이프라인 구축
Step 5. 팀 공유
→ 주간 SRE 미팅에서 현황 보고:
"현재 Budget 40% 잔여, 이번 달 배포는 소형 변경만 허용"
→ Error Budget Policy 발동 여부 결정 (25% 미만이면 자동 발동)

시나리오 4: Toil 자동화 우선순위 결정

섹션 제목: “시나리오 4: Toil 자동화 우선순위 결정”

상황: 매주 3가지 반복 작업이 있다. 어떤 것을 먼저 자동화해야 하는가?

반복 작업 목록:
A. 매주 월요일 수동 배포 (2시간)
B. CloudWatch 알람 확인 후 ECS 태스크 수동 재시작 (3시간/주)
C. 개발팀 요청으로 RDS 슬로우 쿼리 로그 수동 추출 (1시간/주)
ROI 계산:
항목 | 주당 시간 | 자동화 비용 | 회수 기간 | 우선순위
A | 2h | 16h (CI/CD) | 8주 | 2순위
B | 3h | 4h (ECS 헬스체크 + 자동복구) | 1.3주 | ★ 1순위
C | 1h | 8h (Lambda + CloudWatch Logs 쿼리) | 8주 | 3순위
→ B를 먼저 자동화: ECS 태스크 헬스체크 + ALB 헬스체크로 자동 교체 구성
AWS 콘솔 → ECS → Service → Health check grace period 설정
→ 헬스체크 실패 시 자동 태스크 교체 (수동 재시작 불필요)

인프라 구축: 새 서비스를 프로비저닝할 때 SLO 정의 기준(어떤 SLI를 측정할 것인가, 목표값을 몇 %로 설정할 것인가)을 템플릿으로 만들어두면 팀 전체에 일관성이 생긴다.

보안 TF: 보안 사고(데이터 유출, 권한 오남용 등)도 Incident Response 프로세스를 따른다. SEV 분류와 에스컬레이션 경로는 동일하게 적용 가능하다.

DX 개선: 개발팀의 Toil(수동 배포, 환경 프로비저닝, 인증서 갱신 등)을 줄이는 내부 도구 개발이 플랫폼 팀의 핵심 가치이다.

CloudWatch 알람 → 장애 대응 파이프라인:

CloudWatch 알람 발화
→ SNS Topic
→ PagerDuty/Slack 알림
→ On-call 담당자 호출
→ Runbook 링크 자동 첨부
→ Postmortem 자동 생성 (장애 해결 후)
항목SLOSLA
대상내부 (개발팀, 운영팀)외부 (고객, 파트너)
성격목표계약
위반 시 결과내부 개선 액션환불, 크레딧, 계약 해지
엄격도SLA보다 높게 설정SLO보다 낮게 설정
예시99.95% 가용성 목표99.9% 가용성 보장 계약
항목DevOpsSRE
개념문화/철학/운동구체적 구현 방법론
기원개발+운영 협력 문화Google이 DevOps를 구체화한 것
핵심 도구CI/CD, IaC, 협업SLO, Error Budget, Toil 관리
측정 방법배포 빈도, DORA 지표SLI/SLO, Error Budget
비유”어떤 방향으로 가야 하는가""그 방향을 어떻게 갈 것인가”

SRE는 DevOps의 구체적 구현이다. “DevOps 한다”는 말보다 “SRE 프랙티스를 도입했다”가 더 구체적이다.

지표이름의미개선 방법
MTTRMean Time To Recovery장애 발생 후 복구까지 평균 시간Runbook 정비, 자동 롤백
MTTFMean Time To Failure정상 가동 후 다음 장애까지 평균 시간코드 품질 향상, 테스트 강화
MTBFMean Time Between Failures장애와 장애 사이의 평균 간격MTTF + MTTR 모두 개선
항목Incident (사고)Problem (문제)
정의현재 발생 중인 장애 증상반복적 장애의 근본 원인
목표빠른 서비스 복구근본 원인 제거
타임라인지금 당장장기 과제
예시”API가 500 에러를 반환한다""DB 연결 풀 설정이 비효율적이다”

판단 기준: 언제 무엇을 선택하는가

섹션 제목: “판단 기준: 언제 무엇을 선택하는가”
서비스 유형권장 SLO이유
결제·인증·핵심 API99.9% ~ 99.99%장애 시 직접 매출 손실, 높은 사용자 민감도
일반 CRUD API99.5% ~ 99.9%장애 허용 범위가 넓고 재시도 가능
배치·비동기 처리99% ~ 99.5%지연 허용 가능, 재처리 가능
내부 도구·관리자 페이지99%외부 사용자 영향 없음

판단 룰: SLA에 약속한 값 + 0.05~0.1%p를 SLO로 설정한다. 그래야 SLA 위반 전에 내부 경보가 울린다.

상황권장 정책이유
초기 서비스 (SLO 데이터 없음)SLO를 낮게 시작 (99%) 후 점진 상향기준 없이 높게 설정하면 과잉 제약 발생
빠른 릴리즈 팀Error Budget 소진 25% 기준으로 경고배포 빈도를 유지하면서 안전선 확보
안정성 중시 팀Error Budget 소진 10% 기준으로 경고보수적 운영, 금융·의료 서비스에 적합
스타트업 초기Error Budget 정책 적용 안 함 (추적만)인력·도구 미비, 일단 데이터 수집 우선
상황선택이유
팀 5명 이하, 초기 스타트업DevOps 문화 우선SRE 도구 없이도 CI/CD + 협업으로 충분
서비스 사용자 10만 이상SRE 프랙티스 도입SLO 없이 운영하면 장애 기준이 없어짐
복수 팀이 같은 인프라 공유플랫폼 SRE 팀 설립각 팀 SLO 관리 및 공통 인프라 신뢰성 담당
온콜 번아웃 발생Error Budget + Alert 감사 우선Alert Fatigue → Toil 증가 → 번아웃 악순환 차단
MTTR이 높다 (복구 오래 걸림)
→ Runbook 부재, 롤백 자동화 미비 → Runbook 작성, 자동 롤백 구현 우선
MTTF가 낮다 (장애가 자주 발생)
→ 코드 품질 낮음, 테스트 부족 → 테스트 커버리지, 카나리 배포 도입 우선
둘 다 나쁘다
→ Error Budget 이미 소진 상태 → 배포 동결, 안정화 스프린트 즉시 시작

1. Error Budget 계산값이 CloudWatch와 맞지 않는다

섹션 제목: “1. Error Budget 계산값이 CloudWatch와 맞지 않는다”

증상

내가 계산한 Error Budget 소진: 약 20%
CloudWatch Application Signals 표시: 65% 소진

원인

SLI 측정 지점이 잘못 설정되어 있는 경우가 많다.

  • 서버 사이드 측정: ALB 액세스 로그 기준 → 네트워크 장애는 카운트 안 됨
  • 클라이언트 사이드 측정: 실제 사용자 요청 기준 → 타임아웃, DNS 실패 포함
  • CloudWatch는 ALB 레벨의 메트릭을 사용하는데, SLO 계산에 ECS 태스크 레벨 메트릭을 쓰면 수치 불일치가 발생한다.

해결

1. SLI 측정 지점을 단일 소스로 통일 (ALB 또는 애플리케이션 중 하나 선택)
2. CloudWatch Application Signals 설정에서 SLI Metric 소스 확인:
AWS 콘솔 → Application Signals → SLO → Edit → SLI Metric 소스 재설정
3. 기존 데이터와 비교해 30일 재계산 후 기준선 재설정

2. On-call 알람이 너무 많아서 무시하게 된다 (Alert Fatigue)

섹션 제목: “2. On-call 알람이 너무 많아서 무시하게 된다 (Alert Fatigue)”

증상

PagerDuty 알람: 하루 평균 50건 이상 호출
On-call 담당자가 알람을 무시하거나 습관적으로 ACK만 누름
실제 장애가 알람 속에 묻혀서 늦게 발견됨

원인

  • 임계값이 너무 낮게 설정됨 (예: CPU 60% 이상이면 알람)
  • 알람이 “증상”이 아닌 “원인”에 설정됨 (CPU 높음 → 사용자에게 실제 영향이 없을 수도 있음)
  • 여러 알람이 동일 장애에 대해 중복 발화

해결

1. 알람 감사 (Alert Audit): 최근 1개월 알람 중 실제 액션이 필요했던 비율 측정
목표: 알람의 80% 이상이 실제 조치 필요
2. 증상 기반 알람으로 전환:
BAD: CPU 사용률 > 70%
GOOD: API 에러율 > 1% (사용자 영향이 있는 것만 알람)
3. CloudWatch Composite Alarm 사용:
CPU > 80% AND 에러율 > 0.5% → 알람 발화 (조건 조합)
4. 알람 우선순위 재정의:
SEV1급: PagerDuty 즉시 호출
SEV3급: Slack 채널 메시지만 (전화 없음)

3. Postmortem을 작성해도 같은 장애가 반복된다

섹션 제목: “3. Postmortem을 작성해도 같은 장애가 반복된다”

증상

Postmortem 문서가 Confluence에 쌓여 있는데,
3개월 전 DB 연결 풀 장애가 이번 달에도 반복됨

원인

  • Action Items에 담당자와 기한이 없어서 아무도 실행하지 않음
  • “모니터링 강화” 같이 추상적인 Action Item (실행 불가능한 항목)
  • Action Items 완료 여부를 추적하는 시스템이 없음

해결

1. Action Items 3요소 필수화:
BAD: "모니터링 강화"
GOOD: "결제 서비스 DB 연결 풀 사용률 CloudWatch 메트릭 추가" / 담당: 홍길동 / 기한: 2025-04-15
2. Action Items를 Jira/Linear 티켓으로 자동 생성:
Postmortem 작성 완료 → 자동으로 티켓 생성 → 스프린트 backlog에 포함
3. 주간 SRE 미팅에서 미완료 Action Items 리뷰 의무화
4. 재발 시 기존 Postmortem과 연결:
"이 장애는 2024-12-15 Postmortem Action Items가 완료되지 않아 재발"
→ 책임 소재가 명확해져 실행력 향상

4. SLO를 설정했는데 아무도 보지 않는다

섹션 제목: “4. SLO를 설정했는데 아무도 보지 않는다”

증상

CloudWatch에 SLO 대시보드를 만들었는데,
팀원들이 배포 전에 SLO 상태를 확인하지 않음
Error Budget 소진 후에야 문제를 인식함

원인

  • 대시보드 URL을 알아도 능동적으로 보러 가지 않음
  • SLO 상태가 의사결정(배포 여부)과 연결되지 않음

해결

1. CI/CD 파이프라인에 Error Budget 체크 단계 추가:
배포 시작 전 → Error Budget 잔여량 API 조회
잔여량 < 25% → 배포 파이프라인 차단 + Slack 경고
2. 주간 Slack 자동 리포트:
매주 월요일 09:00 → CloudWatch → Lambda → Slack
"이번 주 SLO 현황: payment-api 99.97% ✅ / user-api 99.85% ⚠️"
3. Error Budget Policy 명문화 및 팀 전체 공유
"Error Budget 25% 미만 시 배포 동결" 룰을 문서화하고 온보딩에 포함
  • 주요 서비스에 SLI 3개 이상(가용성, 지연시간, 에러율)이 정의되어 있는가?
    • 확인: aws cloudwatch list-metrics --namespace "AWS/ApplicationELB" 로 RequestCount, HTTPCode_Target_5XX_Count, TargetResponseTime 존재 여부 확인
  • SLO 목표값이 결정되고 문서화되어 있는가?
    • 확인: AWS 콘솔 → CloudWatch → Application Signals → Service Level Objectives → SLO 목록 조회
  • Error Budget이 대시보드로 시각화되어 있는가?
    • 확인: CloudWatch 대시보드 → AVAILABILITY Metric Math 위젯 존재 여부 확인. 없으면 aws cloudwatch put-dashboard 로 추가
  • Error Budget 소진 시 발동되는 Policy가 명문화되어 있는가?
    • 확인: 팀 위키(Confluence/Notion)에 “Error Budget Policy” 문서 존재 여부 + 팀 온보딩 자료에 포함 여부
  • 장애 심각도 분류 기준(SEV1~SEV4)이 팀 전체에 공유되어 있는가?
    • 확인: PagerDuty → Services → Escalation Policies → SEV별 에스컬레이션 경로 설정 여부. 또는 팀 Runbook에 SEV 정의 문서 포함 여부
  • On-call 로테이션이 설정되어 있는가?
    • 확인: PagerDuty → On-Call Schedules → 현재 담당자 및 다음 주 담당자 확인. AWS SNS 사용 시 aws sns list-subscriptions-by-topic --topic-arn <arn> 으로 수신자 확인
  • 주요 장애 유형에 대한 Runbook이 작성되어 있는가?
    • 확인: CloudWatch 알람 → 알람 상세 → Description 또는 링크 필드에 Runbook URL 포함 여부. aws cloudwatch describe-alarms --alarm-names "api-latency-p99-alert" 로 AlarmDescription 확인
  • 최근 장애에 대해 Postmortem이 작성되었는가?
    • 확인: 팀 위키에 최근 90일 내 Postmortem 문서 존재 여부 (SEV1/SEV2 건수 대비 작성률 100%인지)
  • Postmortem Action Items가 추적되고 있는가?
    • 확인: Jira/Linear에 label: postmortem-action 필터로 미완료 티켓 조회. 30일 이상 방치된 항목이 없는지 확인
  • 주간 Toil 비율을 측정하고 있는가? (목표: 50% 미만)
    • 확인: 주간 업무 기록(시간 추적 도구 또는 스프린트 티켓)에서 반복·수동 작업 비율 계산. 측정 도구 없으면 1주일 시범 기록부터 시작
  • Google SRE Book: “Site Reliability Engineering: How Google Runs Production Systems” — 무료 온라인 공개 (sre.google/books)
  • Chaos Engineering: 장애를 의도적으로 주입하여 시스템 복원력 검증 (Netflix Chaos Monkey가 시초)
  • Feature Flag + Canary 배포: 새 기능을 일부 트래픽에만 배포하여 SLO 영향 최소화
  • OpenSLO: SLO를 YAML 코드로 정의하는 오픈 표준 (IaC처럼 SLO를 버전 관리)
  • DORA Metrics: 배포 빈도, 변경 실패율, MTTR, 리드타임 — SRE 성과 측정의 보완 지표
  • Synthetic Monitoring: 실제 사용자 요청을 모방한 주기적 프로브로 SLI 측정

실습 1: 현재 서비스에 SLI 3개 정의

섹션 제목: “실습 1: 현재 서비스에 SLI 3개 정의”
Terminal window
# 현재 운영 중인 서비스에서 CloudWatch 메트릭 확인
aws cloudwatch list-metrics \
--namespace "AWS/ApplicationELB" \
--dimensions Name=LoadBalancer,Value=app/my-alb/1234abcd
# 예상 출력
{
"Metrics": [
{
"Namespace": "AWS/ApplicationELB",
"MetricName": "RequestCount",
"Dimensions": [...]
},
{
"Namespace": "AWS/ApplicationELB",
"MetricName": "HTTPCode_Target_5XX_Count",
...
},
{
"Namespace": "AWS/ApplicationELB",
"MetricName": "TargetResponseTime",
...
}
]
}
Terminal window
# AWS CLI로 이번 달 에러율 조회
aws cloudwatch get-metric-statistics \
--namespace "AWS/ApplicationELB" \
--metric-name "HTTPCode_Target_5XX_Count" \
--dimensions Name=LoadBalancer,Value=app/my-alb/1234abcd \
--start-time "2025-04-01T00:00:00Z" \
--end-time "2025-04-30T23:59:59Z" \
--period 2592000 \
--statistics Sum
# 예상 출력
{
"Datapoints": [
{
"Timestamp": "2025-04-01T00:00:00+00:00",
"Sum": 765.0, 이번 5xx 에러 건수
"Unit": "Count"
}
]
}
# Error Budget 수동 계산
# SLO = 99.9%, 총 요청 = 3,000,000건
# Error Budget = 3,000,000 × 0.001 = 3,000건
# 사용량 = 765건 / 3,000건 = 25.5% 소진
# 잔여량 = 74.5% ✅

실습 3: CloudWatch Application Signals SLO 확인

섹션 제목: “실습 3: CloudWatch Application Signals SLO 확인”
AWS 콘솔 접근 경로:
CloudWatch → 좌측 메뉴 → Application Signals → Service Level Objectives
확인 항목:
- SLO 이름, 목표값(예: 99.9%)
- 현재 달성률(Attainment)
- Error Budget 잔여량
- 알람 상태

예상 화면 출력 (Application Signals SLO 목록):

┌─────────────────────────┬────────┬────────────┬──────────────┬────────┐
│ SLO 이름 │ 목표 │ 현재 달성률 │ Budget 잔여 │ 상태 │
├─────────────────────────┼────────┼────────────┼──────────────┼────────┤
│ payment-api-availability│ 99.9% │ 99.97% │ 87.3% │ ✅ OK │
│ user-api-latency-p99 │ 300ms │ 287ms │ 62.1% │ ✅ OK │
│ order-api-availability │ 99.5% │ 99.41% │ 18.0% │ ⚠️ 위험│
└─────────────────────────┴────────┴────────────┴──────────────┴────────┘
# 실습 과제
1. 최근 1개월 내 자신이 경험한 장애(경미한 것도 OK) 하나 선택
2. 위 Postmortem 템플릿에 따라 작성
3. 특히 5 Whys 분석 시도
4. Action Items 3개 이상, 담당자·기한 포함
평가 기준:
- 타임라인이 분 단위로 재구성되어 있는가?
- 근본 원인이 "사람 실수"가 아닌 "시스템 개선 과제"로 정의되는가?
- Action Items가 구체적이고 실행 가능한가?

작성 완료 후 예상 결과물 (예시):

# Postmortem: user-api 응답시간 급증 (2025-04-03)
## 요약
- 발생: 2025-04-03 11:15 KST
- 감지: 2025-04-03 11:17 KST (CloudWatch 알람)
- 해결: 2025-04-03 11:52 KST
- 영향: user-api p99 응답 4,200ms (정상 120ms), SEV2
## 타임라인
- 11:10 - user-api v1.4.2 배포 완료
- 11:15 - p99 응답시간 급증 시작
- 11:17 - CloudWatch 알람 발화 → Slack 알림
- 11:22 - On-call 담당자 확인, SEV2 선언
- 11:30 - RDS 슬로우 쿼리 확인 (full table scan 발생)
- 11:40 - 롤백 결정 및 실행 (v1.4.1)
- 11:52 - 응답시간 정상화
## 5 Whys
1. 왜 응답이 느렸나? → RDS 쿼리 타임아웃 빈발
2. 왜 쿼리 타임아웃? → full table scan 발생
3. 왜 full table scan? → v1.4.2에서 WHERE 절 컬럼 인덱스 누락
4. 왜 인덱스 누락? → 신규 컬럼 추가 시 인덱스 생성 체크리스트 없음
5. 왜 체크리스트 없음? → DB 마이그레이션 PR 리뷰 가이드 미비
## Action Items
| 항목 | 담당자 | 기한 |
| --------------------------------------------------------------- | ------ | ---------- |
| DB 마이그레이션 PR 체크리스트 작성 (인덱스 포함 여부 필수 확인) | 홍길동 | 2025-04-10 |
| 스테이징 환경 슬로우 쿼리 로그 알람 추가 | 이영희 | 2025-04-15 |
| RDS Performance Insights 대시보드 팀 공유 | 김철수 | 2025-04-12 |

자기 평가 체크포인트:

  • 타임라인에서 “배포 완료” 직후 장애가 연결되는가? (배포-장애 상관관계 파악)
  • 5 Whys 마지막 항목이 “시스템/프로세스 개선”으로 끝나는가? (사람 탓으로 끝나지 않는가)
  • Action Items에 담당자·기한이 모두 있는가?
  1. SLI는 측정, SLO는 목표, SLA는 계약 — 이 셋의 계층 구조가 SRE의 기반이며, SLO는 항상 SLA보다 엄격하게 설정한다.
  2. Error Budget = 1 - SLO — 혁신(배포)과 안정(신뢰성)의 균형을 수치로 관리하며, Budget 소진 시 자동으로 배포 동결 Policy가 발동된다.
  3. 장애 대응은 5단계 프로세스 — 탐지 → 분류 → 완화(원인보다 복구 우선) → 해결 → 후속 조치(Postmortem)로 표준화한다.
  4. Postmortem은 Blameless로 — “누가 실수했나”가 아니라 “시스템이 왜 허용했나”에 집중해야 같은 장애가 반복되지 않는다.
  5. 플랫폼 엔지니어의 핵심 역할은 Toil 제거 — 다른 팀의 수동·반복 작업을 자동화하여 전체 팀의 엔지니어링 시간을 늘리는 것이 플랫폼 팀의 존재 이유다.