번외: SLI/SLO/에러 버짓을 실제로 계산해서 배포 판단 기준으로 써보기
SLI(측정값)·SLO(목표치)·SLA(계약)의 관계부터, 카운터 API의 성공률을 SLI로 정의하고 Prometheus recording rule로 에러 버짓 소진률을 계산해 Grafana 대시보드로 보는 절차. 에러 버짓 소진 시 배포를 멈추는 정책까지.
목표
"가용성 99.9%를 목표로 한다"는 문장을 실제로 계산 가능한 숫자로 만든다. SLI를 정의하고, SLO 대비 에러 버짓이 얼마나 남았는지를 Prometheus recording rule로 실시간 계산해, "지금 신규 기능을 더 배포해도 되는지, 안정화에 집중해야 하는지"를 감으로 판단하지 않고 숫자로 판단하는 체계를 만든다.
개념: SLI → SLO → SLA, 그리고 에러 버짓
- SLI(Service Level Indicator): 실제로 측정하는 지표 자체. 예 - "요청 중 성공(2xx/3xx) 비율", "p95 응답시간".
- SLO(Service Level Objective): 그 SLI에 대한 내부 목표치. 예 - "성공 비율 99.9% 이상".
- SLA(Service Level Agreement): SLO를 어겼을 때 페널티가 따르는 대외 계약. 이 랩은 개인 프로젝트라 SLA는 없고 SLO까지만 다룬다.
**에러 버짓(Error Budget)**은 SLO의 반대편이다 - SLO가 99.9%면, 0.1%는 "실패해도 되는 예산"이다. 한 달(30일) 기준으로 계산하면:
전체 요청 예상치: 30일 × 86400초 × 평균 QPS
허용 가능한 실패 요청 수 = 전체 요청 × (1 - 0.999) = 전체 요청 × 0.001
이 예산을 다 쓰면(에러 버짓 소진) 배포를 멈추고 안정화에 집중한다 - "장애가 있었다/없었다"가 아니라 "이번 달에 쓸 수 있는 실패 예산이 몇 % 남았는가"로 운영 판단을 내리는 게 이 개념의 핵심이다.
실제 구축 절차
1. SLI 정의 - 카운터 API의 성공률
시리즈 6에서 만든 api-server의 요청 성공률을 SLI로 삼는다. Prometheus가 이미 http_requests_total{status=~"..."}을 수집하고 있으므로 추가 계측은 필요 없다.
# SLI: 최근 5분간 성공(non-5xx) 비율
sum(rate(http_requests_total{status!~"5.."}[5m]))
/
sum(rate(http_requests_total[5m]))
2. SLO 목표 설정 + recording rule
매번 이 쿼리를 새로 계산하지 않도록 recording rule로 미리 구워둔다 - 대시보드·알림 양쪽에서 재사용하기 위해서다.
# prometheus-rules/slo.yaml
groups:
- name: api-server-slo
rules:
- record: sli:availability:ratio_rate5m
expr: |
sum(rate(http_requests_total{status!~"5.."}[5m]))
/
sum(rate(http_requests_total[5m]))
- record: slo:availability:target
expr: vector(0.999) # SLO 99.9%
3. 에러 버짓 소진률 계산
**소진률(burn rate)**은 "지금 속도로 계속 실패하면 에러 버짓이 얼마나 빨리 바닥나는가"를 나타내는 배수다. 1배면 정확히 SLO 기간(30일) 동안 예산을 다 쓰는 속도, 14.4배면 약 2일 만에 다 쓰는 속도라는 뜻이다(Google SRE 워크북의 멀티윈도우 소진률 계산 방식을 그대로 따른다).
- record: slo:error_budget:burn_rate1h
expr: |
(1 - sli:availability:ratio_rate5m)
/
(1 - slo:availability:target)
- alert: ErrorBudgetFastBurn
expr: slo:error_budget:burn_rate1h > 14.4
for: 5m
labels: { severity: critical }
annotations:
summary: "에러 버짓이 2일 안에 소진될 속도로 타는 중 - 배포 중단 검토"
14.4라는 숫자가 임의로 보일 수 있는데, 30일 SLO 기간을 2일로 나눈 비율(30/2 = 15에 가까운 값)에서 나온 것이다 - "이 속도가 계속되면 이번 달 예산을 이틀 안에 다 쓴다"는 조기 경보 임계값이다.
4. Grafana 대시보드 - 에러 버짓 잔여량
# 이번 SLO 기간(30일) 동안 남은 에러 버짓 비율 (0~100%)
100 * (
1 - (
(1 - avg_over_time(sli:availability:ratio_rate5m[30d]))
/
(1 - slo:availability:target)
)
)
이 값을 Grafana 게이지 패널로 만들어, "남은 에러 버짓 몇 %"를 항상 볼 수 있게 한다. 0%에 가까워지면 배포를 멈추는 정책을 팀 규칙(또는 개인 랩이면 스스로의 규칙)으로 정해둔다.
검증 방법
- 의도적으로
api-server에서 5xx를 일부러 반환하는 엔드포인트를 호출해 SLI가 실제로 떨어지는지 확인 - 그 상태를 몇 분 유지해
ErrorBudgetFastBurn알림이 실제로 발화하는지 확인 - Grafana 게이지에서 에러 버짓 잔여량이 감소하는 게 실시간으로 보이는지 확인
- 5xx 유발을 멈춘 뒤 시간이 지나면서 소진률이 다시 낮아지는지(버짓이 서서히 회복되는지) 확인
체크리스트
- SLI(성공률) PromQL 정의, recording rule로 저장
- SLO 목표치(99.9%) 설정
- 멀티윈도우 소진률 계산 + 조기 경보 알림 규칙
- Grafana 에러 버짓 잔여량 게이지 대시보드
- 의도적 장애 주입으로 알림 발화 검증
- "에러 버짓 소진 시 배포 중단" 정책을 실제 배포 프로세스(ArgoCD/Jenkins)에 연결할지 결정