Kubernetes에서 OpenTelemetry와 Fluent Bit를 활용한 관찰성 아키텍처 설계
Source: DZone DevOps
위에 제공된 링크에 포함된 전체 텍스트를 번역하려면 해당 내용을 복사해서 여기 붙여 주세요.
코드 블록, URL 및 기술 용어는 그대로 유지하고, 일반 문장은 한국어로 번역해 드리겠습니다.
왜 OpenTelemetry (OTel)와 Fluent Bit인가?
- OpenTelemetry는 벤더에 종속되지 않는 CNCF‑주도 프레임워크로, 메트릭, 로그, 트레이스를 표준화된 방식으로 수집합니다. 애플리케이션에 직접 삽입하거나 사이드카/데몬셋으로 실행할 수 있는 SDK, API, 에이전트를 제공합니다.
- Fluent Bit은 가볍고 고성능인 로그 프로세서이자 포워더입니다. 컨테이너에서 로그를 수집하고 Kubernetes 메타데이터로 풍부하게 만들며, Elasticsearch, Loki, CloudWatch 등 다양한 백엔드로 전달할 수 있습니다.
OTel과 Fluent Bit을 결합하면 통합 파이프라인을 구축할 수 있습니다:
- OTel Collector는 클러스터에서 메트릭과 트레이스를 수집하고, 프로세서(예: 배치, 속성 풍부화)를 적용한 뒤 관측 플랫폼으로 내보냅니다.
- Fluent Bit은 로그 수집, 파싱, 라우팅을 담당하며,
trace_id,span_id와 같은 공유 식별자를 통해 해당 메트릭 및 트레이스와 로그를 연관시킵니다.
Architecture Overview
flowchart TD
subgraph K8s Cluster
A[Application Pods] -->|OTel SDK| B[OTel Collector (DaemonSet)]
A -->|Fluent Bit Sidecar| C[Fluent Bit (DaemonSet)]
end
B -->|Metrics & Traces| D[Observability Backend]
C -->|Logs| D
D -->|Correlation UI| E[Dashboard / APM]
- Instrumentation – 서비스에 OTel SDK를 추가합니다 (Go, Java, Python, .NET 등 사용 가능).
- Collector Deployment – OTel Collector를 DaemonSet으로 배포하고 다음과 같은 구성을 합니다:
- Prometheus 스크랩을 통해 메트릭을 수신합니다.
- gRPC/HTTP를 통한 OTLP로 트레이스를 수신합니다.
- 선택한 백엔드(예: Jaeger, Prometheus, Grafana Cloud)로 데이터를 내보냅니다.
- Fluent Bit Deployment – Fluent Bit을 DaemonSet으로 배포하고 다음을 수행합니다:
/var/log/containers/*.log에서 컨테이너 로그를 읽습니다.- 파드, 네임스페이스, 노드 메타데이터로 로그를 풍부하게 합니다.
- 로그‑트레이스 상관관계를 가능하게 하기 위해 OTel 트레이스 컨텍스트(있는 경우)를 추가합니다.
- 로그를 동일한 백엔드 또는 전용 로그 저장소로 전송합니다.
단계별 구현
1. OpenTelemetry SDK 추가
import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/trace"
)
func main() {
// Initialize tracer provider
tp := otel.GetTracerProvider()
tracer := tp.Tracer("my-service")
// Use tracer in your handlers...
}
언어별 스니펫을 스택에 맞는 적절한 SDK로 교체하십시오.
2. OTel Collector 배포
otel-collector-config.yaml 파일 생성:
apiVersion: v1
kind: ConfigMap
metadata:
name: otel-collector-config
namespace: observability
data:
otel-collector-config.yaml: |
receivers:
otlp:
protocols:
grpc:
http:
prometheus:
config:
scrape_configs:
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
processors:
batch:
memory_limiter:
limit_mib: 400
spike_limit_mib: 100
check_interval: 5s
exporters:
otlphttp:
endpoint: "https://api.myobservability.com/v1/traces"
prometheusremotewrite:
endpoint: "https://api.myobservability.com/v1/metrics"
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlphttp]
metrics:
receivers: [prometheus]
processors: [batch, memory_limiter]
exporters: [prometheusremotewrite]
DaemonSet 적용:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: otel-collector
namespace: observability
spec:
selector:
matchLabels:
app: otel-collector
template:
metadata:
labels:
app: otel-collector
spec:
containers:
- name: otel-collector
image: otel/opentelemetry-collector:latest
args: ["--config=/conf/otel-collector-config.yaml"]
volumeMounts:
- name: config
mountPath: /conf
volumes:
- name: config
configMap:
name: otel-collector-config
3. Fluent Bit 배포
fluent-bit-config.yaml 파일 생성:
apiVersion: v1
kind: ConfigMap
metadata:
name: fluent-bit-config
namespace: observability
data:
fluent-bit.conf: |
[SERVICE]
Flush 5
Daemon Off
Log_Level info
[INPUT]
Name tail
Path /var/log/containers/*.log
Parser docker
Tag kube.*
[FILTER]
Name kubernetes
Match kube.*
Merge_Log On
Keep_Log Off
K8S-Logging.Parser On
K8S-Logging.Exclude On
[FILTER]
Name record_modifier
Match *
Record trace_id ${TRACE_ID}
Record span_id ${SPAN_ID}
[OUTPUT]
Name es
Match *
Host elasticsearch.logging.svc
Port 9200
Index kubernetes-logs
Type _doc
DaemonSet 적용:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluent-bit
namespace: observability
spec:
selector:
matchLabels:
app: fluent-bit
template:
metadata:
labels:
app: fluent-bit
spec:
containers:
- name: fluent-bit
image: fluent/fluent-bit:latest
volumeMounts:
- name: config
mountPath: /fluent-bit/etc
volumes:
- name: config
configMap:
name: fluent-bit-config
로그, 메트릭, 트레이스 연관시키기
- Trace Context Propagation – 서비스가
traceparent와tracestate헤더(W3C Trace Context)를 전파하도록 하세요. Fluent Bit는 로그에서 이러한 헤더를 추출(존재하는 경우)하고trace_id와span_id필드로 추가합니다. - Unified Dashboards – Grafana나 APM UI에서 트레이스 ID를 클릭하면 관련 로그와 메트릭 그래프를 확인할 수 있어, 엔드‑투‑엔드 가시성을 제공합니다.
이 접근 방식의 장점
| 이점 | 설명 |
|---|---|
| 벤더 독립적 | 계측을 변경하지 않고 백엔드를 전환할 수 있습니다. |
| 확장 가능 | DaemonSet은 모든 노드에서 실행되어 고처리량 워크로드를 처리합니다. |
| 낮은 오버헤드 | Fluent Bit의 경량 설계는 CPU/메모리 영향을 최소화합니다. |
| 풍부한 컨텍스트 | 연관된 로그, 메트릭 및 트레이스가 근본 원인 분석을 간소화합니다. |
최종 생각
OpenTelemetry와 Fluent Bit을 사용해 쿠버네티스에서 관측성을 설계하면 단일하고 일관된 파이프라인을 모든 텔레메트리 데이터에 제공할 수 있습니다. 수집, 풍부화, 내보내기를 표준화함으로써 운영 복잡성을 줄이고, 사고 대응을 가속화하며, 향후 확장 및 규정 준수 요구에 대한 견고한 기반을 마련합니다.
몇몇 핵심 서비스에 먼저 계측을 적용하고, 콜렉터와 Fluent Bit을 배포한 뒤, 점진적으로 적용 범위를 확대하세요. 그 보상—클라우드 네이티브 애플리케이션에 대한 명확하고 실행 가능한 인사이트—은 노력에 충분히 가치가 있습니다.