시계열 기반으로 메트릭을 수집, 저장하는 모니터링 도구
메트릭: 시스템이나 애플리케이션의 상태를 수치로 표현한 데이터
프로메테우스는 인프라(리눅스 서버, 윈도우 서버, 네트워크 장비 등), 애플리케이션(웹 서버, 데이터베이스, 메시지 브로커 등), 클라우드 서비스(AWS, GCP, Azure 리소스나 OpenStack, Ceph 같은 스토리지/클라우드 플랫폼 등) 혹은 커스텀 애플리케이션을 모니터링 할 수 있는 범용 모니터링 시스템이다.
프로메테우스는 대상의 메트릭 엔드포인트에 직접 접속해서 메트릭을 가져온는 pull 방식으로 동작하기 때문에 메트릭 엔드포인트만 있다면 어떤 대상이든 모니터링할 수 있다.
Pull 방식으로 메트릭 수집
Prometheus 서버가 대상(Target, Exporter라고도 함)에 주기적으로 접속해서 메트릭을 가져온다.
시계열(Time Series) 데이터 기반 저장
모든 데이터를 시계열 형태로 저장한다. 즉, 메트릭(metric)의 값이 "시간의 흐름에 따라 어떻게 변했는지" 기록하는 구조이다.
PromQL(Prometheus Query Language)
시계열 데이터를 질의하고 가공할 수 있는 쿼리 언어를 제공(?)한다.
경량 TSDB(Time Series Database) 내장
외부 DB 필요 없이 자체적으로 시계열 데이터를 디스크에 저장한다.
Alertmanager(알림 시스템) 연동
특정 조건이 발생하면 Alertmanager와 연동해 이메일, Slack, PagerDuty 등으로 알림을 전송할 수 있다.
Exporter : 메트릭을 수집해서 Prometheus가 이해할 수 있는 형식으로 엔드포인트에 노출시키는 에이전트
Prometheus Server : 메트릭 수집 + 저장 + 쿼리 담당
Prometheus Adaptor : Prometheus 메트릭을 Kubernetes Custom Metrics API가 이해할 수 있도록 변환
HPA (Horizontal Pod Autoscaler) : Kubernetes의 리소스 오토스케일링 기능 중 하나로 CPU, 메모리, 혹은 커스텀 메트릭(예: QPS, 요청 지연시간 등)을 기반으로 애플리케이션(파드)의 부하를 자동으로 감지해서 파드 개수를 늘리거나 줄이는 역할
✨정리 : 매트릭이 익스포터를 통해서 제공되면 프로메테우스 서버가 이를 스크래핑한 후 프로메테우스 어댑터에게 전달하여 HPA가 이해할 수 있는 형식으로 변환한다. HPA는 변환된 값을 감지하여 증가하는 시스템 부하에 대응하기 위해 파드를 오토스케일링한다.
파드는 쿠브 프록시를 이용해서 관리 프로메테우스 오퍼레이터가 쿠브 프록시를 감시한다.
[Pod] --메트릭--> [Prometheus Server] --PromQL결과--> [Prometheus Adapter] --Custom Metrics API--> [HPA] --replica 변경--> [Deployment] --Pod scale in/out
프로메테우스 오퍼레이터 : 쿠버네티스에 프로메테우스를 구성할 때 자원 관리와 프로비저닝을 수행하는 역할Alertmanager: 알람 처리
PromQL: 쿼리 언어
Grafana: 시각화 도구 (Prometheus와 자주 같이 사용됨)
프로메테우스 바이너리 다운로드 : wget https://github.com/prometheus/prometheus/releases/download/v3.5.0/prometheus-3.5.0.linux-amd64.tar.gz
압축 해제 : tar xvzf proetheus-3.5.0.linux-amd64.tar.gz
프로메테우스 사용을 위한 유저 추가 : sudo useradd --no-create-home --shell /bin/false prometheus
디렉토리 생성 및 소유자 변경
sudo mkdir /etc/prometheus
sudo mkdir /var/lib/prometheus
sudo chown -R prometheus /etc/prometheus
sudo chown -R prometheus /var/lib/prometheus
sudo cp prometheus-3.5.0.linux-amd64/prometheus /usr/loca/bin/
sudo chown prometheus /usr/local/bin/prometheus
cd /etc/prometheus
nano prometheus.yaml
prometheus.yaml
global:
srcrape_interval: 15s
evaluation_interval: 15s
scrape+configs:
- job_name: "prometheus"
static_configs:
- targets: ["locaslhost:9090"]
- job_name: "node
static_configs:
- targets: ['localhost:9100']
[Unit]
Description=Prometheus
Wants=network-online.target
After=network-online.target
[Service]
User=prometheus
Group=prometheus
Type=simple
ExecStart=/usr/local/bin/prometheus \
--config.file /etc/prometheus/prometheus.yaml \
--storage.tsdb.path /var/lib/prometheus/ \
--storage.tsdb.max-block-duration=1m \
--storage.tsdb.min-block-duration=1m \
--web.enable-lifecycle \
--web.enable-admin-api \
--log.level=info
[Install]
WantedBy=multi-user.target
sudo systemctl start prometheussudo systemctl status prometheus

wget https://github.com/prometheus/node_exporter/releases/download/v1.9.1/node_exporter-1.9.1.linux-amd64.tar.gztar xvf node_exporter-1.9.1.linux-amd64.tar.gzsudo useradd --no-create-home --shell /bin/false node_exportersudo cp node_exporter-1.9.1.linux-amd64/node_exporter /usr/local/bin/sudo chown node_exporter /usr/local/bin/node_exportersudo nano /etc/systemd/system/node_exporter.service[Unit]
Description=Node Exporter
Wants=network-online.start
After=network-online.target
[Service]
Type=simple
User=node_exporter
Group=node_exporter
ExecStart=/usr/local/bin/node_exporter
Restart=on-failure
[Install]
WantedBy=multi-user.target
서비스 실행 : sudo systemctl start node_exporter
node_exporter 서비스 실행을 위해서는 prometheus 서비스가 실행중이어야 한다.
서비스 실행 상태 확인 : sudo systemctl status node_exporter
포트 포워딩 후 브라우저에서 확인



9100/metrics 경로를 통해서 데이터를 제공하면 프로메테우스 서버는 pull 방식으로 익스포터에서 그 데이터를 수집해서 시계열 데이터베이스에 저장한다.
http_requests_total {status="200", method="GET"} @숫자1 숫자2
http_requests_total은 2개의 레이블(status와 method)을 포함하는데 status 레이블은 3종류(200-정상응답, 400-클라이언트 오류, 500-서버오류) method 레이블은 GET과 POST 2종류
실제로는 3 * 2 = 6개의 시계열 데이터를 생성한다.
메트릭에 데이터의 개수를 통해 프로메테우스의 성능과 저장 용량이 결정되기 때문에 중요하다.
위 형식의 데이터는 프로메테우스 데이터베이스인 TSDB에 저장된다.
특징
시계열은 시간순으로 인덱싱되는 숫자 데이터 포인트의 시퀀스로 정의된다.
프로메테우스 데이터 포인트는 일정한 시간 간격으로 수집되는데, 이 데이터를 그래프 형식으로 나타낼 때 x축은 시간이 되고, y축은 데이터 값이 된다.
메모리에 수집된 샘플은 기본 두 시간 단위로 디스크로 플러시되고 블록이 생성된다.
크기가 작은 파일과 데이터가 다수 존재하면 모든 파일에 대한 인덱스를 만들고 검색해야 하기 때문에 조회 속도가 느려진다. 반면에 파일 크기가 너무 크면 효율성이 떨어진다. 따라서 블록을 잘 쪼개거나 병합해야 한다.
예를 들어, 파일 크기가 1GB인데 검색 조건에 필요한 데이터의 크기는 1KB라면 1KB를 조회하기 위해서 메모리에 1GB의 데이터를 로딩해야 한다. 이로 인해 불필요한 IO가 발생하게 된다.
--storage.tsdb.min-block-duration 옵션 : 하나의 블록에 저장되는 데이터의 시간을 의미
기본값 : 2h, 하나의 블록 디렉토리에 2시간 동안의 데이터가 저장됨
--storage.tsdb.max-block-duration 옵션 : 하나의 블록에 최대로 저장할 수 있는 데이터의 시간
기본값 : --storage.tsdb.retention.time(유지율을 설정하는 옵션)의 10%
기본적으로 하나의 블록에는 3개의 블록이 병합된다.
--storage.tsdb.min-block-duration이 2h라면 두 시간 단위의 레벨 1블록이 만들어지고, 3개의 블록이 만들어지는 순간 레벨 2블록으로 병합된다. 즉, 실제로는 하나의 블록이 6h의 데이터를 저장한다.
kube-prometheus 다운로드 : sudo git clone https://github.com/prometheus-operator/kube-prometheus.git
설치 : kubectl create -f kube-prometheus/manifests/setup

확인 : kubectl get crd -n monitoring
관리화면에 접속하기 위해서 포트포워딩을 구성 : kubectl --namespace monitoring port-forward svc/prometheus-k8s 9090
alertmanager를 사용하기 위해서 포트포워딩을 구성 : kubectl --namespace monitoring port-forward svc/prometheus-k8s 9093
파드 확인 : kubekubectl get pods -n monitoring
헬름 또는 오퍼레이터를 이용해서 구성할 수 있다.
쿠버네티스 오퍼레이터의 장점
프로메테우스 어댑터 ➡️ HPA ➡️ Deployment ➡️ Pod ⬅️ Ingress ⬅️ 유저 트래픽
파드는 kubeproxy가 관리하고 이를 서비스 모니터가 모니터링하고 서비스 모니터는 프로메테우스 오퍼레이터의 일부분이고 프로메테우스 컨피그 파일에 의해서 관리된다.
kubectl get servicemonitor -n monitoringkubectl edit servicemonitor grafana -n monitoringkubectl edit pod prometheus-k8s-0 -n monitoringhelm repo add prometheus-community https://prometheus-community.github.io/helm-chartshelm repo updatekubectl create namespace monitoringhelm install prometheus prometheus-community/prometheus --namespace monitoringhelm list --namespace monitoringkubectl get pods -n monitoring

⚠️ 파드가 제대로 설치되지 않은 경우
1. 리소스 부족 가능성
kubectl describe pod 파드이름 -n monitoringhelm show values prometheus-community/prometheus > values.yaml 혹은 helm install prometheus prometheus-community/prometheus -f values.yaml -n monitoringkubectl get pvc -n monitoringkubectl get schelm uninstall prometheus -n monitoringhelm install prometheus prometheus-community/prometheus --namespace monitoring --set server.persistentVolume.enabled=false --set alertmanager.persistenctVolume.enabled=false --set pushgateway.persistenctVolume.enabled=false
삭제 후 재설치해도 일부 pod가 제대로 생성되지 않고 있다.
kubectl apply -f https://raw.githubcontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yamlkubectl get pods -n local-path-storage 혹은 kubectl get storageclasshelm install prometheus prometheus-community/prometheus --namespace monitoring --set server.persistentVolume=true --set alertmanager.persistentVolume=true --set alertmanager.persistentVolume.storageClass="local-path" --set server.persistentVolume.storageClass="local-path"네임스페이스 리소스 제한 문제
kubectl describe quota -n monitoring
kubectl prot-forward -n monitoring deploy/prometheus-server 9090:9090helm uninstall prometheus -n monitoring
kubectl delete pvc --all -n monitoring
kubectl patch storageclass 클래스이름 -p '{"metadata": {"annotation":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
All in One 패키지도 helm stable 저장소에 없어서 저장소를 추가해야 한다.
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
PVC를 위한 클래스 추가(local-path를 기본값으로 설정)
namespace 추가(monitoring)
설치 : helm install 이름 헬름차트 -n namespace
helm install monitoring prometheus-community/kube-prometheus-stack -n monitoring
확인 : helm list -n monitoring
kubectl get pods -n monitoring
kubectl get svc -n monitoring

kubectl port-forward -n monitoring svc/monitoring-grafana 3000:80ID는 admin, 비밀번호는 prom-operator
kubectl port-forward -n monitoring svc/monitoring-kube-prometheus-prometheus 9090:9090values.yaml 파일을 추출
helm show values prometheus-community/kube-prometheus-stack > values.yaml
Prometheous의 Service Type을 변경해서 외부에서 UI에 접근하도록 설정
values.yaml 파일을 열어서 grafana의 service type을 NodePort로 수정
수정한 내용 적용 : helm upgrade monitoring prometheus-community/kube-prometheus-stack -n monitoring -f values.yaml
kubectl create namespace custom-metricsapiVersion: apps/v1
kind: Deployment
metadata:
name: autoscaling-deploy
namespace: custom-metrics
spec:
replicas:
template:
metadata:
labels:
app: autoscaling
release: prom
spec:
containers:
- name: autoscaling
image: query.io/branch/prometheus-example-app:v1.0.0
ports:
- containerPort: 8080
apiVersion: v1
kind: Service
metadata:
labels:
app: sample-app
name: sample-app
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
nodePort: 32001
selector:
app: sample-app
type: NodePort
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: sample-app
labels:
app: sample-app
spec:
selector:
matchLabels:
app: sample-app
endpoints:
- port: http
apiVersion: autoscaling/v2
kind: HorizontalPodAutoScaler
kubectl get deploy -n monitoring