Search
Duplicate
☀️

OpenTelemetry Collector로 Prometheus (scraper) 교체하기

Category
S/W 엔지니어
Tags
OpenTelemetry
OTel
OpenTelemetry Collector
Prometheus
Created time
2024/04/07

Introduction

OTel(OpenTelemetry) Collector로 Prometheus (scraper - agent mode)를 교체하는 방법에 대한 설명이다. OpenTelemetry의 사용자 관점 OverviewOpenTelemetry 설치 준비: OTel k8s Operator 설치 의 연장선 상에 위치한 OpenTelemetry Collector의 상세 검토 중 하나이다.

Summary

OTel Collector로 Kubernetes resource metric 스크래핑을 위한 Prometheus를 대체 가능하다.
다수의 scraping 대상으로 인한 특정 pod로의 부하 쏠림을 해결하기 위해 Target Allocator가 제공된다.
Prometheus로 직접 전달(push)하는 방식과 Prometheus와 동일하게 pull 방식 모두 가능하다.

Architecture

OpenTelemetry Collector 및 Target Allocator의 Kubernetes Metric scrapping 구조
위 는느penTelemetry Collector로 Prometheus (scraper)를 교체했을 때의 아키텍처를 나타낸다.
좌측 노란 박스는 scraping 대상 Kubernetes resources를, 푸른 박스는 OpenTelemetry components로 OpenTelemetry Collector와 Target Allocator를, 붉은 박스는 metric 저장소로서의 Prometheus 및 scraper(오직 OpenTelemetry Collector에서만 scrap)로서의 Prometheus를 나타낸다. 실선은 데이터의 흐름을, 점선은 관계를 나타낸다
각 components에 대한 설명은 아래부터 이어진다.

Components

Prometheus Receiver

Prometheus format의 metric을 수집하는 OTel receiver이다.
stateful 동작으로 인하여 Collector는 statefulset 배포 방식이 요구된다. 이로 인해 발생 가능한 데이터 중복 및 부하 분산 등의 문제를 해결하기 위해 OTel Operator는 Target Allocator를 함께 제공한다. 이에 대해서는 Target Allocator 에서 자세히 다룬다.
Prometheus (scraper)와 동일한 동작을 위해, Prometheus (scraper) 설정된 scraping config를 config.scrape_configs 에 동일하게 설정한다. 에서는 Prometheus helm chart의 default scraping config를 그대로 가져왔다.
config.scrap_configs 설정 시 Prometheus scrap_config 에서 replacement key인 $$$ 으로 변경해야 한다. 이렇게 하지 하지 않으면, 아래와 같은 오류 발생한다. 해결안 출처: (’…The usage of $$ in the replacement keys in the example above is based on …’)
오류 로그 예

memory_limiter, batch Processors

memory_limiter 는 메모리 과다 사용 사전 방지용이고 batch 효율적 data 처리를 위해 수집된 metric을 모아서 처리 가능하게 한다. 이에 대해서는 별도의 글에서 다시 다룬다.

Exporters

Prometheus로 데이터를 보내기 위한 방법에는 기존과 동일하게 Prometheus에서 scrap하는 pull 방식과 Collector가 직접 Prometheus로 전달하는 push 방식이 있다. prometheus는 pull 방식에서, prometheusremotewrite push 방식에서 사용한다. 이외에 debug exporter가 있는데 이는 디버깅 용으로 stderr로 데이터를 보내며 이에 대해 역시 별도의 글에서 다룬다.

prometheus Exporter

Prometheus (scraper)가 Prometheus format의 data를 scrap할 수 있도록 노출한다. 에서는 endpoint 설정 이외에 특별한 것은 없다. 이 exporter를 사용할 경우 Prometheus (scraper)를 그대로 사용하게 되는데, 해당 Prometheus에 아래와 같이 설정함으로 오직 이 Collector에서만 scrap하도록 한다.
... - job_name: otel-prometheus-collector # only collect metrics from otel-collector static_configs: - targets: - otel-prometheus-collector.cluster.svc.cluster.local.:9090 ...
YAML
복사

Prometheus Remote Write Exporter

Prometheus (scraper) 없이 직접 Prometheus에 전달(push)할 때 사용한다. 근데 Non-cumulative monotonic, histogram, summary 타입의 OTLP metric은 export 못한다고. 그럼에도 아래 Grafana의 글은 부하 분산 및 스파이크 방지의 이유로 이 방식을 추천하는데, 처리 데이터 범위가 좁혀진다는 점을 고려한다면 크게 와닺지 않는다.
참고로, --web.enable-remote-write-receiver feature flag와 함께 Prometheus를 실행해야 Prometheus가 데이터를 받을 수 있다. 해당 endpoint는 /api/v1/write 이다.

Target Allocator

targetAllocator.enabled: true 설정 시 collector와 함께 자동 생성된다.
scrap 대상이 많아지면 Collector pod도 scaling하게 되는데, Prometheus Receiver의 stateful 속성으로 인해 scrap 대상이 상시 고정되는데 이는 특정 pod에 부하가 몰릴 가능성이 높아진다는 뜻이다. Target Allocator는 이를 완화시키기 위한 별도의 deployment으로, scrap target discovery와 이를 처리할 Collector를 할당한다. 이외에 Prometheus CR(Custom Resource) discovery 기능도 갖는다고.
아래는 Target Allocator 기반의 Collector 처리 순서를 나타낸다.
sequenceDiagram
  participant Target Allocator
  participant Metrics Targets
  participant OTel Collectors
  Target Allocator ->>Metrics Targets: 1. Discover Metrics targets
  Target Allocator ->>OTel Collectors: 2. Discover available Collectors
  Target Allocator ->>Target Allocator: 3. Assign Metrics targets
  OTel Collectors ->>Target Allocator: 4. Query TA for Metrics endpoints scrape
  OTel Collectors ->>Metrics Targets: 5. Scrape Metrics target
Mermaid
복사

설치 방법

에 대해 kubectl apply 를 실행한다. 앞서 설명한 내용를 적용하고자 할 경우 환경에 관계 없이 별도 수정없이도 동작할 것이라 예상한다. 다만, prometheus exporter를 사용하도록 prometheusremotewrite 에 대해서는 주석화되어 있는데, prometheusremotewrite 를 사용할 경우 적당히 연결할 prometheus endpoint로 수정해야 한다.

Appendix: 동적 scrap 대상 지정용 prometheus.io annotation 목록

metadata: annotations: prometheus.io/scrape: true # Only scrape services that have a value of `true``true`, except if `prometheus.io/scrape-slow` is set to `true` as well. prometheus.io/scrape-slow: false prometheus.io/path: /prometheus # If the metrics path is not `/metrics` override this. prometheus.io/port: 15020 # If the metrics are exposed on a different port to the service then set this appropriately prometheus.io/scheme`: # If the metrics endpoint is secured then you will need to set this to `https` & most likely set the `tls_config` of the scrape config. prometheus.io/param_<parameter>`: # If the metrics endpoint uses parameters then you can set any parameter prometheus.io/probe`: # Only probe services that have a value of `true`
YAML
복사
prometheus.io Kubernetes annotation이란
Prometheus에게 metric 수집 대상임을 알리는 방법으로 예컨데 아래는 Istio sidecar annotation의 예이다.
metadata: annotations: prometheus.io/scrape: 'true' # scrap 대상임을 알림 prometheus.io/path: /stats/prometheus # scrap에 사용되는 endpoint path prometheus.io/port: '15020' # scrap에 사용되는 endpoint의 port
YAML
복사

Appendix: 전체 코드

앞서 설명한 내용이 담긴 OpenTelemetry Collector에 대한 manifest 뿐 아니라, 인가, 인증을 위한 Kubernetes ClusterRole, ClusterRoleBinding에 대한 manifest도 함께한다. Service Account는 Operator가 자동으로 생성하기에 이에 대한 manifest는 없다. 또한, Target Allocator는 targetAllocator.enabled 설정으로 자동 생성된다.
전체 코드