Fluent Bit vs OpenTelemetry Collector, 로그 파이프라인 뭘 쓸까
로그 파이프라인 얘기가 나올 때마다 팀 내부에서 도는 논쟁이 하나 있다. "그냥 Fluent Bit 계속 쓰면 되지 않냐" vs "이제 OpenTelemetry Collector로 통합해야 하지 않냐". 사실 둘 다 맞는 말이라 답이 애매하다. 몇 달간 두 도구를 병렬로 굴려보고 정리한 감상을 적어둔다.
어디서 마주치는 문제인가
우리 팀 클러스터는 노드 40대 규모다. 로그는 원래 Fluent Bit DaemonSet으로 수집해서 사내 Loki로 밀어넣고 있었다. 문제는 그 다음 단계다. 트레이스는 OTel Collector로, 메트릭은 Prometheus로, 로그만 Fluent Bit로 각각 다른 파이프라인이 돌고 있으니 설정 관리가 세 갈래로 갈라진다. 새로 붙는 서비스마다 세 곳을 다 봐야 하고, 라벨링 규칙도 도구마다 다르다.
여기서 자연스럽게 나오는 질문이 "그럼 OTel Collector 하나로 다 통합하면 되지 않냐"였다. 근데 그렇게 단순하지 않았다.
자원 사용량이 생각보다 크게 다르다
이게 첫 번째로 부딪힌 벽이었다. Fluent Bit는 유휴 상태에서 5~10MB 정도의 메모리를 쓰고 CPU도 거의 안 먹는다. OTel Collector는 최소 설정으로도 30~50MB에서 시작한다. 파이프라인에 프로세서를 몇 개 붙이면 100MB를 넘기는 것도 순식간이다.
노드 40대에 DaemonSet으로 돌린다고 하면 이 차이는 무시할 수 없다. 40 × 10MB = 400MB vs 40 × 100MB = 4GB. 클러스터 오버헤드로만 이만큼 차이가 난다. 물론 노드당 몇 GB짜리 워커 노드라면 별거 아니지만, 우리는 t3.medium급 노드가 섞여 있어서 이게 실제로 성능에 영향을 줬다.
한 번은 OTel Collector를 노드 전체에 배포하는 실험을 했는데, 특정 노드에서 kubelet이 메모리 압박으로 pod eviction을 시작한 적이 있었다. 우연이었을 수도 있지만 그 이후로 노드 레벨은 Fluent Bit로 남겨두는 게 낫겠다는 결론에 도달했다.
그럼 둘 다 쓴다는 건 어떻게 생겼나
Fluent Bit 공식 문서에도 OpenTelemetry output이 정식으로 들어와 있다. 즉 노드 레벨에서 Fluent Bit로 로그를 긁고, OTLP로 중앙의 OTel Collector에 밀어넣는 구조가 가능하다. 우리는 이 하이브리드 구조로 정착했다.
# Fluent Bit output (노드 DaemonSet)
[OUTPUT]
Name opentelemetry
Match *
Host otel-collector.observability.svc
Port 4318
Metrics_uri /v1/metrics
Logs_uri /v1/logs
Traces_uri /v1/traces
tls off
중앙에는 OTel Collector Deployment를 replicas 3개로 띄워두고, 여기서 라벨 표준화나 PII 마스킹 같은 무거운 처리를 담당하게 했다. 노드 사이드는 최대한 얇게 유지하는 게 핵심이다.
그러면 Fluent Bit는 언제 없앨 수 있는가
이론적으로는 OTel Collector가 파일 로그 수집도 지원한다(filelog receiver). 그러니 노드 레벨을 통째로 OTel로 바꿔도 되는 거 아니냐고 물어볼 수 있다.
내가 직접 벤치마크한 결과로는, 초당 수만 건 이상의 로그를 처리하는 노드에서는 Fluent Bit가 여전히 더 안정적이었다. C로 짜인 만큼 GC 스톱이 없고, 파일 tail 성능도 검증돼 있다. 특히 로그 폭주 상황에서 백프레셔 처리가 훨씬 부드러웠다.
반면 OTel Collector의 filelog는 Go로 짜였고, 스토리지 백엔드로 배치를 밀어낼 때 미묘한 지연이 관찰됐다. 낮은 트래픽에서는 문제없지만, 배포 이벤트로 순간적으로 로그가 폭증할 때 몇 초씩 밀리는 게 눈에 띄었다.
그래서 어떻게 결정했나
지금 우리 팀 기준으로 정리하자면:
- 노드 레벨 수집: Fluent Bit. 가볍고, 검증됐고, 로그 폭주에 강하다.
- 중앙 집계/변환: OTel Collector. 로그/메트릭/트레이스를 한 곳에서 라벨링/필터링/라우팅한다.
- 트레이스/메트릭: 서비스에서 OTel SDK로 직접 OTel Collector에 밀어넣는다. Fluent Bit는 거치지 않는다.
이 구조의 장점은 Fluent Bit 설정이 아주 얇아진다는 것이다. 노드 수준에서는 그냥 "긁어서 OTLP로 던져라"만 하면 된다. 라벨링, 리다이렉션, 마스킹 같은 로직은 전부 OTel Collector 쪽 설정 파일 하나에 모인다. 새 서비스 붙일 때 봐야 할 파일이 실질적으로 하나로 줄었다.
단점도 있다. 홉이 하나 더 늘어난 만큼 네트워크 실패 지점이 하나 더 생겼고, OTel Collector가 죽으면 노드 쪽 Fluent Bit가 큐에 쌓아뒀다가 뱉는 구조라 디스크 스토리지 관리가 조금 예민해졌다. 아직 대규모 장애를 겪어본 건 아니라 실전에서 어떻게 나올지는 좀 더 지켜봐야 한다.
결론이라기보다는
"뭘 써야 하냐"에 대한 단답은 나오기 어렵다. 노드 수가 적고 로그량이 크지 않다면 OTel Collector 하나로 통합하는 게 관리 부담이 훨씬 적다. 반대로 노드가 많고 리소스가 빠듯하다면 Fluent Bit를 계속 살려두는 게 안전하다.
한 가지 확실한 건, OTel 진영이 로그 표준을 강력하게 밀고 있고 Fluent Bit도 OTLP를 정식 지원하는 방향으로 계속 가고 있다는 점이다. 완전 통합은 아직 아니지만, 몇 년 내로 두 도구의 경계가 훨씬 흐려질 거라고 본다. 그때까지는 하이브리드가 현실적인 답인 것 같다.
혹시 다른 팀에서 두 도구 중 하나로 완전 통합해서 잘 돌리고 있는 사례가 있으면 궁금하다. 특히 트래픽이 큰 환경에서.
'IT > 모니터링' 카테고리의 다른 글
| PromQL의 rate()랑 irate(), 언제 뭘 쓸지 헷갈릴 때 (0) | 2026.07.05 |
|---|---|
| Prometheus absent()로 알람 걸 때, unless도 같이 봐야 하는 이유 (0) | 2026.07.03 |
| OpenTelemetry Collector, Agent와 Gateway 두 층으로 굴리기 (0) | 2026.07.02 |
| 새벽에 Prometheus가 죽었다 — 카디널리티 폭발 삽질기 (0) | 2026.07.01 |
| OpenTelemetry tail sampling이 결정을 내리는 순간을 톺아보기 (0) | 2026.06.29 |