Tech story/Container

OpenTelemetry를 활용한 K8S Metric, Log, Trace 데이터 통합 수집기

kt cloud 테크블로그 2024. 11. 4. 15:30

[kt cloud 서비스개발팀 정예은 님]

 

OpenTelemetry를 활용한 K8S Metric, Log, Trace 데이터 통합 수집기

 

최근 MSA 아키텍처, Cloud Native 애플리케이션, 컨테이너 환경을 활용한 운영이 일반화되며 시스템의 복잡도가 늘어났습니다. 이에 따라 시스템들들을 관리하기 위한 Observability의 중요성 또한 대두되고 있습니다.

 

Obeservability란, 추적(trace), 메트릭(metrics), 로그(logs)라는 세 가지 요소를 모두 포괄하는 개념입니다. 이 세 종류의 데이터를 시각화하고, 이를 적재적소에 활용하여 서비스 장애에 보다 더 빠르게 대응하고 스케일링 시기를 예측하는 등 서비스 운영에서의 편리함을 도모할 수 있습니다.

 

kt cloud에서도 observability를 위한 서비스를 제공하고 있는데요, 쿠버네티스 클러스터 관리 서비스인 K2P Standard(K8S)APM 기능입니다.

 

APM에서는 쿠버네티스 클러스터 및 Pod, Service, Deployment 등의 리소스를 관찰하는 기능을 제공하는데요, 로그 및 메트릭 수집을 위해 Fluent-Bit를, 추적 수집을 위해서는 OpenTelemetry를 사용하고 있습니다.

 

그런데 고객들에게 수집기가 너무 많아요! 라는 불만이 종종 들려왔습니다.

 

수집기가 고작 두 대인데?라고 할 수 있지만, 이 또한 운영 포인트 중 하나이기에, 리소스를 절약하고 일관성 있는 데이터 관리를 위해 하나의 통합된 수집기로 전환하고자 하는 니즈가 발생하게 되는 것입니다.

 

이러한 문제를 해결하기 위해 OpenTelemetry 단 하나만으로 세 가지를 모두 수집해 보고자 하였습니다.

 

OpenTelemetry는 애플리케이션의 Observability를 강화하기 위한 오픈소스 프레임워크이며, 분산 시스템의 성능을 모니터링하고 디버깅하는 데 필요한 추적, 메트릭, 로그 데이터를 수집, 처리, 내보낼 수 있는 도구와 API를 제공합니다.

 

OpenTelemetry를 통해 어떻게 추적, 메트릭, 로그를 통합 수집하도록 설정하였는지에 대해 알아보도록 하겠습니다.

 

 

1. OpenTelemetry의 구성 요소

 

우선 설정 전에, OpenTelemetry의 구성 요소에 대해 살펴봅시다.

 

  • Receiver
    • 네트워크 포트로부터 데이터를 수집하는 역할
    • 일반적으로 1개의 파이프라인에 1개의 receiver를 설정
  • Processor
    • Receiver로부터 데이터를 전달받아서 데이터를 가공 후, Exporter로 전달하는 역할
    • pipeline 형태로 연속적으로 설정 가능
    • EX) 특정 데이터는 필터링하여 전달하지 않거나, 새 데이터를 추가 생성한다.
  • Exporter
    • destination으로 최종 데이터를 전달하는 역할

위 내용을 토대로 아래 설정 파일 예시를 살펴봅시다.

extensions:
  basicauth/client:
    client_auth:
      username: {{username}}
      password: {{password}}

receivers:
  otlp:
    protocols:
      http:
        endpoint: {{otlp endpoint}}

processors:
  batch:

exporters:
  debug:
    verbosity: detailed

  otlp/trace:
    endpoint: {{trace endpoint}}
    tls:
      insecure: true

  otlp/logs:
    endpoint: {{logs endpoint}}
    tls:
      insecure: true

  otlp/metrics:
    endpoint: {{metrics endpoint}}
    tls:
      insecure: true

service:

  pipelines:

    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlp/trace]

    metrics:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlp/metrics]

    logs:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlp/logs]

  extensions: [basicauth/client]

 

1. Extensions

- basicauth/client: 기본 인증 확장으로, client_auth 옵션을 통해 외부 서버에 인증할 때 사용할 사용자 이름과 비밀번호를 설정합니다.

extensions:
  basicauth/client:
    client_auth:
      username: {{username}}
      password: {{password}}

 

2. Receivers

- otlp: OTLP 프로토콜을 사용하는 수신기(receiver)로, HTTP 프로토콜을 통해 {{otlp endpoint}}에서 데이터를 받아옵니다.

receivers:
  otlp:
    protocols:
      http:
        endpoint: {{otlp endpoint}}

3/ Processors

- batch: 데이터를 일정 배치로 묶어 전송하는 프로세서로, 데이터 전송 효율을 높여줍니다.

 
processors:
  batch:

 

4. Exporters

- debug: 디버그 출력 설정으로, 데이터를 Collector 로그에 상세하게 출력합니다.

- otlp/trace, otlp/logs, otlp/metrics: OTLP로 데이터를 내보내기 위한 각기 다른 exporter 설정입니다. 각각의 엔드포인트   (trace, logs, metrics)에 데이터를 전송하며, insecure: true로 설정하여 TLS 인증을 사용하지 않습니다.

 
exporters:
  debug:
    verbosity: detailed
  otlp/trace:
    endpoint: {{trace endpoint}}
    tls:
      insecure: true
  otlp/logs:
    endpoint: {{logs endpoint}}
    tls:
      insecure: true
  otlp/metrics:
    endpoint: {{metrics endpoint}}
    tls:
      insecure: true

 

5. Service

- pipelines: 데이터 처리 파이프라인을 정의하며, traces, metrics, logs 데이터 유형별로 각 파이프라인을 설정합니다. 각 파이프라인은 동일한 otlp receiver, batch processor, 그리고 각기 다른 otlp exporter를 사용합니다.

- extensions: basicauth/client를 확장으로 추가하여 인증 설정을 적용합니다.

 
service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlp/trace]
    metrics:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlp/metrics]
    logs:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlp/logs]
  extensions: [basicauth/client]

 

필요한 receiver, processer, exporter 그리고 extension을 가져다가 기재만 하면 되는 형식이므로, 크게 복잡하지 않게 OpenTelemetry를 원하는 대로 구성할 수 있습니다!

 

 

2. OpenTelemetry의 종류

 

OpenTelemetry에는 크게 두 종류가 있습니다.

  • OpenTelemetry Collector: 기본적인 Observability 데이터를 수집, 처리 및 내보내기 위한 코어 구성 요소를 포함하는 콜렉터
  • Opentelemetry Contrib collector: 기본 OpenTelemetry Collector 기능에 더해 추가적으로 다양한 receiver, processor, exporter 기능이 포함된 확장 버전

OpenTelemetry Collector에서 지원하는 기능에 한계가 있기 때문에, OpenTelemetry Contrib Collector를 범용적으로 사용합니다.

아래 OpenTelemetry Github에 접속해보면, 지원 가능한 receiver 및 processer 목록을 확인할 수 있습니다.

GitHub - open-telemetry/opentelemetry-collector-contrib: Contrib repository for the OpenTelemetry Collector

저 또한 OpenTelemetry Contrib Collector에서만 지원하는 쿠버네티스와 관련된 receiver 및 processor를 사용하기 위해 OpenTelemetry Contrib Collector를 활용하였습니다.

 

 

3. OpenTelemetry를 통한 K8S Clouster 데이터 수집

 

이제 본격적으로 실전에 적용해보도록 하겠습니다!

제가 OpenTelemetry를 통해 수집하고자 한 주요 데이터는 쿠버네티스 리소스와 관련된 정보였습니다.

쿠버네티스 노드 데이터 수집을 위한 OpenTelemetry 설정

exporters:
  debug: {}
  logging:
  otlp/logs:
    endpoint: data-prepper-headless.opensearch.svc:21892
  otlp/metrics:
    endpoint: data-prepper-headless.opensearch.svc:21891
  otlp/data-prepper:
    endpoint: data-prepper-headless.opensearch.svc:21890
      
extensions:
  file_storage:
    directory: /var/lib/otelcol
  health_check:
    endpoint: ${env:K8S_POD_IP}:13133
    
processors:
  batch: {}
  k8sattributes:
### 설정 추가
  resourcedetection:
    ### 설정 추가
  memory_limiter:
    ### 설정 추가
    
receivers:
  filelog:
    exclude: []
    include:
      - /var/log/pods/*/*/*.log
    ### 설정 추가
  hostmetrics:
    ### 설정 추가
  otlp:
    protocols:
      grpc:
        endpoint: ${env:K8S_POD_IP}:4317
      http:
        endpoint: ${env:K8S_POD_IP}:4318
  kubeletstats:
    ### 설정 추가
service:
  extensions:
    - health_check
    - file_storage
  pipelines:
    logs:
      exporters:
        - debug
        - otlp/logs
      processors:
        - memory_limiter
        - batch
        - k8sattributes
      receivers:
        - otlp
        - filelog
    metrics:
      exporters:
        - debug
        - otlp/metrics
      processors:
        - memory_limiter
        - batch
        - resourcedetection
        - k8sattributes
      receivers:
        - otlp
        - hostmetrics
        - kubeletstats
    traces:
      exporters:
        - debug
        - logging
        - otlp/data-prepper
      processors:
        - memory_limiter
        - batch
        - k8sattributes
      receivers:
        - otlp

 

  • Exporters
    • Logs, Metrics, Traces 데이터를 각각 data-prepper-headless.opensearch.svc로 내보내, 지정된 포트를 사용하여 Data Prepper 서비스에 전송
  • Extensions
    • file_storage: 임시 데이터를 /var/lib/otelcol 디렉토리에 저장
    • health_check: Collector의 헬스 체크 지원
  • Processors
    • batch: 데이터를 일정 배치로 묶어 전송하는 프로세서
    • k8sattributes: Kubernetes 메타데이터를 수집된 데이터에 추가
    • resourcedetection: 환경과 시스템 정보를 감지하고 데이터 태깅
    • memory_limiter: 메모리 사용량을 모니터링하고 제한하며, 제한 비율과 스파이크 비율을 설정하여 과부하 방지
  • Receivers
    • filelog: Pod 단위로 생성되는 컨테이너 및 애플리케이션 로그 수집
    • hostmetrics: Collector가 배포된 노드의 Metric 데이터 수집
    • otlp: 애플리케이션에서 직접 Collector로 전송하기 위한 receiver로, gRPC 및 HTTP 지원
    • kubeletstats: Kubernetes kubelet을 통해 클러스터 내에서 노드에 할당된 pod와 컨테이너의 리소스 사용량 메트릭 수집

위 구성을 통해 쿠버네티스 호스트와 Pod, 애플리케이션 로그 및 메트릭 데이터를 모두 수집할 수 있도록 설계되었으며, 이를 통해 클러스터 전체의 상태를 종합적으로 파악할 수 있게 됩니다.

 

 

마무리

 

OpenTelemetry 단 하나의 수집기만으로 쿠버네티스 자원의 로그, 메트릭, 추적을 관측하도록 설정해 보았습니다.

각자의 필요에 따라 OpenTelemetry receiver, processor, exporter를 추가하여 멋진 OpenTelemetry pipeline을 구성해 보시기 바랍니다.

 

 

기타/참고