Prometheus 아키텍처
I’m happy to translate the article for you, but I’ll need the full text you’d like translated. Could you please paste the content (excluding the source line you already provided) here? Once I have it, I’ll keep the source link unchanged and translate the rest into Korean while preserving all formatting, markdown, and technical terms.
소개
이 시리즈는 현대 모니터링 스택의 주요 구성 요소 아키텍처에 초점을 맞춘 첫 번째 글입니다.
처음에는 Mimir, Thanos, Cortex와 같은 Prometheus 생태계의 다양한 변형 및 도구들을 비교하는 것으로 시작하려고 했습니다. 하지만 결국 Prometheus 자체부터 시작하는 것이 더 의미가 있습니다. 왜냐하면 이들이 모두 기반하고 시작된 것이 바로 Prometheus이기 때문입니다.
아마도 여러분의 IT 여정 중 어느 시점에서든 관측성을 위해 Prometheus 형식으로 노출된 메트릭을 들어보았거나, 보았거나, 사용해 본 적이 있을 것입니다. Prometheus는 클라우드 네이티브 컴퓨팅 재단(CNCF)에서 졸업한 오픈소스 프로젝트로, Kubernetes에 이어 두 번째로 이 지위를 획득한 프로젝트입니다.
Kubernetes 환경에서 매우 뛰어나게 동작하지만, 클라우드 및 컨테이너 기반 환경 전반에도 완벽하게 적응합니다.
Prometheus는 pull‑based 방식을 사용해 메트릭을 수집합니다. 에이전트가 데이터를 적극적으로 전송하는 시스템과 달리, Prometheus는 소스로 직접 가서 데이터를 pull 합니다.
그림 1 – Prometheus 데이터‑수집 흐름 (pull vs. push)
[Insert diagram showing pull and push mechanisms]
Getting Started
가장 간단한 시작 방법은 Prometheus를 컨테이너로 실행하는 것입니다:
docker run -p 9090:9090 prom/prometheus:latest
운영하려면 YAML 구성 파일이 필요합니다. 여기에서 전역 파라미터, 스크레이프 주기 및 대상들을 정의합니다.
Basic startup configuration
global:
scrape_interval: 15s # Scrape frequency
evaluation_interval: 15s # Rule evaluation frequency
external_labels:
cluster: 'demo-cluster'
environment: 'dev'
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
labels:
instance: 'prometheus-server'
instance 라벨(및 추가하는 다른 라벨)은 나중에 쿼리 시 메트릭을 필터링하고 집계하는 데 사용되며, 데이터에 대한 컨텍스트를 제공합니다.
일반적인 Prometheus 배포
A typical deployment consists of several elements working together:
| Component | Description |
|---|---|
| Prometheus Server | 작업의 두뇌 역할을 하며, 수집 및 저장을 담당합니다. |
| Targets | 애플리케이션이나 서버가 메트릭을 노출하는 엔드포인트. |
| Exporters | 서드파티 시스템의 메트릭을 Prometheus 형식으로 변환하는 에이전트. |
| Time‑Series Database (TSDB) | 시계열 데이터에 최적화된 내부 데이터베이스. |
| PromQL | 데이터를 분석하기 위한 강력한 쿼리 언어. |
| Pushgateway | 단기 작업을 처리하기 위한 보조 구성 요소. |
| Alertmanager | 알림을 관리, 그룹화 및 라우팅합니다. |
| Client Libraries | 애플리케이션 내에서 직접 사용자 정의 코드를 계측하기 위한 라이브러리. |
그림 2 – 모든 핵심 구성 요소가 포함된 완전한 Prometheus 아키텍처
[Insert diagram showing all core components and their interactions]
Component Details
1. Prometheus Server
서버는 중앙 구성 요소입니다. 세 가지 주요 기능을 수행합니다:
- Scraping – 설정된 대상에 주기적으로 HTTP로 연결하여 메트릭을 가져옵니다.
- Storage – 수집된 데이터를 로컬 TSDB에 기록합니다.
- Evaluation & Querying – 알림 규칙을 평가하고 PromQL API를 통해 쿼리(예: Grafana) 요청에 응답합니다.
실제로 이는 운영의 핵심이며, 소스에서 저장소로 데이터가 지속적으로 흐르도록 보장합니다.
2. Targets
Targets는 메트릭의 출처입니다. 사실상 무엇이든 될 수 있습니다: Linux 서버, Java 애플리케이션, API 엔드포인트, 혹은 Kubernetes 파드 등. 기본적으로 Prometheus는 대상의 /metrics HTTP 엔드포인트에서 메트릭을 가져오지만, 이 경로는 설정으로 변경할 수 있습니다.
scrape_configs:
- job_name: 'node-metrics'
static_configs:
- targets: ['instance-dev:9100']
labels:
instance: 'instance-dev'
Common target ports
| Port | Typical Exporter / Service |
|---|---|
| 9100 | node_exporter – OS 메트릭 |
| 8080 | 사용자 정의 애플리케이션 메트릭 |
| 8081 | cAdvisor – Docker 컨테이너 메트릭 |
3. Exporters
모든 소프트웨어가 Prometheus 형식으로 메트릭을 기본 제공하는 것은 아닙니다(예: MySQL, Redis). Exporters는 작은 바이너리로, 원본 시스템의 네이티브 API를 사용해 메트릭을 수집하고 이를 Prometheus가 이해할 수 있는 텍스트 형식으로 변환해 HTTP 엔드포인트에 노출합니다.
Popular exporters (maintained by the community and officially)
node_exporter– 하드웨어 및 OS 메트릭(CPU, 메모리, 디스크).blackbox_exporter– HTTP, DNS, TCP, ICMP 등 외부 엔드포인트를 프로빙.mysqld_exporter/postgres_exporter/redis_exporter– 데이터베이스 전용 메트릭.
전체 목록은 공식 문서에서 확인할 수 있습니다.
Example metric output
From node_exporter (system)
node_cpu_seconds_total{instance="instance-dev",cpu="0",mode="idle"} 145893.45
node_memory_MemAvailable_bytes{instance="instance-dev"} 4294967296
From cAdvisor (containers)
container_cpu_usage_seconds_total{instance="instance-dev",name="my-app",image="nginx:latest"} 234.56
Custom application metrics
http_requests_total{instance="instance-dev",method="GET",status="200"} 1547
http_request_duration_seconds{instance="instance-dev",endpoint="/api/users"} 0.234
4. Time‑Series Database (TSDB)
Prometheus가 수집하는 데이터는 정의상 시계열이며, 시간에 따라 변하는 숫자값에 타임스탬프가 항상 붙어 있습니다. 이를 효율적으로 저장하기 위해 Prometheus는 자체 TSDB를 사용하며, 높은 쓰기 처리량과 빠른 읽기를 위해 최적화되어 있습니다.
Prometheus는 디스크에 블록이라는 구조로 메트릭을 저장합니다.
Figure 3 – Prometheus TSDB lifecycle and storage flow
[Insert diagram showing in‑memory buffering, block creation, compression, and retention]
Key characteristics
- Append‑only 설계 → 높은 쓰기 성능.
- 최신 데이터는 메모리에 보관되어 빠르게 접근 가능하고, 주기적으로 디스크에 플러시됩니다.
- 각 블록은 압축된 샘플, 빠른 조회를 위한 인덱스, 메타데이터를 포함합니다.
Retention – 기본적으로 Prometheus는 데이터를 로컬에 15 일 동안 보관합니다. 오래된 블록은 공간을 확보하기 위해 삭제됩니다. Prometheus는 원래 장기 저장소 솔루션으로 설계된 것은 아니지만, 보존 기간을 조정하거나 원격 저장소 통합(예: Thanos, Cortex)을 사용해 더 긴 보관 기간을 구현할 수 있습니다.
다음 글에서는 원격 저장소 솔루션과 Prometheus 기반 모니터링 스택의 확장 전략에 대해 살펴보겠습니다.
PromQL (Prometheus 쿼리 언어)
PromQL은 데이터를 검색하고 분석하기 위한 통합 함수형 쿼리 언어입니다. Grafana에서 대시보드를 만들거나 알림을 정의할 때 PromQL을 사용합니다.
이 언어를 사용하면 시계열 데이터에 대해 선택, 필터링, 집계, 그리고 복잡한 수학 연산을 수행할 수 있습니다.
간단한 메트릭 선택 (현재 값)
http_requests_total
라벨을 통한 필터링
http_requests_total{instance="instance-dev", status="200"}
초당 요청 비율 (지난 5분 평균)
rate(http_requests_total[5m])
인스턴스별 집계된 요청 비율의 전체 합계
sum(rate(http_requests_total[5m])) by (instance)
사용 가능한 메모리 비율 계산
(node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100
CPU 사용량 ( idle 가 아닌 모든 것)
100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
PromQL에는 다음과 같은 함수도 포함됩니다:
- 백분위수:
histogram_quantile - 선형 예측:
predict_linear - 시간 비교:
offset
Push Gateway (for short‑lived jobs)
Prometheus는 pull 모델을 사용하지만, 짧은 시간에 끝나는 작업(예: 배치 백업 스크립트)은 Prometheus가 스크레이프하기 전에 완료될 수 있습니다.
Push Gateway는 중간 캐시 역할을 합니다: 작업이 메트릭을 게이트웨이에 push하고, Prometheus는 정해진 간격으로 게이트웨이를 스크레이프합니다.
예시: 작업 수행 시간을 나타내는 메트릭 전송
echo "job_duration_seconds 45.2" | curl --data-binary @- \
http://pushgateway:9091/metrics/job/batch-job/instance/worker-1
Note: Push Gateway는 매우 특정한 사용 사례에만 적용됩니다. Prometheus를 push‑기반 시스템으로 바꾸기 위해 사용해서는 안 됩니다. pull 모델이 여전히 선호되는 이유는 다음과 같습니다:
- Prometheus가 부하를 제어할 수 있습니다.
- 비활성 대상(
up/down)을 쉽게 감지합니다.- 서비스 디스커버리를 단순화합니다.
알림 아키텍처
알림에 관련된 구성 요소들의 책임을 혼동하기 쉽습니다.
| 구성 요소 | 책임 |
|---|---|
| Prometheus Server | 문제를 감지하고(PromQL 규칙을 평가) 알림 상태를 발생시킵니다. |
| Alertmanager | 발생한 알림을 수신하고 이를 어떻게 처리할지 결정합니다(그룹화, 억제, 무음, 라우팅). |
Alertmanager 기능
- 그룹화 – 유사한 알림을 여러 개 하나의 알림으로 결합합니다.
- 억제 – 중요한 알림이 활성화된 경우 덜 중요한 알림을 억제합니다.
- 무음 – 계획된 유지보수 기간 동안 알림을 무음 처리합니다.
- 라우팅 – 알림을 다양한 채널(예: PagerDuty, Slack)로 전송합니다.
예시: Prometheus 감지 규칙
groups:
- name: example
rules:
- alert: HighCPUUsage
expr: rate(node_cpu_seconds_total{mode!="idle"}[5m]) > 0.8
for: 5m # 조건이 5분 동안 유지되어야 함
labels:
severity: warning
예시: Alertmanager 라우팅 구성
route:
# 기본 라우트
receiver: 'team-slack'
routes:
# critical 알림에 대한 별도 라우트
- match:
severity: critical
receiver: 'pagerduty-oncall'
receivers:
- name: 'team-slack'
slack_configs:
- channel: '#alerts-general'
- name: 'pagerduty-oncall'
pagerduty_configs:
- service_key: '...'
자체 애플리케이션 계측하기
기성 시스템용 익스포터를 사용하는 것 외에도, 가장 좋은 방법은 자체 애플리케이션을 계측하여 비즈니스 및 성능 메트릭을 기본적으로 노출하도록 하는 것입니다.
Prometheus는 Go, Java/Scala, Python, Ruby에 대한 공식 클라이언트 라이브러리를 제공하며, .NET, Node.js, Rust 등 커뮤니티가 유지 관리하는 라이브러리도 있습니다. 몇 줄의 코드만으로 애플리케이션이 /metrics 엔드포인트를 제공하도록 할 수 있습니다.
Python 예제
from prometheus_client import Counter, Histogram, start_http_server
import time
# 1. Define the metrics
requests_total = Counter(
'http_requests_total',
'Total HTTP requests received',
['method', 'endpoint', 'status'] # Labels for dimensionality
)
request_duration = Histogram(
'http_request_duration_seconds',
'Histogram of request duration',
['endpoint']
)
# 2. Use in application code (e.g., using decorators)
@request_duration.labels(endpoint='/api/users').time()
def handle_user_request():
# Application logic...
time.sleep(0.1)
# Increment the counter at the end
requests_total.labels(method='GET', endpoint='/api/users', status='200').inc()
if __name__ == '__main__':
# 3. Start an HTTP server to expose the metrics
start_http_server(8000)
print("Metrics server running on port 8000...")
# Main application loop...
클라이언트 라이브러리는 스레드 안전성, 올바른 데이터 포맷팅 및 기타 복잡한 작업을 여러분을 대신해 처리합니다.
왜 프로메테우스가 시장 표준이 되었는가
| 강점 | 설명 |
|---|---|
| Pull 모델 | 대상에서 흐름 제어, 디버깅 및 장애 감지를 용이하게 합니다. |
| 다차원 데이터 | 라벨을 통해 매우 유연한 분석이 가능합니다. |
| PromQL | 모니터링 데이터를 위해 특별히 설계된 쿼리 언어입니다. |
| 운영 단순성 | 단일 정적 바이너리이며, 배포가 쉽고 복잡한 외부 의존성이 없습니다. |
| 서비스 디스커버리 | Kubernetes, AWS, Azure 등과의 네이티브하고 동적인 통합을 지원합니다. |
| 오픈 에코시스템 | 거의 모든 기술에 대한 수백 개의 익스포터가 제공됩니다. |
Prometheus의 제한 사항
- 단일‑노드 아키텍처 – 기본적인 수평 확장을 위해 설계되지 않았으며, 과부하가 발생하면 여러 서버에 수동으로 샤딩해야 합니다.
- 로컬 및 일시적 스토리지 – 데이터가 서버의 로컬 디스크에 저장됩니다; 서버가 죽고 디스크가 손실되면 데이터도 사라집니다. 기본적인 데이터 복제 기능이 없습니다.
- 장기 보존 – 매우 오랜 기간 데이터를 저장하면 외부 솔루션(예: Thanos, Cortex, 또는 Mimir에 원격 쓰기) 없이 비용이 많이 들거나 실용적이지 않을 수 있습니다.
이러한 트레이드오프를 이해하면 Prometheus가 적합한 도구인 경우와 고가용성 또는 장기 스토리지를 위해 보완 시스템이 필요한 경우를 판단하는 데 도움이 됩니다.
Overview
- 기간 보존: Prometheus에 수년간의 히스토리 데이터를 저장하는 것은 효율적이지 않습니다.
- 분산된 전역 뷰: 여러 Kubernetes 클러스터마다 자체 Prometheus 인스턴스가 있을 경우, 모든 클러스터에 걸친 메트릭에 대한 기본적인 통합 뷰가 없습니다.
이러한 아키텍처 제한은 Prometheus를 **“수용하고 확장”**하는 도구들, 예를 들어 Thanos, Cortex, Mimir의 개발을 촉진했습니다.
다음은?
다가오는 기사들에서 위의 제한을 극복하는 방법을 탐구할 것입니다:
- Thanos – 장기 저장소(객체 스토리지를 통해)를 추가하고 Prometheus에 대한 통합된 글로벌 뷰를 제공합니다.
- Cortex – 다중 테넌트, 수평 확장 가능한 Prometheus를 위한 최초 솔루션입니다.
- Mimir – Cortex의 진화형으로, 대규모 확장성과 운영 단순성에 초점을 맞춥니다.
태그
#Prometheus #Monitoring #Observability #CNCF #DevOps #SRE