본문 바로가기
Infra, Cloud/Kubernetes

Jaeger Operator를 구축하여 Trace 시각화하기, OpenTelemetry 연동 가이드

by J4J 2025. 11. 4.
300x250
반응형

안녕하세요. J4J입니다.

 

이번 포스팅은 jaeger operator를 구축하여 trace 시각화하는 방법에 대해 적어보는 시간을 가져보려고 합니다.

 

 

 

관련 글

 

OpenTelemetry 구축 가이드: OTel Collector를 이용하여 메트릭, 로그, 트레이스를 하나로

 

OpenTelemetry 구축 가이드: OTel Collector를 이용하여 메트릭, 로그, 트레이스를 하나로

안녕하세요. J4J입니다. 이번 포스팅은 open telemetry 구축 가이드, otel collector를 이용하여 메트릭, 로그, 트레이스를 통합 관리하는 방법에 대해 적어보는 시간을 가져보려고 합니다. 관련 글 Kubernet

jforj.tistory.com

 

Kubernetes Service Mesh 구축 가이드: Istio에 대한 이해와 Istio Operator 설치 방법

 

Kubernetes Service Mesh 구축 가이드: Istio에 대한 이해와 Istio Operator 설치 방법

안녕하세요. J4J입니다. 이번 포스팅은 kubernetes service mesh 구축을 위한 istio에 대한 이해와 istio operator 설치하는 방법에 대해 적어보는 시간을 가져보려고 합니다. Service Mesh kubernetes 환경에서 마이

jforj.tistory.com

 

Micrometer Tracing으로 Spring 애플리케이션 분산 트레이싱하기

 

Micrometer Tracing으로 Spring 애플리케이션 분산 트레이싱하기

안녕하세요. J4J입니다. 이번 포스팅은 micrometer tracing으로 spring 애플리케이션 분산 트레이싱하는 방법에 대해 적어보는 시간을 가져보려고 합니다. 관련 글 애플리케이션 모니터링을 위한 Spring B

jforj.tistory.com

 

Helm 이란? Helm 입문을 위한 기본 개념 설명

 

Helm 이란? Helm 입문을 위한 기본 개념 설명

안녕하세요. J4J입니다. 이번 포스팅은 helm 입문을 위한 기본 개념 설명하는 시간을 가져보려고 합니다. Helm 이란? helm이라고 하는 것은 kubernetes를 사용하는 환경에서 kubernetes cluster가 관리하는 영

jforj.tistory.com

 

 

반응형

 

 

Jaeger

 

jaeger는 분산 추적 관측 플랫폼으로 한 번의 사용자 요청이 서로 다른 서비스 등을 거치게 되는 MSA와 같은 환경에서 trace 정보를 기반으로 추적을 할 수 있도록 도와주는 오픈소스입니다.

 

MSA 기반의 서비스 구축을 하고 있다면 쉽게 공감할 수 있는 부분 중 하나가 사용자의 요청에 장애가 발생했을 때 어떤 곳에서 문제가 되는 것인지 확인하기가 어렵다는 것입니다.

 

관련 글에 담겨 있는 이전 글들을 보신 분들은 아시겠지만

 

1. 요청에 대한 추적을 위해 istio를 이용한 서비스 메시 설정이 이루어지고

 

2. otel collector에 의해 telemetry 정보가 수집되며

 

3. application에서부터 w3c 기반의 traceparent 정보가 전달되는

 

 

환경들을 구축하였고, 이런 설정들을 통해 수집된 trace 정보들이 최종적으로 jeager에 전달되면서 관리자 및 개발자의 레벨에서 요청에 대한 장애 추적을 쉽게 확인할 수 있는 구조를 만들어 볼 수 있습니다.

 

 

 

이 외에도 jaeger를 사용하면 다음과 같은 이점들을 얻을 수 있습니다.

 

  • 사용자의 요청이 처리된 서비스들의 흐름을 시간 순서대로 확인 가능
  • 비즈니스 처리의 병목 지점들을 확인할 수 있음
  • 서비스의 처리가 지연되고 있는 구간을 확인할 수 있음

 

 

 

jaeger를 구축하게 되면 GUI 기반의 서비스를 활용하여 요청 처리에 대한 분석이 가능하게 됩니다.

 

Jaeger 공식 문서를 확인해 보면 다음과 같은 GUI에 대해서 안내하고 있습니다.

 

Introduction

IntroductionSee also: Welcome to Jaeger’s documentation! Below, you’ll find information for beginners and experienced Jaeger users. If you cannot find what you are looking for, or have an issue not covered here, we’d love to hear from you. About Jaeg

www.jaegertracing.io

 

jaeger 공식 문서에서 소개하고 있는 jaeger의 요청 추적 기본 GUI

 

 

 

해당 화면은 수집된 trace 정보를 바탕으로 한 번의 요청이 어떤 흐름을 통해 흘러가는지를 가볍게 확인할 수 있는 곳입니다.

 

또한 trace 정보를 클릭하여 상세 정보도 확인할 수 있습니다.

 

상세 정보를 보게 된다면 아래와 같이 각 서비스 별로 비즈니스 처리가 이루어진 순서와 소요 시간, 장애가 발생했을 땐 왼쪽 부분의 느낌표로 처리된 부분을 한눈에 확인하여 어떤 흐름으로 요청이 처리되었는지 확인할 수 있게 됩니다.

 

jaeger 공식 문서에서 소개하고 있는 jaeger의 요청 추적 상세 GUI

 

 

 

 

Jaeger Operator

 

관련 글에 걸어둔 것 중 istio에 대해 적은 글을 보면 istio operator라는 것을 확인할 수 있었는데 jaeger operator 또한 비슷한 역할이 수행됩니다.

 

operator라고 하는 것은 kubernetes에서 애플리케이션 서비스의 배포와 수명 주기 관리들을 자동화하도록 컨트롤러 역할을 수행합니다.

 

operator가 없다면 jaeger를 구성하기 위해 필요한 jaeger query, jaeger collector 등을 별도의 리소스로 모두 관리하며 설치가 이루어져야 합니다.

 

하지만 operator를 활용하면 jaeger 구성을 위해 정의된 CRD를 이용하여 jaeger 동작을 위해 필요한 서비스들의 리소스들을 자동적으로 구성해 줍니다.

 

더 편한 방식으로 관리가 가능하기 때문에 jaeger operator를 이용하는 것을 권장하며, 필요에 따라 operator를 꼭 사용하지 않아도 설치하는 것에는 문제가 없습니다.

 

 

 

 

Jaeger Storage 구성

 

jaeger를 활용하기 위해서는 stroage 구성이 필요할 수 있습니다.

 

물론 memory 기반으로도 관리가 됩니다.

 

그러나 운영 단계에서는 별도의 storage를 구성하여 trace 정보들을 보관하는 과정을 가진다면 데이터가 손실되지 않고 추적 관측이 필요할 때 안정적으로 활용할 수 있습니다.

 

 

 

storage로 구성될 수 있는 서비스들은 다음과 같이 다양하게 존재합니다.

 

  • elasticsearch
  • cassandra
  • kafka
  • open search
  • 등등...

 

 

어떤 구조와 방식을 선호하는지에 따라 설정되는 storage의 종류가 달라질 수 있습니다.

 

이들 중 대규모 트래픽이 아닌 곳에서 가장 대중적으로 많이 사용되는 것으로 보이는 것은 빠른 검색과 집계가 가능한 elasticsearch로 생각됩니다.

 

 

 

storage를 구성할 때 가장 중요하다고 생각하는 요소를 고른다면 보관 기관과 압축이라고 얘기할 수 있습니다.

 

jaeger를 구축하게 된다면 클러스터 환경 내부에 존재하는 모든 서비스에서 trace 정보가 수집되고 그 정보들이 storage의 디스크를 차지하는 현상이 발생하게 됩니다.

 

물론 otel collector의 tail sampling 기능을 이용하거나 수집이 이루어지는 곳에서 head sampling 처리가 이루어져서 모든 트래픽의 trace 정보가 100% 수집되지는 않겠지만, 적재되는 데이터의 양이 많아지기에 보관 기관과 압축 과정을 필수적으로 설정하는 것을 권장합니다.

 

jaeger operator를 활용하면 jaeger CRD의 설정 정보에 보관 기관과 압축 과정에 대한 설정을 담을 수 있습니다.

 

그래서 이곳에서는 storage를 구성하는 정보에 별도의 설정을 담지는 않을 예정입니다.

 

 

 

elasticsearch를 이용하여 storage를 구성하는 분들은 다음 방식을 참고해 주시면 될 것 같습니다.

 

만약, 다른 stroage 설정이 필요하신 경우라면 별도의 레퍼런스를 보시는 것을 권장드립니다.

 

 

 

[ 1. elasticsearch yaml 구성 ]

 

elasticsearch를 설치할 때는 helm을 활용할 예정입니다.

 

helm 기반으로 설치하기 위해 리소스 구성을 위한 추가적인 yaml 정보를 다음과 같이 작성합니다.

 

// elastic-values.yaml
# replicas 설정
replicas: 1

# es 보안 기능 비활성화 설정, 운영 단계에서는 활성화 권장
esConfig:
  elasticsearch.yml: |
    xpack.security.enabled: false
    
# http protocol 사용으로 cert 생성 미 설정
createCert: false

# OOM이 발생하거나, 과도한 GC에 의한 성능 저하 막기 위해 사이즈 조정
# 설정된 메모리의 50%로 적용하는 것을 권장
esJavaOpts: "-Xms512m -Xmx512m" # heap size 512m 설정


resources:
  # resource request 설정 (스케줄링 되기 위해 필요한 최소 리소스 설정)
  requests:
    cpu: 200m
    memory: 1Gi
  # resource limit 설정 (사용할 수 있는 최대 리소스 설정)
  limits:
    cpu: 200m
    memory: 1Gi
    
# strogae 설정
volumeClaimTemplate:
  # storageClassName: # storage class가 존재하는 경우 설정하여 pvc 기반 보관
  accessModes: ["ReadWriteOnce"] # access mode 설정 (single node read/write)
  resources:
    requests:
      storage: 10Gi # 용량 설정
      
# http protocol 설정
protocol: http

# health check 판단 조정
clusterHealthCheckParams: "wait_for_status=yellow&timeout=30s"

 

 

 

[ 2. helm repository 추가 ]

 

 $ helm repo add elastic https://helm.elastic.co
 $ helm repo update

 

 

혹시 추가 사항으로 window 기반의 docker desktop을 활용하시는 분들이라면 다음 명령어를 이용한 설정도 필요할 수 있습니다.

 

참고만 하시면 될 것 같습니다.

 

 $ wsl -d docker-desktop sysctl -w vm.max_map_count=382144
 $ wsl -d docker-desktop sh -c 'echo "vm.max_map_count=382144" >> /etc/sysctl.conf'

 

 

 

[ 3. elasticsearch 설치 ]

 

$ helm install elastic elastic/elasticsearch -n observability -f elastic-values.yaml

 

 

 

[ 4. 설치 확인 ]

 

설치가 올바르게 되었다면 pod가 올바르게 동작하는지 확인합니다.

 

$ kubectl get pods -n observability

 

 

 

그리고 다음 명령어를 입력하여 elasticsearch 계정 정보를 위한 secret도 생성이 되었는지 확인해 줍니다.

 

$ kubectl get secret -n observability

 

elasticsearch 을 설치할 때 자동으로 생성되는 credentials secret 정보를 확인

 

 

 

 

Jaeger 설치

 

storage 구성이 완료되었다면 본격적으로 jaeger를 설치해 보겠습니다.

 

jaeger 설치는 operator 기반으로 수행되고, operator를 설치하기 전 필요한 것 중 하나는 cert manager 구성이 필요합니다.

 

cert manager의 경우 jaeger 구성을 위한 서비스끼리 api를 포함한 내부 통신을 위해 사용되는 정보이며, 최신 버전들은 모두 cert manager의 구성이 필수입니다.

 

이미 kubernetes 내부에 구성되어 있는 cert manager가 있다면 해당 정보를 그대로 사용하시면 됩니다.

 

 

 

[ 1. cert manager 설치 ]

 

cert manager의 경우 최신 release 버전은 CertManager Release에서 확인할 수 있습니다.

 

$ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.19.1/cert-manager.yaml

 

 

 

[ 2. cert manager 설치 확인 ]

 

$ kubectl get pods -n cert-manager

 

 

 

[ 3. jaeger operator 설치 ]

 

jaeger를 설치하기 전 operator를 kubernetes에 구성해놔야 합니다.

 

jaeger operator의 최신 release 버전은 JaegerOperator Release에서 확인할 수 있습니다.

 

$ kubectl create -f https://github.com/jaegertracing/jaeger-operator/releases/download/v1.65.0/jaeger-operator.yaml -n observability

 

 

 

[ 4. jaeger operator 설치 확인 ]

 

$ kubectl get pods -n observability

 

 

 

[ 5. jaeger yaml 구성 ]

 

jaeger operator까지 설치가 이루어졌다면 jaeger CRD를 이용하여 편리하게 구성을 해볼 수 있습니다.

 

구성에 따라 여러 가지 설정 방식이 존재하겠지만 다음과 같은 설정을 통해 기본적인 환경을 구축해 볼 수 있습니다.

 

// jaeger.yaml
apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: jaeger
  namespace: observability
spec:
  # 배포 아키텍처 strategy 설정
  # production : 외부 스토리지, Ingress 설정 등 운영 환경 표준 전략
  # allInOne : memory 스토리지를 사용한 개발/테스트 환경을 위한 전략
  # streaming : kafka를 이용한 대용량 트래픽 처리 스트리밍 구성 전략
  strategy: production

  storage:
    # storage로 es 사용 설정
    type: elasticsearch
    options:
      es.server-urls: "http://elasticsearch-master.observability.svc.cluster.local:9200"
      es.index-prefix: "jaeger"
      es.use-aliases: "true" # rollover 사용을 위한 alias 사용 설정
    secretName: elasticsearch-master-credentials # elasticsearch 가 설치되며 함께 만들어진 credentials secret
    # 오랜 기간 저장된 es index 정보를 비워주는 설정
    esIndexCleaner:
      enabled: true # cron job 기반 cleaner 사용 설정
      numberOfDays: 7 # index 정보가 유지되는 일수
      schedule: "15 16 * * *" # cron 동작을 위한 schedule 설정 (UTC 기준 16시 15분, KST 기준 1시 15분)
    # es index의 크기가 커질 때 성능 유지를 위한 index 분할 설정
    esRollover:
      conditions: "{\"max_age\": \"1d\"}" # 하루마다 새로운 index 생성
      schedule: "0 * * * *" # cron 동작을 위한 schedule 설정 (매시 정각)

  collector:
    # HPA 기반 autoscale 설정 적용
    maxReplicas: 5
    minReplicas: 1
    # autoscale을 적용하지 않고 고정된 replicas 설정이 필요한 경우
    # replicas: 1
    resources:
      # resource request 설정 (collector pod가 스케줄링 되기 위해 필요한 최소 리소스 설정)
      requests:
        cpu: 500m
        memory: 512Mi
      # resource limit 설정 (collector가 사용할 수 있는 최대 리소스 설정)
      limits:
        cpu: "1"
        memory: 1Gi

  query:
    options:
      # query ui base path 설정
      query.base-path: "/"
    
  ingress:
    # ingress 미 사용, 필요한 경우 별도의 ingress를 구성하는 것을 권장
    enabled: false

 

 

 

[ 6. jaeger 설치 ]

 

$ kubectl apply -f jaeger.yaml

 

 

 

[ 7. jaeger 설치 확인 ]

 

다음 명령어를 이용하여 생성된 pod 정보들을 확인해 보면 총 3개의 pod가 추가된 것을 볼 수 있습니다.

 

  • jaeger-collector
  • jaeger-es-rollover
  • jaeger-query

 

$ kubectl get pods -n observability

 

 

 

[ 8. jaeger query ui 확인 ]

 

GUI를 확인하기 위해서는 jaeger query를 활용하면 됩니다.

 

보통 ingress 설정을 통해 외부에 노출시킬 텐데, ingress를 활용하신다면 jaeger operator에서 제공해 주는 ingress 보다는 별도의 ingress를 구축하는 것이 더 유연한 설정을 할 수 있으니 참고해 주시면 됩니다.

 

저는 port-forward를 통해 다음과 같이 확인해 보겠습니다.

 

$ kubectl port-forward svc/jaeger-query 16686 -n observability

 

 

 

그리고 다음과 같이 url을 입력해 보면 jaeger GUI를 확인할 수 있습니다.

 

jaeger operator를 이용하여 jaeger 설치한 뒤 jaeger query ui를 접속하면 보이는 초기 페이지

 

 

 

 

OpenTelemetry 연동

 

open telemetry 연동에 가장 대표적인 것은 otel collector가 존재합니다.

 

otel collector를 아직 구성하지 못하신 분들은 상단에 관련 글들을 확인해 주시길 바랍니다.

 

 

 

이전에 설정했던 otel collector 설정에서 새롭게 구축된 jaeger를 exporter로 추가하는 설정이 필요합니다.

 

사실 이미 이전 글에서 설정 값들을 추가해 놨지만, 적용되어 있지 않다는 가정하에 추가적으로 구성되어야 하는 설정 값들에 대해서만 표기한다면 다음과 같이 작성해볼 수 있습니다.

 

// otel-collector.yaml
config:
  # 데이터를 내보내는 exporter 서비스 설정
  exporters:
    # otlp 기반 exporter (jeager 설정)
    otlp:
      endpoint: jaeger-collector.observability.svc:4317 # gRPC 기반 데이터 전송
      tls:
        insecure: true # tls 인증 생략

  service:
    # Receivers → Processors → Exporters 처리 파이프라인 정의, 정의된 순서대로 동작을 수행
    pipelines:
      traces:
        exporters:
          - otlp
          - debug
        processors:
          - ...
        receivers:
          - ...

 

 

 

그런 뒤 helm을 이용하여 otel collector를 재 구성 해줍니다.

 

$ helm upgrade --install otel-collector open-telemetry/opentelemetry-collector -n observability -f otel-collector-values.yaml

 

 

 

 

otel collector에 의해 trace 정보가 jaeger로 exporter 처리가 이루어지게 된다면 최종적으로 jaeger ui에 trace 정보가 확인되는 것을 볼 수 있습니다.

 

올바르게 수집이 되는 경우 공식 문서에서 볼 수 있었던 것처럼 다음과 같이 trace 목록들이 ui에 노출되는 것을 확인할 수 있습니다.

 

otel-collector와 jaeger를 연동한 뒤 otel-collector에 수집된 trace 정보가 jaeger ui에 표출되는 화면

 

 

 

 

 

 

 

이상으로 jaeger operator를 구축하여 trace 시각화하는 방법에 대해 간단하게 알아보는 시간이었습니다.

 

읽어주셔서 감사합니다.

 

 

 

728x90
반응형

댓글