반응형
은세고화
뚜렷한 기억보단 흐릿한 잉크를
은세고화
전체 방문자
오늘
어제
  • 분류 전체보기 (99)
    • TDD (2)
      • 학점 산출 프로그램 (2)
    • IT (1)
      • 부스트코스 (18)
      • CS50 (3)
      • 도서추천 알고리즘 (2)
      • 스터디 일정 (3)
      • 스프링 (4)
      • 프로젝트 개발 중 발생한 에러 (8)
      • 웹개발 (5)
      • DB (3)
    • 독서 후기 (12)
      • 도서 (12)
    • e북 (3)
    • 알고리즘 (26)
    • 프로젝트 (6)
      • 향수 (6)
    • 회고 (1)

블로그 메뉴

  • 홈

공지사항

인기 글

티스토리

hELLO · Designed By 정상우.
글쓰기 / 관리자
은세고화

뚜렷한 기억보단 흐릿한 잉크를

IT

[OpenSearch] OpenShift 환경에서 OpenTelemetry로 노드 모니터링 구축하기 (feat. Data Prepper)

2026. 1. 23. 15:18
반응형

오픈서치(OpenSearch)를 클라우드 관리형(AWS OpenSearch Service)이 아닌, **자체 설치(Self-hosted)**해서 사용할 경우 가장 난감한 부분이 바로 **'노드 모니터링'**입니다.

 

과거(3.x 이전)에는 Performance Analyzer(PA)와 RCA를 연동하여 모니터링을 구성했지만, 3.x 버전부터 아키텍처가 변경되면서 이 방식이 더 이상 권장되지 않거나 불가능해졌습니다.

 

Elastic Stack(ELK)의 경우 Kibana에서 간편하게 Stack Monitoring을 켤 수 있지만, OpenSearch Dashboards에는 그런 기본 기능이 없습니다... (ㅠㅠ)

 

현재 OpenSearch 3.4 공식 문서 기준으로 추천하는 모니터링 아키텍처는 다음과 같습니다.

OpenTelemetry (수집) -> Data Prepper (가공) -> OpenSearch (저장/시각화)

 

지금부터 OpenShift (Kubernetes) 환경을 기준으로 이 세팅 과정을 하나씩 정리해 보겠습니다.


1. 아키텍처 및 개념 이해

우선 오픈서치 노드의 메트릭 데이터를 외부로 가져와야 합니다. 이때 **OpenTelemetry(OTel)**가 핵심적인 역할을 합니다.

OpenTelemetry 수집 데이터 3요소

  1. 메트릭 (Metrics): 시스템 상태나 성능을 숫자로 표현한 시계열 데이터 (예: CPU 사용률, 메모리 사용량, JVM 힙).
  2. 로그 (Logs): 애플리케이션에서 발생하는 개별 이벤트 기록. 보통 메트릭으로 이상 징후를 파악한 뒤, 로그를 통해 원인을 분석합니다.
  3. 트레이스 (Traces): 하나의 요청(Transaction)이 분산 시스템을 통과하는 전체 경로를 기록. 병목 지점 파악에 필수적입니다.

수집 방식: Pull vs Push

오픈서치 노드 상태를 수집하는 데는 두 가지 방법이 있습니다.

  1. Pull (Scraping): OTel이 주기적으로 오픈서치에 접속해 데이터를 긁어가는 방식. (추천)
  2. Push: 오픈서치 설정(yml)을 수정하여, 오픈서치가 스스로 OTel에게 데이터를 쏘는 방식.

선택: Push 방식은 오픈서치 설정을 건드려야 하고 재시작 리스크가 있습니다. 반면 Pull 방식은 오픈서치 수정 없이 외부에서 접근만 하면 되므로 훨씬 안전합니다. 따라서 Pull 방식을 선택했습니다. (단, Trace 데이터 수집이 필요하다면 Push 방식 설정이 필요할 수 있습니다.)


2. OpenTelemetry Collector 세팅

OpenTelemetry는 표준 API와 SDK를 제공하지만, 이를 직접 구현하기보다 이미 잘 만들어진 완제품인 OpenTelemetry Collector를 사용하는 것이 효율적입니다.

특히, 기본 이미지보다는 다양한 플러그인이 포함된 contrib 이미지를 사용해야 OpenSearch(Elasticsearch) 리시버를 사용할 수 있습니다.

2-1. 배포 설정 (Deployment)

YAML

kind: Deployment
apiVersion: apps/v1
metadata:
  name: otel-collector
  namespace: [내-프로젝트-이름] # OpenShift 네임스페이스 기입
  labels:
    app: otel-collector
spec:
  replicas: 1
  selector:
    matchLabels:
      app: otel-collector
  template:
    metadata:
      labels:
        app: otel-collector
    spec:
      volumes:
        - name: otel-config-vol
          configMap:
            name: otel-collector-config
            defaultMode: 420
      containers:
        - name: otel-collector
          # 다양한 리시버 사용을 위해 contrib 이미지 사용 필수
          image: 'otel/opentelemetry-collector-contrib:0.143.0'
          args:
            - '--config=/conf/otel-collector-config.yaml'
          resources:
            limits:
              cpu: 500m
              memory: 500Mi
            requests:
              cpu: 100m
              memory: 200Mi
          volumeMounts:
            - name: otel-config-vol
              mountPath: /conf
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: IfNotPresent

2-2. ConfigMap 설정 (otel-collector-config.yaml)

OTel Collector가 오픈서치(Source)에서 데이터를 긁어서 Data Prepper(Destination)로 보내도록 설정합니다.

참고: OTel은 OpenSearch 전용 리시버가 별도로 없으므로, 호환되는 elasticsearch 리시버를 사용합니다.

YAML

apiVersion: v1
kind: ConfigMap
metadata:
  name: otel-collector-config
data:
  otel-collector-config.yaml: |
    receivers:
      elasticsearch:
        # [중요] OpenSearch 서비스 주소 (Headless 서비스 권장)
        endpoint: "https://opensearch-headless:9200"
        tls:
          # 사설 인증서(Self-signed) 사용 시 필수
          insecure_skip_verify: true

        username: "admin"
        password: "admin_password" # 실제 비밀번호 입력

        # 수집 주기 (너무 짧으면 부하 발생)
        collection_interval: 60s

    processors:
      batch:
        send_batch_size: 1000
        timeout: 5s

      # 불필요한 메트릭 제거 (용량 최적화)
      filter:
        error_mode: ignore
        metrics:
          exclude:
            match_type: strict
            metric_names:
              - elasticsearch.node.fs.io_stats.total_reads
              - elasticsearch.node.fs.io_stats.total_writes
              - elasticsearch.node.http.connections.opened
              - elasticsearch.node.http.connections.total
              - elasticsearch.node.transport.packets.received
              - elasticsearch.node.transport.packets.sent
              - elasticsearch.node.thread_pool.completed
              - elasticsearch.node.thread_pool.largest

    exporters:
      # 수집한 데이터를 Data Prepper로 전송
      otlp:
        endpoint: "data-prepper-service:21890" # Data Prepper OTLP 포트
        tls:
          insecure: true

    service:
      pipelines:
        metrics:
          receivers: [elasticsearch]
          processors: [filter, batch] # filter 프로세서 추가됨
          exporters: [otlp]

설정 포인트:

  1. collection_interval: 60s: 주기가 너무 짧으면 데이터 양이 폭증하여 스토리지 낭비가 심합니다. 1분 정도가 적당합니다.
  2. send_batch_size: 1000: 데이터를 한 번에 묶어서 보냅니다. 제한이 없으면 Data Prepper가 받아내지 못할 수 있습니다.
  3. metric_names (Filter): 모니터링 대시보드에서 보지 않을 세부적인 I/O나 스레드풀 정보는 과감히 제외하여 용량을 아낍니다.
  4. insecure: true: 내부 통신에 사설 인증서를 사용하는 경우 SSL 검증을 건너뛰어야 에러가 나지 않습니다.

수집되는 데이터 예시 -> 필자 기준 61개 칼럼이 수집된다.

elasticsearch.node.thread_pool.tasks.finished
elasticsearch.node.thread_pool.threads
elasticsearch.node.thread_pool.tasks.queued
elasticsearch.node.operations.completed
elasticsearch.node.operations.time
elasticsearch.breaker.tripped
elasticsearch.breaker.memory.limit
elasticsearch.breaker.memory.estimated
jvm.memory.pool.used
elasticsearch.memory.indexing_pressure
jvm.memory.pool.max
elasticsearch.node.cluster.io

 

3. Data Prepper 세팅

OTel Collector가 데이터를 수집했다면, 이를 받아 OpenSearch에 저장할 파이프라인이 필요합니다. 저같은 경우 Logstash로 로그 수집을 하고 있어서 이쪽으로 처리할 까 고민했지만

 

공식 가이드의 추천과

1. 추후 Otel을 활용해 Trace 데이터를 수집할 가능성

2. 로그스태시가 옵저빌리티 데이터까지 수집하면 비대함

3. Grok 패턴을 추가할 때 필요없는 옵저빌리티 로그로 인한 디버깅 어려움

 

이 세가지 이유로 DataPrepper를 세팅했습니다.

YAML

kind: Service
apiVersion: v1
metadata:
  name: data-prepper-service
  labels:
    app: data-prepper
spec:
  ipFamilies:
    - IPv4
  ports:
    - protocol: TCP
      port: 21890
      targetPort: 21890
  internalTrafficPolicy: Cluster
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: data-prepper
  labels:
    app: data-prepper
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: data-prepper
    spec:
      volumes:
        - name: config-volume
          configMap:
            name: dataprepper-config
            defaultMode: 420
      containers:
        - resources:
            limits:
              cpu: '1'
              memory: 2Gi
            requests:
              cpu: 500m
              memory: 2Gi
          terminationMessagePath: /dev/termination-log
          name: data-prepper
          env:
            - name: JAVA_OPTS
              value: '-Xms1g -Xmx1g'
          ports:
            - containerPort: 21890
              protocol: TCP
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - name: config-volume
              mountPath: /usr/share/data-prepper/pipelines/pipelines.yaml
              subPath: pipelines.yaml
          image: '이미지 주소'

3-3. 파이프라인 설정 (dataprepper-config.yaml)

Data Prepper의 핵심인 pipelines.yaml 설정입니다. **Source(OTLP)**로 받아서 **Sink(OpenSearch)**로 내보냅니다.

metrics-pipeline:
  source:
    otlp:
      ssl: false
      port: 21890 # OTel Collector와 통신할 포트
  buffer:
    bounded_blocking:
      buffer_size: 20000
      batch_size: 1000
  processor:
    - otel_metrics:

  sink:
    - opensearch:
        hosts: 주소
        username: "admin"
        password: "admin" # [필수수정] 실제 비밀번호

        # [중요] 템플릿 적용을 위해 custom 타입 사용
        index_type: "custom"
        #인증서 검사 X
        insecure: true

        # [변경] 템플릿의 index_patterns 와 일치하도록 이름 변경
        index: "ss4o_metrics-opensearch-%{yyyy.MM.dd}"

        # 컨테이너에 마운트될 템플릿 파일 경로 -> 주석처리하고 오류나면 추가한 뒤 아래 파일도 추가해야함.
        #template_file: "/usr/share/data-prepper/templates/ss4o_metrics.json"

 

- 최하단 template_file은 적용되지 않아서 주석처리했습니다.

- ss4o_metrics는 옵저빌리티 공식 인덱스 이름이기 때문에 지켜주는게 추후 호환에 더 좋습니다.

 

 

결론

위와 같이 설정했다면 ss4o_metrics로 데이터가 들어올 것입니다.

 

다만 이제 가장 중요한 대시보드를 세팅해야합니다. 본인이 필요한 지표로 대시보드를 세팅할 수 있다면 혼자하면되고 모르겠다면 다음편에 대시보드 세팅방법을 게시하겠습니다.

반응형
저작자표시 (새창열림)
    은세고화
    은세고화

    티스토리툴바