在 Kubernetes 中使用 OpenTelemetry 和 Fluent Bit 构建可观测性架构

发布: (2026年1月14日 GMT+8 02:00)
5 min read

Source: DZone DevOps

为什么选择 OpenTelemetry (OTel) 和 Fluent Bit?

  • OpenTelemetry 是一个供应商无关、由 CNCF 托管的框架,标准化指标、日志和追踪的收集。它提供 SDK、API 和代理,可直接嵌入应用程序或作为 sidecar/daemonset 运行。
  • Fluent Bit 是一个轻量级、高性能的日志处理器和转发器。它可以从容器中获取日志,使用 Kubernetes 元数据进行丰富,并将日志发送到多种后端(例如 Elasticsearch、Loki、CloudWatch)。

将 OTel 与 Fluent Bit 结合使用,可构建统一的管道:

  • OTel Collector 从集群收集指标和追踪,应用处理器(例如批处理、属性丰富),并将其导出到可观测性平台。
  • Fluent Bit 负责日志收集、解析和路由,确保日志通过共享标识符(例如 trace_idspan_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]
  1. Instrumentation – 为你的服务添加 OTel SDK(支持 Go、Java、Python、.NET 等)。
  2. Collector Deployment – 将 OTel Collector 以 DaemonSet 方式部署,并使用如下配置:
    • 通过 Prometheus 抓取接收指标。
    • 通过 OTLP(gRPC/HTTP)接收链路追踪。
    • 将数据导出到你选择的后端(例如 Jaeger、Prometheus、Grafana Cloud)。
  3. Fluent Bit Deployment – 将 Fluent Bit 以 DaemonSet 方式部署,完成以下工作:
    • /var/log/containers/*.log 读取容器日志。
    • 为日志添加 pod、namespace 和 node 元数据。
    • 将 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 – 确保你的服务传播 traceparenttracestate 头(W3C Trace Context)。Fluent Bit 从日志中提取这些头(如果存在),并将其添加为 trace_idspan_id 字段。
  • Unified Dashboards – 在 Grafana 或你的 APM UI 中,你可以点击 trace ID 查看相关日志和指标图表,实现端到端可视化。

此方法的优势

优势描述
供应商无关在不更改仪器化的情况下切换后端。
可扩展DaemonSet 在每个节点上运行,能够处理高吞吐量工作负载。
低开销Fluent Bit 的轻量化设计将 CPU/内存影响降至最低。
丰富的上下文关联的日志、指标和追踪简化根因分析。

最后思考

在 Kubernetes 中使用 OpenTelemetry 和 Fluent Bit 构建可观测性,为所有遥测数据提供 单一、连贯的管道。通过标准化收集、增强和导出,您可以降低运营复杂性,加快事件响应,并为未来的扩展和合规需求奠定坚实基础。

首先对几个关键服务进行仪器化,部署 collector 和 Fluent Bit,并逐步扩大覆盖范围。回报——对云原生应用的清晰、可操作的洞察——非常值得投入。

Back to Blog

相关文章

阅读更多 »

我对 Kubernetes 的看法

文章 URL: https://garnaudov.com/writings/how-i-think-about-kubernetes/ 评论 URL: https://news.ycombinator.com/item?id=46396043 点赞数: 31 评论数: 13