Monitoring

Prometheus 와 Thanos 설치 및 구성

Somaz 2024. 9. 19. 08:19
728x90
반응형

Overview

지난번 포스팅에서 Prometheus와 Thanos에 대해서 알아보았다.

 

이번에는 Prometheus와 Thanos 설치 및 구성에 대해서 알아본다. 모든 설치는 Helm으로 진행된다.

그리고 PV와 PVC를 설정해야 하기때문에 Storage 구성을 위한 Provionser 설정은 되어 있어야 한다.

그리고 Object Storage(AWS S3, GCP GCS, Minio, Ceph..etc) 준비도 필요하다.

 

Objcet Storage 구성방법

https://thanos.io/v0.8/thanos/storage.md/

 

Local Storage Dynamic Provisoning

https://github.com/rancher/local-path-provisioner/tree/master

 

NFS Storage Dynamic Provisoning

https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner

 

출처 : https://particule.io/en/blog/thanos-monitoring/

 

 

 

 

📅 관련 글

2024.03.05 - [Monitoring] - Fluent Bit (With Loki)

2024.09.12 - [Monitoring] - Prometheus와 Thanos란?

2024.09.12 - [Monitoring] - Prometheus 와 Thanos 설치 및 구성

2024.09.12 - [Monitoring] - Loki란?

2024.09.13 - [Monitoring] - Loki와 Promtail 설치

2025.01.13 - [Monitoring] - ELK Stack 구축해보기

 

 

 

 

 

 

 


 

 

 

Prometheus 설치

Prometheus는 kube-prometheus-stack chart와 prometheus-community chart를 활용한 설치방법에 대해서 알아본다.

 

 

그리고 아래의 values 파일은 내가 필요한 Component들만 가지고 설치한 예시이다. 따라서 `values.yaml` 을 확인하고 필요한 Component들을 추가 또는 제거해주면 된다.

 

 

 

 


 

 

 

 

Prometheus CRD(CustomResourceDefinition) 설치

 

먼저 Prometheus 설치전에 CRD를 설치해 줘야 한다.

# repo 추가
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

# helm chart 확인
helm search repo prometheus-community/prometheus-operator-crds
NAME                                         	CHART VERSION	APP VERSION	DESCRIPTION                                       
prometheus-community/prometheus-operator-crds	14.0.0       	v0.76.0    	A Helm chart that collects custom resource defi...

# 설치
helm install prometheus-operator-crds -n monitoring prometheus-community/prometheus-operator-crds

# crd 확인
k get crd |grep monitoring

# 삭제방법
helm delete -n monitoring prometheus-operator-crds

 

 

 

 

 


 

 

 

 

 

Prometheus-Community 설치

# git clone
git clone https://github.com/prometheus-community/helm-charts.git

# 디렉토리 이동
cd helm-charts/charts/prometheus

# helm repo 등록
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

# helm dependency 설치
helm dependency update

mkdir values

 

 

`values/somaz.yaml`

server:
  name: server
  image:
    repository: quay.io/prometheus/prometheus
  persistentVolume:
    enabled: true
    accessModes:
      - ReadWriteOnce
    storageClass: "default"
  replicaCount: 1
  statefulSet:
    enabled: false
  service:
    enabled: true
    # type: ClusterIP
    type: NodePort
extraScrapeConfigs: |-
  - job_name: 'somaz-exporter'
    scrape_interval: 1h
    static_configs:
      - targets: ['localhost:30501']

alertmanager:
  enabled: true
  persistence:
    size: 2Gi

kube-state-metrics:
  enabled: true

prometheus-node-exporter:
  enabled: true

prometheus-pushgateway:
  enabled: true
  # Optional service annotations
  serviceAnnotations:
    prometheus.io/probe: pushgateway

 

 

설치 방법은 아래와 같다.

# 설치 방법
helm install prometheus-community . -n monitoring -f ./values/somaz.yaml

# 업그레이드 방법
helm upgrade prometheus-community . -n monitoring -f ./values/somaz.yaml

# helm 배포 확인방법
helm list -n monitoring

# 삭제 방법
helm delete -n monitoring prometheus-community

 

 

 

 

 


 

 

 

 

 

 

kube-prometheus-stack 설치

git clone https://github.com/prometheus-community/helm-charts.git

# 파일 복사 
sudo cp -r ~/helm-charts/kube-prometheus-stack .
cd ~ kube-prometheus-stack

# helm repo 등록
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

# values 파일 생성
mkdir -p values
cp values.yaml ./values/somaz.yaml

# 의존성 설치
helm dependency update ~/kube-prometheus-stack/

 

 

`values/somaz.yaml`

alertmanager:
  enabled: true
  config:
    global:
      resolve_timeout: 5m
  service:
    type: NodePort

grafana:
  enabled: false

## Component scraping the kubelet and kubelet-hosted cAdvisor
##
kubelet:
  enabled: true
  namespace: kube-system

## Component scraping the kube controller manager
##
kubeControllerManager:
  enabled: true

## Component scraping coreDns. Use either this or kubeDns
##
coreDns:
  enabled: true

## Component scraping kubeDns. Use either this or coreDns
##
kubeDns:
  enabled: false

## Component scraping kube scheduler
##
kubeScheduler:
  enabled: true

## Component scraping kube proxy
##
kubeProxy:
  enabled: true

kubeEtcd:
  enabled: true

## Component scraping kube state metrics
##
kubeStateMetrics:
  enabled: true

## Configuration for kube-state-metrics subchart
##
kube-state-metrics:
  namespaceOverride: ""
  rbac:
    create: true
  releaseLabel: true
  prometheus:
    monitor:
      enabled: true

## Deploy node exporter as a daemonset to all nodes
##
nodeExporter:
  enabled: true
  operatingSystems:
    linux:
      enabled: true
    darwin:
      enabled: true

  ## ForceDeployDashboard Create dashboard configmap even if nodeExporter deployment has been disabled
  ##
  forceDeployDashboards: false

## Manages Prometheus and Alertmanager components
##
prometheusOperator:
  enabled: true
  thanosImage:
    registry: quay.io
    repository: thanos/thanos
    tag: v0.36.1
    sha: ""

## Deploy a Prometheus instance
##
prometheus:
  enabled: true
  thanosService:
    enabled: true
  thanosServiceMonitor:
    enabled: true
  thanosServiceExternal:
    enabled: true
    type: NodePort
  ingress:
    enabled: true
    ingressClassName: nginx
    annotations:
      nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
      nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
    hosts:
      - prometheus.somaz.link
  serviceMonitor:
    disableCompaction: true
    selfMonitor: true
    replicas: 1
    shards: 1
    # resources:
    #   requests:
    #     cpu: 4
    #     memory: 10Gi
    #   limits:
    #     cpu: 4
    #     memory: 10Gi
  prometheusSpec:
    replicas: 1
    thanos:
      baseImage: quay.io/thanos/thanos
      version: v0.36.1
      objectStorageConfig:
        existingSecret:
          name: thanos-objstore
          key: objstore.yml
    storageSpec: 
      volumeClaimTemplate:
        spec:
          storageClassName: default
          accessModes: ["ReadWriteOnce"]
          resources:
            requests:
              storage: 100Gi
    externalLabels:
      provider: somaz
      region: seoul
      cluster: mgmt
      cluster_id: somaz-seoul-mgmt
    retention: 10d

 

 

설치 방법은 아래와 같다.

# lint 확인
helm lint --values ./values/somaz.yaml  

# 설치전 확인
helm install kube-prometheus-stack . -n monitoring -f ./values/somaz.yaml  --create-namespace --dry-run >> output.yaml

# 설치
helm install kube-prometheus-stack . -n monitoring -f ./values/somaz.yaml --create-namespace

# 업그레이드 방법
helm upgrade kube-prometheus-stack . -n monitoring -f ./values/somaz.yaml

# 주의할점 삭제하고 재설치 시
helm delete -n monitoring kube-prometheus-stack
helm delete -n monitoring prometheus-operator-crds

 

 

 

 

 


 

 

 

 

 

Thanos 설치

Thanos 설치 방법에 대해서 알아본다.

 

 

 

Thanos는 내부 Prometheus Thanos Discovery Sidecar에서 데이터를 가져오는 방법과, 외부 Cluster의 Prometheus Thanos Discovery Sidecar에서 데이터를 가져오는 방법, 그리고 통합하여 하나의 Thanos로 합쳐서 관리하는 방법에 대해서 알아본다.

 

 

 

 


 

 

 

 

 

 

 

내부 Prometheus 데이터 수집을 위한 Thanos 설치

git clone https://github.com/bitnami/charts.git

# 파일 복사 
sudo cp -r charts/bitnami/thanos .
cd ~/thanos

# helm repo 등록
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

# values 파일 복사
mkdir -p values
cp values.yaml ./values/somaz.yaml

# 의존성 설치
helm dependency update ~/thanos/

 

 

`values/somaz.yaml`

global:
  defaultStorageClass: "default"

fullnameOverride: "thanos" 
clusterDomain: somaz-cluster.local

existingObjstoreSecret: "thanos-objstore"

query:
  enabled: true
  logLevel: debug
  # resources:
  #   requests:
  #     cpu: 200m
  #     memory: 4Gi
  #   limits:
  #     cpu: 400m
  #     memory: 8Gi
  replicaLabel:
    - prometheus_replica
  dnsDiscovery:
    enabled: false
  stores:
    - dnssrv+_grpc._tcp.kube-prometheus-stack-thanos-discovery.monitoring.svc.somaz-cluster.local
  replicaCount: 1
  startupProbe:
    enabled: true
  ingress:
    enabled: true
    hostname: thanos-query.somaz.link
    ingressClassName: nginx
    pathType: ImplementationSpecific
    path: /
    grpc:
      enabled: false

queryFrontend:
  enabled: true
  # resources:
  #   requests:
  #     cpu: 100m
  #     memory: 1Gi
  #   limits:
  #     cpu: 200m
  #     memory: 2Gi
  rbac:
    create: true
  ingress:
    enabled: true
    hostname: thanos.somaz.link
    ingressClassName: nginx
    pathType: ImplementationSpecific
    path: /

bucketweb:
  enabled: false

compactor:
  enabled: true
  retentionResolutionRaw: 60d      # Retain raw data (10-second resolution) for 10 days
  retentionResolution5m: 60d       # Retain 5-minute downsampled data for 60 days
  retentionResolution1h: 1y        # Retain 1-hour downsampled data for 1 year
  consistencyDelay: 1h
  ingress:
    enabled: true
    hostname: thanos-compactor.somaz.link
    ingressClassName: nginx
    pathType: ImplementationSpecific
    path: /
  persistence:
    enabled: true
    storageClass: "default"
    accessModes:
      - ReadWriteOnce
    size: 10Gi

storegateway:
  enabled: true
  logLevel: warn
  # resources:
  #   requests:
  #     cpu: 400m
  #     memory: 3Gi
  #   limits:
  #     cpu: 800m
  #     memory: 6Gi
  persistence:
    enabled: true
    storageClass: "default"
    accessModes:
      - ReadWriteOnce
    size: 10Gi
  sharded:
    enabled: false
  pdb:
    create: true
    minAvailable: ""
    maxUnavailable: ""
  ingress:
    enabled: false

ruler:
  enabled: false

receive:
  enabled: false

receiveDistributor:
  enabled: false

metrics:
  enabled: true
  serviceMonitor:
    enabled: true
  prometheusRule:
    enabled: false

volumePermissions:
  enabled: false

minio:
  enabled: false

 

 

 

위의 `values/somaz.yaml` 파일에서 가장 중요한 부분은 아래와 같다.

  stores:
    - dnssrv+_grpc._tcp.kube-prometheus-stack-thanos-discovery.monitoring.svc.somaz-cluster.local

 

 

  • `dnssrv`
    • DNS SRV 레코드를 통해 서비스를 검색하겠다는 의미이다.
    • Thanos 구성에서 stores 필드에 이 방식을 사용하면, Thanos Query 컴포넌트가 자동으로 DNS를 조회하여 해당 서비스의 위치와 포트 정보를 얻는다.

 

  • `_grpc._tcp`
    • Thanos가 gRPC 프로토콜을 사용하여 통신한다는 것을 나타낸다.
    • `_grpc` 는 gRPC 서비스를, `_tcp` 는 TCP 프로토콜을 사용한다는 것을 의미한다.

 

  • `kube-prometheus-stack-thanos-discovery.monitoring.svc.somaz-cluster.local`
    • Kubernetes 내에서 서비스를 식별하는 FQDN(Fully Qualified Domain Name)이다.
      • `kube-prometheus-stack-thanos-discovery`: Thanos Discovery 서비스의 이름이다.
      • `monitoring`: 서비스가 속해 있는 네임스페이스이다.
      • `svc`: 이는 Kubernetes Service 객체를 나타낸다.
      • `somaz-cluster.local`: 클러스터의 도메인 이름을 나타낸다.

 

 

설치방법은 아래와 같다.

# lint 확인
helm lint --values ./values/somaz.yaml  

# 설치 전 확인
helm install thanos . -n monitoring -f ./values/somaz.yaml --create-namespace --dry-run >> output.yaml

# 설치
helm install thanos . -n monitoring -f ./values/somaz.yaml --create-namespace

# 업그레이드 방법
helm upgrade thanos . -n monitoring -f ./values/somaz.yaml
  • 설치후에 Thanos Frontend Web에 접속해서 Endpoint 부분을 확인하면 등록이 잘되었는지 알 수 있다.

 

만약 데이터 수집할때 에러가 발생한다면, 아래와같이 디버깅을 해보면 된다.

kubectl run -it --rm --image=nicolaka/netshoot dns-test --restart=Never -- /bin/sh

dig _grpc._tcp.kube-prometheus-stack-thanos-discovery.monitoring.svc.somaz-cluster.local

 

 

 

`dig` 로확인했을때 A 레코드에는 `endpoint ip` 가 나와야 정상이다.

k get ep -n monitoring |grep thanos-discovery

 

 

 

 


 

 

 

 

 

외부 Prometheus 데이터 수집을 위한 Thanos 설치

Chart는 위에서 사용한 것과 동일한 것을 사용한다.

따라서 파일을 복사해서 사용해준다. 그리고 외부 Cluster에는 Prometheus까지는 설치된 상태여야 한다.

# externalcluster 용 yaml 파일 생성
cp values/somaz.yaml values/somaz-externalcluster.yaml

# multicluster 용 yaml 파일 생성
cp values/somaz.yaml values/somaz-multicluster.yaml

 

 

그리고 externalcluster용 thanos는 외부 Cluster에 설치해준다. multicluster용 thanos는 첫번째 설치했던 thanos와 같은 Cluster에 설치해준다.

 

 

`values/somaz-externalcluster.yaml`

global:
  defaultStorageClass: "default"

fullnameOverride: "thanos" 
clusterDomain: external-cluster.local

existingObjstoreSecret: "thanos-objstore"

query:
  enabled: true
  logLevel: debug
  # resources:
  #   requests:
  #     cpu: 200m
  #     memory: 4Gi
  #   limits:
  #     cpu: 400m
  #     memory: 8Gi
  replicaLabel:
    - prometheus_replica
  dnsDiscovery:
    enabled: false
  stores:
    - dnssrv+_grpc._tcp.kube-prometheus-stack-thanos-discovery.monitoring.svc.external-cluster.local
  replicaCount: 1
  startupProbe:
    enabled: true
  ingress:
    grpc:
      enabled: true
      hostname: external-cluster-thanos-query.somaz.link
      ingressClassName: "nginx"
      annotations:
        nginx.ingress.kubernetes.io/ssl-redirect: "true"
        nginx.ingress.kubernetes.io/backend-protocol: "GRPC"

queryFrontend:
  enabled: false

bucketweb:
  enabled: false

compactor:
  enabled: false

storegateway:
  enabled: false

ruler:
  enabled: false

receive:
  enabled: false

receiveDistributor:
  enabled: false

metrics:
  enabled: false

volumePermissions:
  enabled: false

minio:
  enabled: false

 

 

`values/somaz-multicluster.yaml`

global:
  defaultStorageClass: "default"

fullnameOverride: "thanos-multicluster" 
clusterDomain: somaz-cluster.local

existingObjstoreSecret: "thanos-objstore"

query:
  enabled: true
  logLevel: debug
  # resources:
  #   requests:
  #     cpu: 200m
  #     memory: 4Gi
  #   limits:
  #     cpu: 400m
  #     memory: 8Gi
  replicaLabel:
    - prometheus_replica
  dnsDiscovery:
    enabled: false
  stores:
    - external-cluster-thanos-query.somaz.link:443
  extraFlags:
    - "--grpc-client-tls-secure"
  replicaCount: 0
  startupProbe:
    enabled: true
  ingress:
    enabled: false

queryFrontend:
  enabled: false

bucketweb:
  enabled: false

compactor:
  enabled: false

storegateway:
  enabled: false

ruler:
  enabled: false

receive:
  enabled: false

receiveDistributor:
  enabled: false

metrics:
  enabled: false

volumePermissions:
  enabled: false

minio:
  enabled: false

 

 

설치 완료후에 다시 한번더 `values/somaz.yaml` 파일을 수정한다.

stores 밑에 multicluster-thanos-query도 수집하게 추가해준다.

global:
  defaultStorageClass: "default"

fullnameOverride: "thanos" 
clusterDomain: somaz-cluster.local

existingObjstoreSecret: "thanos-objstore"

query:
  enabled: true
  logLevel: debug
  # resources:
  #   requests:
  #     cpu: 200m
  #     memory: 4Gi
  #   limits:
  #     cpu: 400m
  #     memory: 8Gi
  replicaLabel:
    - prometheus_replica
  dnsDiscovery:
    enabled: false
  stores:
    - dnssrv+_grpc._tcp.kube-prometheus-stack-thanos-discovery.monitoring.svc.somaz-cluster.local
    - dnssrv+_grpc._tcp.thanos-multicluster-query-grpc.monitoring.svc.somaz-cluster.local # 추가
  replicaCount: 1
  startupProbe:
    enabled: true
  ingress:
    enabled: true
    hostname: thanos-query.somaz.link
    ingressClassName: nginx
    pathType: ImplementationSpecific
    path: /
    grpc:
      enabled: false
...

 

 

 

Thanos Query Frontend 로 접속해 EndPoints를 확인하면 정상적으로 가져오고 있는걸 알 수 있다.

`Announced LabelSet` 에는 Prometheus에서 설정한 `externalLabelsets` 의 값도 같이 가져오게 된다.

 

 

 

 

 


 

 

 

 

 

Prometheus & Thanos 운영 시 실무 팁

 

Prometheus 보존 기간 전략

  • Prometheus 자체 보존기간은 짧게 (15일~30일 권장)
  • 장기 데이터는 반드시 Thanos Object Storage로 이관
  • retention 설정은 아래처럼:
prometheus:
  prometheusSpec:
    retention: 15d
 
 
 
 

Retention vs Storage Spec

  • Prometheus 보존 기간과 PVC 크기를 같이 고민해야 함
  • 저장 주기, scrape 간격, 타겟 수에 따라 실제 데이터 용량 계산 필수
  • 예) 100개 타겟, 15일 보존, 15s scrape 기준 → 약 100~150GB 예상

 

 

 

Multi Cluster 구성 시 External Labels 통일

  • 각 클러스터 Prometheus에 external_labels 필수로 설정 (아래 예시 참고)
prometheus:
  prometheusSpec:
    externalLabels:
      cluster: seoul-dev
      environment: dev
 
 

 

Thanos Compactor 주기적 점검 필수

  • Compactor는 데이터 압축 및 downsampling 담당
  • 이게 제대로 안되면 Object Storage 비용 폭증
  • 로그 점검과 주기적인 compactor 메트릭 모니터링 필요

 

 

 

Thanos Querier Query Performance

  • PromQL 쿼리가 느릴 때는 Querier 로그 확인
  • 특히 대규모 데이터 요청 시 Store Gateway와 Querier 간 네트워크 부하 점검
  • Query Frontend 캐싱 적극 활용 권장

 

 

 

 

구성 참고 예시

구성 추천 툴설명
메트릭 수집 Prometheus Kubernetes 기본 모니터링 도구
장기 보존 Thanos Object Storage로 아카이빙
대시보드 Grafana Prometheus + Thanos 데이터 시각화
알림 Alertmanager Slack, Email 연동
Log 수집 Loki Promtail로 각 노드 로그 수집
Event 수집 Node Problem Detector 노드 이벤트도 수집 가능

 

 

 

Prometheus & Thanos 트러블슈팅 사례

증상 원인 해결 방법
Prometheus Out of Memory 타겟 수 과다, 스크랩 주기 너무 짧음 타겟 조정, scrape_interval 늘리기
Querier Timeout Store Gateway 응답 지연 Querier - Store Gateway 네트워크 점검, Object Storage 성능 확인
Compactor 실패 Object Storage 권한 문제 Service Account 재확인 및 IAM 설정
데이터 누락 Sidecar 설정 누락 Prometheus Spec 확인 및 Sidecar 로그 점검

 

 

 

 

Prometheus & Thanos vs 다른 솔루션 비교

솔루션 특징 장점 단점
Prometheus+Thanos CNCF 표준, 에코시스템 풍부 Kubernetes 친화적, 확장성 구성 복잡, 스토리지 비용 증가
Mimir Grafana Labs 솔루션 대규모 데이터 처리 특화 Prometheus 호환성 100% 아님
VictoriaMetrics 단일 바이너리, 성능 특화 메모리 효율 좋음 커뮤니티 작음
OpenTelemetry + ClickHouse 차세대 표준 Trace + Metric 통합 구성 난이도 높음

 

 

 

 

최신 업데이트 및 꿀팁

 

 

Prometheus Agent 모드 활용 (remote_write 전용 경량 수집기)

  • Prometheus 2.32부터 제공
  • local storage 없이 `remote_write` 만 수행
  • Sidecar 없이 Thanos Receive로 바로 전송 가능
  • 리소스 절감 효과

 

 

Grafana Mimir 연계도 고려

  • Thanos 대신 Mimir로 장기 보관 구성도 증가 추세
  • 특히 수천개 타겟을 모니터링하는 환경에서는 Mimir가 훨씬 유리
  • 참고: https://grafana.com/docs/mimir/latest/

 

 

 

 

 


 

 

 

 

 

 

이번 포스팅에서는 Prometheus와 Thanos 설치 및 구성 방법을 상세히 살펴보았다.

 

단기 모니터링과 장기 데이터 보관을 함께 만족시키는 현대적인 Observability 아키텍처로 Prometheus + Thanos는 강력한 조합이다.

 

하지만 구성 난이도와 운영 부담도 함께 커지는 만큼,

  • 필요 없는 메트릭 수집 줄이기
  • 알림 폭풍 방지
  • 저장소 비용 절감 전략

 

같은 현실적인 운영 최적화도 반드시 고민해야 한다.

 

 

다음시간에는 Loki + Promtail + Node Feature Discovery 를 구성해보려고 한다. 그리고 Grafana도 구성해서 Metric data와 Log Data를 시각화까지 해볼 예정이다.

 

 

 

 


Reference

https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack

https://github.com/prometheus-community/helm-charts/tree/main/charts/prometheus

https://thanos.io/v0.8/thanos/storage.md/

https://github.com/rancher/local-path-provisioner/tree/master

https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner

https://github.com/bitnami/charts/tree/main/bitnami/thanos

https://particule.io/en/blog/thanos-monitoring/

728x90
반응형

'Monitoring' 카테고리의 다른 글

ELK Stack 구축해보기  (2) 2025.01.27
Loki와 Promtail 설치  (5) 2024.10.02
Loki란?  (4) 2024.09.26
Prometheus와 Thanos란?  (4) 2024.09.12
Fluent Bit (With Loki)  (4) 2024.03.08