쿠버네티스

[Observability] Prometheus 이해하기

안녕유지 2025. 3. 1. 17:53

Prometheus

CNCF에서 관리하는 오픈소스 모니터링 및 알람 시스템입니다.

많은 서버가 분산된 환경에서는 장애 감지와 성능 모니터링이 어렵습니다. 예를 들어, 애플리케이션의 응답 속도 지연, 서버의 과부하 또는 리소스 부족, 특정 하드웨어 장애 발생 등을 신속하게 감지하는 것이 중요합니다.

Prometheus는 이러한 문제를 해결하기 위해 시계열 데이터(time-series data) 수집 및 저장에 최적화된 구조를 갖추고 있으며, 쿼리 언어(PromQL)를 통해 데이터를 분석하고, 알람을 설정할 수 있습니다.

 

 

 

 

 

Prometheus의 구성요소

1) Prometheus operator

쿠버네티스 환경에서 Prometheus의 배포와 관리를 자동화하는 도구, 설치부터 설정관리까지 CRD로 관리합니다.

  • Custom Resource 정의 및 관리
    • Podmonitor, Servicemonitor 등 CRD 정의하여 쿠버네티스 내에서 관리
  • 자동 설정 및 업데이트
    • 관리하는 리소스의 변경을 감자항 Prometheus 스크래핑 대상 설정을 자동으로 업데이트

 

2) Prometheus Server

설정된 scrape_configs에 따라 메트릭을 주기적으로 수집 및 저장합니다. (TSDB 사용)

  • exporter로 부터 메트릭 읽어와서 수집 (pull 방식)
  • 메트릭을 TSDB에 저장
  • PromQL을 통해 데이터 조회

 

3) Exporter

Prometheus가 메트릭을 가져올 수 있도록 어플리케이션이나 시스템을 모니터링하는 메트릭 변환기로 미리 메트릭을 만들어놓아 노출시킵니다.

  • node-exporter : OS 레벨 메트릭 (CPU, 메모리, 디스크) 
  • kube-metric-exporter : Kubernetes 리소스 상태 정보
  • cAdvisor : 컨테이너 메트릭 모니터링 
  • blackbox-exporter : 외부 HTTP/S 서비스 모니터링 

 

4) AlertManager

Prometheus에서 알림을 관리하는 컴포넌트입니다.

 

5) PushGateway

Prometheus는 기본적으로 Pull 방식이지만, 단기 실행되는 작업 (ex, 배치 작업)의 데이터 저장하려면 Push 방식이 필요한데, 그런 경우에 사용합니다.

 

6) ServiceDiscovery

모니터링 해야할 타겟 서비스 대상을 자동으로 발견하고 스크래핑 대상으로 추가하는 기능입니다.

  • 일반적인 물리 장비에 설치되는 prometheus 라면 exporter를 노출하여 직접 스크래핑하지만, 쿠버네티스에서는 동적으로 생성, 삭제되는 서비스가 많기 때문에 서비스 디스커버리가 필요
  • Prometheus Operator를 사용하기 때문에 scrape_configs를 직접 설정할 필요 없이, ServiceMonitor 리소스 이용하여 라벨, 엔드포인트 매칭하는 서비스를 감시하여 설정이 반영

 

ServiceMonitor

특정 라벨 가진 쿠버네티스 서비스 대상 모니터링 (서비스 엔드포인트 통해 메트릭 수집)

  • node-exporter
  • kube-state-metrics
  • kubelet
  • api-server
  • coredns
  • kube-controller-manager
  • kube-proxy
  • 등등

PodMonitor

특정 라벨 가진 쿠버네티스 파드 대상 모니터링 (파드 메트릭 엔드포인트 통해 수집)

 

ServiceMonitor는 Service의 엔드포인트만 스크래핑하기 때문에 Pod가 여러 개일때 일부 Pod만 스크래핑할 수 있습니다.

PodMonitor는 각 Pod에 직접 접근해서 개별적으로 메트릭을 수집하기 때문에 모든 Pod의 데이터를 빠짐없이 수집할 수 있어서 HPA환경이나 수집해야하는 Pod 수가 많은 경우 Servicemonitor보다는 Podmonitor 수집이 필요합니다.

 

Istio 메트릭이 쿠버네티스 메트릭과 통합되는 이유

사내 환경에서 별 다른 설정을 하지 않았는데 어플리케이션 서비스에서 사용하는 Istio 메트릭도 같이 수집되고 있어서, 이유가 궁금해져서 작성하였습니다.

https://istio.io/latest/docs/ops/integrations/prometheus/#option-1-metrics-merging

 

Prometheus

How to integrate with Prometheus.

istio.io

 

Istio의 Envoy Proxy들은  metric을 프로메테우스 metric 형식으로 노출합니다. - Envoy Proxy의 메트릭은 Pod의 15090 포트로 노출

Istio는 기존 어플리케이션이 노출하는 프로메테우스 메트릭이 있다면 그걸 병합해서 merged prometheus telemtry의 포트인 15020에 덮어씁니다. 이렇게 두 메트릭을 병합하는 옵션은 Istio meshConfig.enablePrometheusMerge 옵션에 의해 설정되는데, 기본값이 true라서 Istio proxy가 주입되었다면 기존 어플리케이션의 메트릭이 병합됩니다. 그리고 istio proxy가 주입된 Pod은 prometheus Scrape을 위한 prometheus.io/xxx 등의 어노테이션이 붙습니다.

 

Prometheus 메트릭 종류 

1) Gauge

특정 시점 값을 표현하기 위해 사용하는 메트릭 타입

현재 상태 측정한 값으로 증가/감소 가능

ex)

  • 메모리 사용량 (node_memory_Active_bytes)
  • CPU 온도 (node_thermal_zone_temp)
  • 현재 연결된 세션 수 (nginx_connections_active)
  • 현재 큐(queue)에 남아 있는 작업 개수 (queue_length)

2) Counter 

누적된 값을 표현하기 위해 사용하는 메트릭 타입, 증가 시 구간별로 변화 확인 가능

누적 값으로 항상 증가하는 값

ex)

  • HTTP 요청 횟수 (http_requests_total)
  • 프로세스 시작 이후 실행된 명령 개수 (process_cpu_seconds_total)
  • 패킷 전송량 (node_network_transmit_bytes_total)
  • 에러 발생 횟수 (nginx_http_requests_errors_total)

3) Summary

구간 내에 있는 메트릭 값의 빈도, 중앙값 등 통계적 메트릭

중앙값으로 백분위수 등 통계 기반 메트릭

ex) 

  • HTTP 응답 시간의 중앙값 (http_request_duration_seconds{quantile="0.5"})
  • 상위 99% 사용자 응답 시간 (http_request_duration_seconds{quantile="0.99"})

4) Histogram

사전에 미리 정의한 구간 내에 있는 메트릭 값의 빈도 측정 (함수로 측정 포맷을 변경)

범위 기반 분포 저장

ex)

  • HTTP 요청 응답 시간 분포 (http_request_duration_seconds_bucket)
  • 디스크 I/O 속도 분포
  • 응용 프로그램에서 처리하는 요청 크기 분포

 

Prometheus 연산자

  • sum : 메트릭 합산
  • count : 메트릭 갯수
  • avg : 메트릭 평균
  • stddev, stdvar : 표준편차, 표준 분산
  • min, max : 최대 최소
  • topk, bottomk : 메트릭 상위 하위 n번째
  • count_values : 시계열에 대한 빈도 히스토그램
  • without : 특정값을 제외한 메트릭 선택
  • by : 메트릭 그룹화

 

 

Prometheus 데이터 저장 과정

프로메테우스는 데이터를 시계열 데이터(Series로 저장. 최근 데이터 는 WAL + mmap chunk에 저장되고, 일정 기간 지나면 Block단위로 압축해서 디스크에 저장되는 구조

  • 인메모리 : WAL(Wrtie Ahead Logging)파일 & 인메모리 버퍼
  • 로컬 파일 시스템 : 일반적인 chunk 블록 파일

Prometheus 기본 용어

metric data 
  • exporter가 prometheus에 노출한 데이터


Series
  • metric data 이름 + 라벨 조합
  • prometheus에 Series + 시계열값 (time, value) 으로 저장
  • proemetheus 내부에서는 series 형태로 데이터 관리하고, 새로운 값이 들어올때마다 새로운 Series에 추가


Head Chunks - 2시간 이내 데이터 메모리에 저장 (메모리 + mmap 활용)

WAL(Write Ahead Log) - 로그
  • 데이터 유실을 방지하고 복구하기 위해, 새로운 Series 데이터를 먼저 기록하는 로그 파일
  • 데이터를 디스크에 바로 저장하지 않고 WAL로 기록 후 mmaap 데이터를 나중에 Block Chunk으로 변환, 그 이후 wal 삭제 
  • 데이터를 메모리에 저장하지만, 주기적으로 WAL 파일에 백업, 데이터를 인메모리와 WAL에 저장하고 있다가 데이터를 chunk 블록으로 flush 한뒤 가장 오래된 WAL 파일 삭제
  • 즉시즉시 기록하는 로그라 압축하지 않아서 데이터 크기 큼


M-map chunks : Memory Mapped Chunks - 현재 활성 데이터
  • 최근 데이터를 메모리에 저장할 때 mmap (메모리 매핑) 사용해 빠르게 접근
  • 메모리 내에서는 압축된 chunk 형태로 데이터 유지
  • Prometheus가 재시작 될 경우, mmap chunk가 날아갈 수 도 있기 때문에 WAL을 복구 (Reply)하는 과정이 필요 (2시간 이내 데이터)


Block Chunks - 2시간 이상 데이터 디스크에 저장
  • Mmap Chunk 데이터를 Block chunk으로 변환해서 디스크에 저장
  • Block  내부에는 여러 개의 chunk 포함

 

1) Series 생성

Prometheus가 특정 metric_name{label1="value1", label2="value2"} 형태의 시계열 데이터를 수집합니다.

각 시계열 데이터는 Series라고 부릅니다.

2) WAL(Write-Ahead Log)에 저장

데이터는 WAL에 먼저 저장해서, 프로메테우스가 갑자기 종료되더라도 복구 가능합니다. (mmap chunk에 먼저 쓰지 않음)

WAL은 메모리에 저장되며, 이후 디스크에 주기적으로 기록합니다.

3) mmap chunk에 데이터 저장 (메모리 활용)

빠르게 쿼리할 수 있도록(2시간 동안 데이터 유지할 수 있도록) 최신 데이터를 메모리 매핑합니다.

4) Block chunk에 주기적인 데이터 압축(디스크 저장)

일정 시간 지나면 mmap chunk 데이터를 Block으로 변환하여 디스크에 저장합니다.

5) Compaction (데이터 압축)

Block이 여러개 쌓이면 오래된 Block을 합쳐서 Compaction 수행합니다.

 

PromQL이 메모리에 없는 청크를 필요로 하면 디스크 청크를 메모리로 로드합니다. 디스크 시리즈 파일에 존재하지 않고 메모리에만 존재하는 청크는 장애 발생으로 손실 될 수 있으므로 이를 방지하기 위해 프로메테우스는 주기적으로 체크 포인트를 파일로 기록하고 재시작시 메모리로 로드합니다.

'쿠버네티스' 카테고리의 다른 글

[Observability] Prometheus 이해하기 2 + Prometheus adapter  (0) 2025.03.04
Istio  (1) 2023.04.21