쿠버네티스 SLO 자동화: Sloth와 Pyrra로 구현하는 선언형 SLO 관리
Prometheus Operator CRD 기반 접근 방식과 Grafana SLO 비교
서비스가 복잡해질수록 "지금 우리 서비스가 얼마나 잘 동작하고 있는가?"라는 질문에 명확하게 답하기 어려워집니다. 알림은 끊임없이 울리지만 무엇이 정말 중요한지 파악하기 힘들고, 장애가 난 뒤에야 대응하는 구조가 반복됩니다. 2024~2025년 Platform Engineering 트렌드에서 이 문제를 해결하는 핵심 방법론으로 "SLO as Code"가 주목받고 있습니다. SLO(Service Level Objective)를 코드로 선언하고 GitOps 워크플로우로 관리함으로써, 서비스 신뢰성을 팀 전체의 공유 언어로 만드는 것입니다.
이 글에서는 Kubernetes 환경에서 SLO를 코드로 관리할 수 있게 해주는 오픈소스 도구인 Sloth와 Pyrra를 중심으로, Prometheus Operator CRD 기반 접근 방식이 무엇인지, Grafana Cloud의 관리형 SLO 서비스와 어떤 차이가 있는지 실제 YAML 예시와 함께 살펴봅니다. 이 글을 읽고 나면 팀 상황에 맞는 SLO 도구를 선택하고 GitOps 워크플로우에 SLO를 통합하는 구체적인 방법을 파악할 수 있습니다. Kubernetes를 운영 중인 개발자·SRE를 대상으로 하며, PromQL 경험이 있다면 더욱 빠르게 따라갈 수 있지만 각 개념은 처음 접하는 분도 이해할 수 있도록 설명합니다.
핵심 개념
SLO, SLI, 에러 버짓 — 세 가지 개념의 관계
SLO를 도입하려면 먼저 세 가지 핵심 용어를 구분해야 합니다.
SLI(Service Level Indicator): 서비스 품질을 측정하는 실제 지표. 예: HTTP 요청 성공률, 응답 지연(p99 latency)
SLO(Service Level Objective): SLI에 대한 목표치. 예: "4주 기간 동안 HTTP 성공률 99.9% 이상 유지"
에러 버짓(Error Budget): SLO에서 허용하는 장애 허용 한도. SLO가 99.9%라면 0.1%가 에러 버짓이며, 이를 소진하면 신규 배포를 중단하는 등의 의사결정 기준이 됩니다.
이 세 가지가 맞물리면 "지금 배포해도 되는가?" 같은 운영 의사결정이 감이 아닌 데이터로 가능해집니다.
Prometheus Operator + CRD 기반 SLO 관리란?
Kubernetes에서 SLO를 관리하는 현대적인 방법은 CRD(Custom Resource Definition)를 활용하는 것입니다. 먼저 관련 컴포넌트를 이해하면 전체 그림이 잡힙니다.
PrometheusRule: Prometheus Operator가 제공하는 CRD입니다. 알림 규칙(Alerting Rule)과 레코딩 규칙(Recording Rule, 자주 쓰는 PromQL 표현식을 사전 계산해 저장하는 규칙)을 Kubernetes 리소스로 선언할 수 있게 해줍니다. Prometheus는 이 YAML에 정의된 표현식을 주기적으로 평가하여 알림을 발송하거나 새로운 메트릭 시계열을 생성합니다.
Sloth와 Pyrra는 각각 자신만의 CRD를 제공합니다. 이 CRD를 Kubernetes에 배포하면 각 오퍼레이터가 watch 메커니즘으로 CRD 변경을 감지하고, reconcile 루프를 통해 PrometheusRule을 자동으로 생성·업데이트합니다. 즉, 사용자가 간단한 SLO CRD를 정의하기만 하면 복잡한 알림 규칙 YAML은 오퍼레이터가 자동으로 만들어줍니다.
개발자 → SLO CRD (YAML) → Git 저장소
↓ ArgoCD/Flux
K8s Cluster
↓ Sloth/Pyrra Operator (watch → reconcile)
PrometheusRule CR (알림/레코딩 규칙 자동 생성)
↓
Prometheus (규칙 평가 → 알림 발송)이 흐름의 핵심은 SLO 정의 자체가 Kubernetes 리소스가 된다는 점입니다. 코드 리뷰, GitOps 배포, 버전 관리 등 기존 개발 워크플로우를 그대로 SLO 관리에 적용할 수 있습니다.
다중 번 레이트 알림(Multi-Window, Multi-Burn-Rate Alert)이란?
SLO 알림의 핵심 과제는 "빠른 감지"와 "노이즈 최소화"의 균형입니다. Google SRE Workbook에서 제안한 다중 번 레이트 알림 방법론은 짧은 창(short window)과 긴 창(long window)을 조합해, 에러 버짓이 빠르게 소진될 때는 즉시 알리고 느리게 소진될 때는 중요도가 낮은 알림으로 분류합니다.
번 레이트(Burn Rate): 에러 버짓이 소진되는 속도입니다. 번 레이트 1은 SLO 윈도우(예: 4주) 동안 에러 버짓이 정확히 다 소진되는 속도이고, 번 레이트 14는 4주 에러 버짓을 2일 만에 소진하는 속도로 즉각적인 대응이 필요한 수준입니다.
Sloth는 alerting.page(빠른 소진, critical)와 alerting.ticket(느린 소진, warning) 두 가지 알림을 선언하면, 내부적으로 Google SRE 가이드라인 기반의 6개 알림 규칙을 자동 생성합니다.
| 알림 종류 | 긴 창 (Long Window) | 짧은 창 (Short Window) | 번 레이트 |
|---|---|---|---|
| page (critical) | 1h | 5m | 14× |
| page (critical) | 6h | 30m | 6× |
| ticket (warning) | 3d | 6h | 3× |
| ticket (warning) | 3d | 6h | 1× |
(실제 생성되는 규칙은 Sloth 버전 및 설정에 따라 달라질 수 있습니다.)
Sloth와 Pyrra 모두 이 복잡한 다중 번 레이트 알림 규칙을 사용자가 직접 PromQL로 작성할 필요 없이 자동 생성해줍니다.
Sloth vs Pyrra vs Grafana SLO — 각 도구의 포지셔닝
세 도구는 같은 문제를 서로 다른 철학으로 해결합니다.
| 구분 | Sloth | Pyrra | Grafana SLO |
|---|---|---|---|
| 유형 | CLI + K8s 오퍼레이터 | K8s 오퍼레이터 | 관리형 클라우드 서비스 |
| 오픈소스 | ✅ | ✅ | ❌ |
| 내장 UI | ❌ | ✅ | ✅ |
| GitOps 친화성 | 높음 | 중간 | 낮음 |
| Thanos/Mimir 지원 | 제한적 | ✅ (v0.8.0+) | ✅ |
| OpenSLO 지원 | ✅ | ❌ | ❌ |
| 비용 | 무료 | 무료 | 연간 $25,000+ |
Thanos / Grafana Mimir: Prometheus의 장기 메트릭 보관과 고가용성 쿼리를 담당하는 레이어입니다. 여러 클러스터의 메트릭을 통합하거나 수개월치 데이터를 보관해야 하는 환경에서 Prometheus와 함께 사용됩니다.
GitOps 친화성에서 Pyrra가 "중간"인 이유: Pyrra는 오퍼레이터 전용으로 동작하며 Sloth와 달리 CLI 모드를 제공하지 않습니다. 이 때문에 CI 파이프라인에서 오퍼레이터 없이 규칙을 미리 생성하거나 검증하는 오프라인 워크플로우가 불가능합니다. CRD 자체는 Git으로 관리할 수 있지만, 실제 PrometheusRule 생성 결과를 PR 단계에서 확인하려면 Sloth CLI처럼 독립적인 검증 수단이 없다는 점이 제약입니다.
실전 적용
예시 1: Sloth로 HTTP 가용성 SLO 정의하기
Sloth의 CRD인 PrometheusServiceLevel을 사용하면 복잡한 다중 번 레이트 알림 규칙을 간단한 YAML로 선언할 수 있습니다.
apiVersion: sloth.slok.dev/v1
kind: PrometheusServiceLevel
metadata:
name: my-service-slo
namespace: monitoring
spec:
service: "my-service"
slos:
- name: "requests-availability"
objective: 99.9
description: "HTTP 요청 성공률 99.9% 유지"
sli:
events:
# 5xx 응답의 초당 발생 비율 합산 (에러 이벤트)
errorQuery: >
sum(rate(http_requests_total{job="my-service",code=~"5.."}[{{.window}}]))
# 전체 요청의 초당 발생 비율 합산
totalQuery: >
sum(rate(http_requests_total{job="my-service"}[{{.window}}]))
alerting:
name: MyServiceHighErrorRate
page:
labels:
severity: critical
ticket:
labels:
severity: warning| 필드 | 설명 |
|---|---|
objective: 99.9 |
4주 기간 기준 99.9% 가용성 목표 |
sli.events.errorQuery |
에러로 집계할 이벤트 PromQL. {{.window}}는 Sloth가 규칙 생성 시 자동 치환 |
sli.events.totalQuery |
전체 이벤트 PromQL |
alerting.page |
번 레이트가 높을 때(빠른 소진) 발송하는 critical 알림 |
alerting.ticket |
번 레이트가 낮을 때(느린 소진) 발송하는 warning 알림 |
중요: YAML에 포함된 {{.window}}는 Sloth 내부의 Go 템플릿 문법입니다. 이 YAML을 그대로 kubectl apply하는 것이 아니라, Sloth 오퍼레이터가 CRD를 watch하면서 자동으로 전처리하거나, Sloth CLI가 먼저 PrometheusRule YAML로 변환한 뒤 적용하는 방식으로 사용합니다.
# CLI 모드: PrometheusRule YAML 미리 생성 및 검증 (오퍼레이터 없이도 가능)
sloth generate -i my-service-slo.yaml -o output-rules.yaml이 YAML 하나를 적용하면 Sloth 오퍼레이터가 앞서 설명한 6개 알림 규칙을 담은 PrometheusRule을 자동 생성합니다.
예시 2: Pyrra로 gRPC 에러율 SLO 정의하기
Pyrra의 CRD인 ServiceLevelObjective는 더욱 간결한 문법을 제공합니다.
apiVersion: pyrra.dev/v1alpha1
kind: ServiceLevelObjective
metadata:
name: grpc-service-availability
namespace: monitoring
labels:
pyrra.dev/team: "platform" # metadata.labels 섹션 — Pyrra UI 팀별 필터링용
spec:
target: "99.5" # 문자열 타입 (Pyrra CRD 스펙이 string으로 정의됨)
window: 4w
indicator:
ratio:
errors:
metric: grpc_server_handled_total{job="grpc-service",grpc_code!="OK"}
total:
metric: grpc_server_handled_total{job="grpc-service"}| 필드 | 위치 | 설명 |
|---|---|---|
pyrra.dev/team |
metadata.labels |
Pyrra UI에서 팀별 필터링에 활용되는 레이블. spec이 아닌 metadata 하위에 위치함 |
target: "99.5" |
spec |
4주 기준 99.5% 가용성 목표. Pyrra CRD 스펙이 string 타입으로 정의되어 따옴표 필요 |
window: 4w |
spec |
SLO 평가 윈도우 (4주) |
indicator.ratio |
spec |
비율 기반 SLI 정의 |
errors.metric |
spec.indicator.ratio |
에러로 집계할 메트릭 셀렉터 |
total.metric |
spec.indicator.ratio |
전체 요청 메트릭 셀렉터 |
Pyrra는 이 CRD로부터 PrometheusRule을 생성할 뿐만 아니라, 내장 Web UI에서 에러 버짓 소진율과 남은 에러 버짓을 실시간으로 시각화해줍니다. Grafana 없이도 SLO 현황을 즉시 파악할 수 있다는 점이 Pyrra의 큰 차별점이지만, 실전에서 Pyrra의 진가는 Thanos 환경에서의 쿼리 최적화에 있습니다. 고카디널리티 메트릭 환경에서 서브쿼리 사전 집계(subquery pre-aggregation)를 내장하고 있어, Thanos를 사용하는 멀티 클러스터 환경에서 쿼리 성능이 크게 향상됩니다.
예시 3: GitOps 워크플로우 통합 패턴
실제 운영 환경에서는 SLO CRD를 별도 Git 저장소(또는 인프라 저장소의 하위 디렉토리)에 보관하고 ArgoCD나 Flux로 배포하는 패턴이 표준으로 자리잡았습니다.
infra-repo/
├── slos/
│ ├── my-service-availability.yaml # Sloth CRD
│ ├── grpc-service-slo.yaml # Pyrra CRD
│ └── kustomization.yaml # kubectl apply -k 로 배포 시 사용
└── argocd/
└── slo-app.yaml # ArgoCD Application# slos/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- my-service-availability.yaml
- grpc-service-slo.yaml# argocd/slo-app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: slos
namespace: argocd
spec:
source:
repoURL: https://github.com/my-org/infra-repo
targetRevision: main
path: slos
destination:
server: https://kubernetes.default.svc
namespace: monitoring
syncPolicy:
automated:
prune: true
selfHeal: true이 패턴에서 SLO 변경은 반드시 PR → 코드 리뷰 → 머지 → 자동 배포 순서를 거칩니다. "누가 언제 어떤 SLO 목표치를 변경했는가"가 Git 히스토리로 완전히 추적됩니다.
장단점 분석
장점
| 항목 | Sloth | Pyrra | Grafana SLO |
|---|---|---|---|
| GitOps 통합 | CLI로 CI 파이프라인 오프라인 검증 지원 | CRD 기반 선언형 관리 (CLI 없음) | Terraform IaC 지원 |
| 알림 품질 | Google SRE 기반 다중 번 레이트 자동 생성 | 동일한 수준의 알림 자동 생성 | 사전 구성된 알림 제공 |
| 확장성 | 플러그인 시스템으로 SLI 로직 재사용 | Thanos/Mimir 고카디널리티 최적화 내장 | Grafana Cloud 생태계 완전 통합 |
| 접근성 | PromQL 지식 필요 | PromQL 지식 필요 | UI만으로 설정 가능 |
| 표준 지원 | OpenSLO 스펙 직접 수용 | — | — |
OpenSLO: CNCF 생태계의 벤더 중립적 SLO 선언 스펙입니다. Sloth는 이 스펙을 직접 입력으로 받아 Prometheus 규칙을 생성할 수 있어, 특정 도구에 종속되지 않는 SLO 정의가 가능합니다.
단점 및 주의사항
카디널리티(Cardinality): 메트릭 시계열의 고유한 레이블 조합 수입니다. 카디널리티가 높을수록 Prometheus의 메모리 사용량과 쿼리 비용이 증가합니다. Pyrra는 고카디널리티 환경을 위한 서브쿼리 사전 집계 최적화를 내장하고 있어 Thanos 환경에서 특히 유리합니다.
| 항목 | 내용 | 대응 방안 |
|---|---|---|
| Sloth 내장 UI 없음 | Sloth는 시각화 도구를 제공하지 않음 | Grafana 공식 대시보드 ID 14348을 import하거나 자체 구성 |
| Pyrra Grafana 연동 제한 | Pyrra 생성 규칙을 Grafana에서 시각화할 때 -generic-rules 플래그 필요, 그룹핑 미지원 |
Pyrra 내장 UI와 Grafana를 용도에 따라 병행 사용 |
| Grafana SLO 벤더 종속 | Grafana Cloud 전용, 자체 호스팅 불가 | 초기 도입 후 오픈소스 전환 시 마이그레이션 비용 사전 고려 |
| Grafana SLO 고비용 | 연간 $25,000 이상의 엔터프라이즈 비용 | 팀 규모와 ROI를 사전에 검토 |
| Sloth 시각화 공수 | Pyrra 대비 Grafana 대시보드 초기 설정 공수가 높음 | 공식 대시보드 템플릿을 import해 시작하는 것을 권장 |
실무에서 가장 흔한 실수
- 에러 버짓 소진율을 모니터링하지 않고 SLO만 설정하는 경우 — SLO를 설정했더라도 에러 버짓이 얼마나 빠르게 소진되는지 정기적으로 리뷰하지 않으면 형식적인 지표로만 남습니다. 주간 에러 버짓 리뷰를 팀 루틴으로 만들어보시면 좋습니다.
- 너무 많은 서비스에 동시에 SLO를 적용하는 경우 — 처음부터 모든 서비스에 SLO를 적용하면 알림 피로(alert fatigue)가 증가합니다. 가장 중요한 서비스 1~2개에서 시작해 점진적으로 확장하는 방식을 권장합니다.
- SLO 목표치를 임의로 높게 설정하는 경우 — 99.99%처럼 과도하게 높은 목표치를 설정하면 에러 버짓이 지나치게 작아져 정상적인 배포도 어렵게 만듭니다. 현재 실제 서비스 수준을 먼저 측정한 뒤 현실적인 목표치를 설정하는 것이 좋습니다.
마치며
Sloth와 Pyrra는 복잡한 SLO 알림 규칙을 간단한 CRD 선언으로 추상화해, Kubernetes 환경에서 SLO를 GitOps 워크플로우에 자연스럽게 통합할 수 있게 해주는 강력한 오픈소스 도구입니다.
도구 선택 시에는 팀의 현재 스택과 필요에 따라 다음 기준을 체크해보시면 도움이 됩니다.
| 체크 항목 | Sloth | Pyrra | Grafana SLO |
|---|---|---|---|
| 이미 Grafana를 적극 활용 중 | ✅ | — | — |
| Grafana 없이 에러 버짓 즉시 시각화 필요 | — | ✅ | ✅ |
| Thanos/Mimir 멀티 클러스터 환경 | — | ✅ | ✅ |
| CI 파이프라인에서 SLO 규칙 오프라인 검증 필요 | ✅ | — | — |
| PromQL 없이 UI만으로 설정하고 싶음 | — | — | ✅ |
| 오픈소스, 자체 호스팅 필요 | ✅ | ✅ | — |
| 빠른 도입, Grafana Cloud 이미 사용 중 | — | — | ✅ |
지금 바로 시작해볼 수 있는 3단계:
-
Pyrra로 첫 SLO 배포해보기 — 아래 명령으로 Pyrra를 설치할 수 있습니다.
monitoring네임스페이스가 없다면 먼저kubectl create namespace monitoring으로 생성하고, Prometheus Operator(또는 kube-prometheus-stack)가 사전에 설치되어 있어야 합니다.bashhelm repo add pyrra https://pyrra-dev.github.io/pyrra helm install pyrra pyrra/pyrra -n monitoring설치 후 위 예시의
ServiceLevelObjectiveYAML을 가장 중요한 서비스 하나에 적용해 Pyrra 내장 UI에서 에러 버짓이 시각화되는 것을 확인해볼 수 있습니다. -
GitOps 저장소에
slos/디렉토리 생성 — 기존 인프라 저장소에slos/디렉토리를 만들고, SLO CRD YAML을 PR 기반으로 관리하는 워크플로우를 적용해보시면 좋습니다. 위 예시의 ArgoCD Application YAML 하나를 추가하는 것만으로 GitOps 통합이 완성됩니다. -
주간 에러 버짓 리뷰 루틴 도입 — SLO 도구 도입 이후 에러 버짓 소진율을 팀 주간 회의에서 5분간 리뷰하는 루틴을 만들어보시면 좋습니다. 이 작은 습관이 SLO가 형식적인 지표로 전락하는 것을 막고, 데이터 기반 배포 의사결정 문화를 만드는 시작점이 됩니다.
다음 글: 에러 버짓 정책 자동화 — SLO 위반 시 배포 게이트를 자동으로 차단하는 GitOps 파이프라인 구성 방법
참고 자료
- Sloth 공식 문서 — Kubernetes CRD 스펙
- Sloth GitHub 저장소 (slok/sloth)
- Pyrra 공식 사이트
- Pyrra GitHub 저장소 (pyrra-dev/pyrra)
- Service Level Objectives made easy with Sloth and Pyrra — 0xDC.me
- Service Level Objectives made easy with Sloth and Pyrra — Medium (David Calvert)
- SLO Reporting Frameworks: Pyrra vs. SloK — TECHVZERO
- Monitor SLOs with the Grafana LGTM Stack: Daimler Truck 사례 — Grafana Labs
- Grafana SLO 공식 문서
- Introduction to SLOTH Prometheus SLI Generator — Medium (Oct 2024)
- The SLO Toolkit: Setup & Alerting with Pyrra — tb.lx insider
- Pyrra on Wikimedia — Wikitech
- How we built a complex SLO app tightly integrated with Grafana — GrafanaCON 2024
- How to Define and Configure SLOs for Kubernetes Services — OneUptime Blog