VictoriaTraces로 트레이스 백엔드 구축하기: VictoriaLogs 생태계로 통일하는 분산 추적

VictoriaTraces는 VictoriaLogs 위에 만들어진 트레이스 데이터베이스로, OTLP 스팬을 구조화 로그로 변환해 저장하고 Jaeger API로 조회합니다. VictoriaLogs와 같은 운영 방식(single/cluster 차트, vmauth 진입점, vmui, 로컬 디스크 저장)이라, VictoriaLogs 스택을 쓰는 환경에 생태계 일관성이 큽니다. 적재는 /insert/opentelemetry/v1/traces(single 10428 / cluster vmauth 8427)이고, Grafana에서는 Jaeger 데이터소스로 연결합니다. 이 글은 “OTel 트레이스 확장” 시리즈 3편(VictoriaTraces 백엔드) 으로, 2편 Tempo와 대칭되는 또 하나의 선택지를 다룹니다.

🎯 VictoriaTraces란 무엇인가 #

VictoriaTraces는 VictoriaMetrics 진영의 트레이스 데이터베이스로, VictoriaLogs 아키텍처 위에 만들어졌습니다. OTLP 스팬을 받아 구조화 로그로 변환해 저장하고, Jaeger Query Service JSON API로 조회합니다.

  • 로컬 디스크 저장-storageDataPath에 저장하며 오브젝트 스토리지가 불필요합니다(Tempo와 결정적으로 다른 점). 데이터는 per-day 파티션(YYYYMMDD)으로 저장됩니다.
  • 선형 확장·운영 단순 — VictoriaLogs처럼 CPU/RAM/디스크에 선형 확장됩니다.
  • VictoriaLogs와 같은 운영vmauth·vmui·vmalert를 공유합니다.

💡 VictoriaLogs를 이미 쓴다면 운영 방식이 거의 동일해 학습·운영 비용이 최소입니다. 다만 Tempo보다 신생이라, 도입 시 버전·기능 성숙도를 확인하는 것이 좋습니다(빠르게 발전 중).


🧱 VictoriaLogs와 닮은 구조 #

소규모는 victoria-traces-single(단일 노드), 대규모는 victoria-traces-cluster 입니다. 클러스터는 VictoriaLogs 클러스터와 판박이 구조입니다.

컴포넌트역할
vtinsert트레이스 수신
vtstorage저장(PVC, 로컬 디스크)
vtselect조회
vmauth적재·조회 진입점·LB·인증 (8427)

vtinsert/vtselect/vtstorage같은 바이너리의 역할 분리입니다(VictoriaLogs와 동일).

flowchart LR
    OT["OTel Collector"] -->|"OTLP"| VMA["vmauth :8427"]
    VMA -->|"/insert/*"| VI["vtinsert"]
    VI --> VS["vtstorage<br/>PVC(로컬 디스크)"]
    VSEL["vtselect"] --> VS
    VMA -->|"/select/*"| VSEL
    GF["Grafana<br/>(Jaeger 데이터소스)"] --> VMA
    UI["vmui"] --> VMA

📦 폐쇄망 이미지 준비 #

필요한 이미지는 victoria-traces(본체) + vmauth 입니다. Docker Hub에서 받아 사내 레지스트리로 미러합니다.

1docker pull docker.io/victoriametrics/victoria-traces:<버전>
2docker pull docker.io/victoriametrics/vmauth:<버전>
3# 사내 레지스트리로 재태깅·push 후, 차트가 끌어오는 이미지 전체 확인
4helm template t ./victoria-traces-cluster-<버전>.tgz -f vt-values.yaml | grep 'image:' | sort -u

⚙️ values.yaml (cluster, 대규모·보안) #

핵심 설정입니다. 차트는 helm repo add vm https://victoriametrics.github.io/helm-charts/로 받고, 폐쇄망은 global.image.registry로 사내 레지스트리를 지정합니다.

 1# === vt-values.yaml ===
 2nameOverride: vt          # 리소스 이름 63자 제한 회피(VictoriaLogs와 동일 패턴)
 3
 4global:
 5  image:
 6    registry: <사내레지스트리>
 7
 8vtstorage:
 9  replicaCount: 3
10  retentionPeriod: 7d            # 시간 기반 (최소 24h). 또는 디스크 기반 옵션
11  persistentVolume:
12    enabled: true
13    storageClassName: <사내-storageclass>
14    size: 50Gi
15  resources:
16    requests: { cpu: "1", memory: 2Gi }
17    limits:   { cpu: "2", memory: 4Gi }
18
19vtinsert:
20  replicaCount: 2
21
22vtselect:
23  replicaCount: 2
24
25vmauth:
26  enabled: true                  # 진입점/LB/인증 (8427)

💡 retention·PVC 사이징은 VictoriaLogs 백엔드 편과 같은 원리입니다 — per-day 파티션이라 오래된 날짜 파티션을 통째로 지워 retention이 빠르게 적용되고, PVC는 점진 증설을 전제로 보수적으로 잡습니다.


🚀 설치 #

1kubectl create namespace tracing
2helm install vt ./victoria-traces-cluster-<버전>.tgz -f vt-values.yaml -n tracing
3kubectl -n tracing get statefulset,deploy,svc,pvc

vtstorage(StatefulSet)의 PVC가 Bound이고 파드가 Running인지, vtinsert·vtselect·vmauth가 모두 Running인지 확인합니다.


🔗 OTel Collector에서 VictoriaTraces로 보내기 #

Collector의 traces exporter를 otlphttptraces_endpoint로 적재 경로에 향하게 합니다. 트레이스만 독립이든 로그와 통합이든 exporter 설정은 같습니다.

 1# OTel Collector traces 파이프라인 발췌 (OTLP/HTTP)
 2exporters:
 3  otlphttp/victoriatraces:
 4    traces_endpoint: http://vt-victoria-traces-cluster-vmauth.tracing.svc:8427/insert/opentelemetry/v1/traces
 5    compression: gzip
 6    headers:
 7      # VT-Extra-Fields: "team=backend"      # 필드 추가(선택)
 8      # Authorization: "Bearer ${VT_TOKEN}"  # 인증(선택)
 9service:
10  pipelines:
11    traces:
12      receivers: [otlp]
13      processors: [memory_limiter, batch]
14      exporters: [otlphttp/victoriatraces]

⚠️ 적재 경로가 Tempo와 다릅니다. VictoriaTraces는 otlphttptraces_endpoint/insert/opentelemetry/v1/traces를 줍니다. gRPC로 보내려면 VictoriaTraces에서 -otlpGRPCListenAddr(예: :4317)로 gRPC 리스너를 켠 뒤 otlp exporter를 씁니다(기본 비활성). Gateway 공용/분리 구성은 개요를 참고하세요.


🔎 조회: vmui와 Grafana(Jaeger) #

두 가지로 봅니다 — 내장 vmui, 그리고 Grafana의 Jaeger 데이터소스.

1# vmui 내장 UI
2kubectl -n tracing port-forward svc/vt-victoria-traces-cluster-vmauth 8427
3# 브라우저: http://localhost:8427/select/vmui   → 스팬 탐색

Grafana는 Jaeger 데이터소스로 연결합니다(VictoriaTraces가 Jaeger API 호환).

  • URL: http://vt-victoria-traces-cluster-vmauth.tracing.svc:8427/select/jaeger/

⚠️ Tempo는 “Tempo 데이터소스"였지만, VictoriaTraces는 “Jaeger 데이터소스” 를 씁니다. 혼동하지 마세요.


⚖️ Tempo와 무엇이 다른가 #

둘 다 OTLP를 받는 트레이스 백엔드지만, 저장·조회·생태계가 다릅니다.

항목Grafana TempoVictoriaTraces
저장오브젝트 스토리지 필수(S3 등)로컬 디스크(PVC) — VictoriaLogs와 동일
Grafana 데이터소스TempoJaeger
생태계Grafana 통합VictoriaLogs·vmauth·vmui·vmalert 통일
성숙도더 검증됨발전 중(신생)
  • VictoriaTraces — VictoriaLogs를 이미 운영한다면 같은 방식이라 일관성이 큽니다. 별도 오브젝트 스토리지 운영 부담이 없습니다.
  • Tempo — Grafana 생태계 통합과 성숙도가 강점입니다.

어느 쪽이 “우월"한 게 아니라 성향과 성숙도 차이입니다. VictoriaLogs 스택으로 통일하고 싶으면 VictoriaTraces, Grafana 생태계·검증을 중시하면 Tempo입니다.


📐 규모별 변형 #

규모에 따라 달라지는 점만 한곳에 모으면 다음과 같습니다. 기본 전제는 대규모(cluster) 입니다.

구분대규모(기본)소규모/개인
차트victoria-traces-clustervictoria-traces-single
진입vmauth 842710428 직접
저장vtstorage replica 3+단일 노드

💡 소규모는 single 차트(10428) 로 시작하고, 커지면 cluster로 전환하세요(단일 노드를 vtstorage로 승격 — VictoriaLogs와 동일 원리).


❓ 자주 묻는 질문 #

Q. 트레이스 저장에 S3가 필요한가요? 아닙니다. 로컬 디스크(PVC) 입니다 — VictoriaLogs와 동일하며, Tempo(오브젝트 스토리지 필수)와 다른 점입니다.

Q. 적재 경로가 뭔가요? /insert/opentelemetry/v1/traces입니다(single 10428, cluster vmauth 8427).

Q. Grafana 데이터소스는 무엇인가요? Jaeger 데이터소스(/select/jaeger/)입니다. Tempo와 다릅니다.

Q. gRPC로 적재하려면? VictoriaTraces에서 -otlpGRPCListenAddr로 gRPC 리스너를 켠 뒤 otlp exporter를 씁니다(기본 비활성).

Q. VictoriaLogs와 같이 운영하기 쉬운가요? 같은 생태계(vmauth·vmui·vmalert)라 일관됩니다. 단 성숙도는 Tempo보다 발전 중입니다.

Q. 멀티테넌시는? AccountID/ProjectID 헤더로 테넌트를 구분합니다.


🧭 시리즈: OTel 트레이스 확장 #

이 편의 한 줄 요약: “VictoriaTraces는 VictoriaLogs 기반의 트레이스 DB로, 로컬 디스크에 저장하고 Jaeger API로 조회한다.” 적재는 /insert/opentelemetry/v1/traces, 조회는 Grafana Jaeger 데이터소스이며, VictoriaLogs 스택과의 운영 일관성이 강점입니다(성숙도는 Tempo보다 발전 중).

🔗 이 트레이스 확장은 “OTel + VictoriaLogs 로그 스택” 시리즈(완결) 위에 얹힙니다.


📚 참고 #