Fluent Bit se ha convertido en el colector de logs estandar para entornos de contenedores y Kubernetes. Con un consumo de memoria de apenas 1-5 MB por instancia, procesa miles de registros por segundo sin impactar el rendimiento de las aplicaciones. A diferencia de soluciones mas pesadas como Logstash o incluso Fluentd, Fluent Bit fue diseñado desde cero para ejecutarse como sidecar o DaemonSet en entornos donde cada megabyte de RAM cuenta.

En esta guía cubriremos la arquitectura interna de Fluent Bit, las diferencias clave con Fluentd, el despliegue en Kubernetes como DaemonSet, la configuración de parsing y routing de logs, y las mejores prácticas de rendimiento.

Fluent Bit vs Fluentd: diferencias clave

Ambos pertenecen al proyecto CNCF Fluentd, pero sirven propositos diferentes:

CaracteristicaFluent BitFluentd
LenguajeCRuby + C
Memoria tipica1-5 MB30-100 MB
Plugins~100 built-in1000+ (community)
PropositoColección y forwardingColección, procesamiento y agregación
Formato configNativo o YAMLRuby-style config

La recomendación general es usar Fluent Bit como agente ligero en cada nodo (edge) y, si necesitas procesamiento complejo o plugins específicos, agregar Fluentd como agregador centralizado. Esta arquitectura se conoce como el patron “Fluent Bit -> Fluentd -> Backend”.

Sin embargo, para la mayoria de los casos de uso en Kubernetes, Fluent Bit solo es suficiente para recolectar, parsear y enviar logs directamente a Elasticsearch, CloudWatch o S3.

Arquitectura de Fluent Bit

Fluent Bit procesa datos a traves de un pipeline con cuatro etapas:

Inputs (entradas)

Los inputs definen de donde se recolectan los datos. Los mas usados en contenedores:

  • tail: lee archivos de log, incluyendo los logs de contenedor almacenados por el kubelet en /var/log/containers/.
  • systemd: captura logs del journal de systemd (kubelet, containerd, Docker daemon).
  • forward: recibe logs via protocolo Forward de Fluentd (TCP).
  • http: recibe logs via HTTP POST, útil para aplicaciones que emiten logs via API.

Parsers (analizadores)

Los parsers transforman logs en texto plano a registros estructurados. Fluent Bit incluye parsers predefinidos para formatos comunes:

[PARSER]
    Name        docker
    Format      json
    Time_Key    time
    Time_Format %Y-%m-%dT%H:%M:%S.%L
    Time_Keep   On

[PARSER]
    Name        nginx
    Format      regex
    Regex       ^(?<remote>[^ ]*) - (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)
    Time_Key    time
    Time_Format %d/%b/%Y:%H:%M:%S %z

[PARSER]
    Name        java_multiline
    Format      regex
    Regex       ^(?<time>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3}) (?<level>[A-Z]+) (?<message>.*)$
    Time_Key    time
    Time_Format %Y-%m-%d %H:%M:%S,%L

Filters (filtros)

Los filtros modifican, enriquecen o descartan registros en el pipeline:

  • kubernetes: enriquece los logs con metadata del pod (nombre, namespace, labels, annotations).
  • modify: agrega, renombra o elimina campos.
  • grep: filtra registros basandose en regex (incluir o excluir).
  • lua: permite transformaciones arbitrarias usando scripts Lua.

Outputs (salidas)

Los outputs definen el destino final de los logs. Fluent Bit soporta multiples outputs simultaneos:

  • es (Elasticsearch/OpenSearch)
  • cloudwatch_logs (AWS CloudWatch)
  • s3 (AWS S3 para archivado)
  • loki (Grafana Loki)
  • forward (reenvio a Fluentd)
  • kafka (Apache Kafka)
  • stdout (para debug)

Despliegue en Kubernetes como DaemonSet

El patron mas comun es desplegar Fluent Bit como DaemonSet, de forma que cada nodo del cluster tenga una instancia que recolecte los logs de todos los contenedores en ese nodo.

Manifiesto base

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluent-bit
  namespace: logging
  labels:
    app.kubernetes.io/name: fluent-bit
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: fluent-bit
  template:
    metadata:
      labels:
        app.kubernetes.io/name: fluent-bit
    spec:
      serviceAccountName: fluent-bit
      tolerations:
      - operator: Exists
      containers:
      - name: fluent-bit
        image: cr.fluentbit.io/fluent/fluent-bit:3.1
        ports:
        - containerPort: 2020
          name: metrics
        resources:
          limits:
            memory: 128Mi
            cpu: 200m
          requests:
            memory: 64Mi
            cpu: 100m
        volumeMounts:
        - name: varlog
          mountPath: /var/log
          readOnly: true
        - name: containers
          mountPath: /var/lib/docker/containers
          readOnly: true
        - name: config
          mountPath: /fluent-bit/etc/
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: containers
        hostPath:
          path: /var/lib/docker/containers
      - name: config
        configMap:
          name: fluent-bit-config

ConfigMap con la configuración

apiVersion: v1
kind: ConfigMap
metadata:
  name: fluent-bit-config
  namespace: logging
data:
  fluent-bit.conf: |
    [SERVICE]
        Flush         5
        Log_Level     info
        Daemon        off
        Parsers_File  parsers.conf
        HTTP_Server   On
        HTTP_Listen   0.0.0.0
        HTTP_Port     2020

    [INPUT]
        Name              tail
        Tag               kube.*
        Path              /var/log/containers/*.log
        Parser            cri
        DB                /var/log/flb_kube.db
        Mem_Buf_Limit     10MB
        Skip_Long_Lines   On
        Refresh_Interval  10

    [FILTER]
        Name                kubernetes
        Match               kube.*
        Kube_URL            https://kubernetes.default.svc:443
        Kube_CA_File        /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        Kube_Token_File     /var/run/secrets/kubernetes.io/serviceaccount/token
        Kube_Tag_Prefix     kube.var.log.containers.
        Merge_Log           On
        Merge_Log_Key       log_processed
        Keep_Log            Off
        K8S-Logging.Parser  On
        K8S-Logging.Exclude On

    [OUTPUT]
        Name            es
        Match           kube.*
        Host            elasticsearch.logging.svc
        Port            9200
        Logstash_Format On
        Logstash_Prefix k8s-logs
        Retry_Limit     5
        Replace_Dots    On
        tls             On
        tls.verify      Off

  parsers.conf: |
    [PARSER]
        Name        cri
        Format      regex
        Regex       ^(?<time>[^ ]+) (?<stream>stdout|stderr) (?<logtag>[^ ]*) (?<message>.*)$
        Time_Key    time
        Time_Format %Y-%m-%dT%H:%M:%S.%L%z

    [PARSER]
        Name        json
        Format      json
        Time_Key    time
        Time_Format %Y-%m-%dT%H:%M:%S.%L

Routing a multiples destinos

Una de las funcionalidades mas útiles de Fluent Bit es enviar logs a distintos destinos segun el tag o contenido. Por ejemplo, enviar logs de aplicación a Elasticsearch para busqueda rápida y logs de infraestructura a S3 para archivado a bajo costo.

# Logs de aplicacion -> Elasticsearch
[OUTPUT]
    Name            es
    Match           kube.var.log.containers.app-*
    Host            elasticsearch.logging.svc
    Port            9200
    Logstash_Format On
    Logstash_Prefix app-logs

# Logs de infraestructura -> S3 (archivado)
[OUTPUT]
    Name            s3
    Match           kube.var.log.containers.infra-*
    region          us-east-1
    bucket          my-logs-archive
    total_file_size 50M
    upload_timeout  10m
    s3_key_format   /logs/$TAG/%Y/%m/%d/%H_%M_%S.gz
    compression     gzip

# Logs de seguridad -> CloudWatch
[OUTPUT]
    Name            cloudwatch_logs
    Match           kube.var.log.containers.auth-*
    region          us-east-1
    log_group_name  /k8s/security
    log_stream_prefix from-fluent-bit-
    auto_create_group On

# Todos los logs -> Loki (para correlacion con Grafana)
[OUTPUT]
    Name            loki
    Match           kube.*
    Host            loki.monitoring.svc
    Port            3100
    Labels          job=fluent-bit
    Auto_Kubernetes_Labels On

Despliegue con Helm

El chart oficial de Fluent Bit simplifica el despliegue y la gestión de configuraciones:

helm repo add fluent https://fluent.github.io/helm-charts
helm repo update

helm install fluent-bit fluent/fluent-bit \
  --namespace logging \
  --create-namespace \
  --set resources.limits.memory=128Mi \
  --set resources.limits.cpu=200m \
  --set resources.requests.memory=64Mi \
  --set resources.requests.cpu=100m \
  -f values-custom.yaml

Un archivo values-custom.yaml tipico para enviar logs a Elasticsearch:

config:
  service: |
    [SERVICE]
        Flush         5
        Log_Level     info
        HTTP_Server   On
        HTTP_Listen   0.0.0.0
        HTTP_Port     2020
        Parsers_File  /fluent-bit/etc/parsers.conf

  inputs: |
    [INPUT]
        Name              tail
        Tag               kube.*
        Path              /var/log/containers/*.log
        Parser            cri
        DB                /var/log/flb_kube.db
        Mem_Buf_Limit     10MB

  filters: |
    [FILTER]
        Name                kubernetes
        Match               kube.*
        Merge_Log           On
        Keep_Log            Off
        K8S-Logging.Parser  On

  outputs: |
    [OUTPUT]
        Name            es
        Match           *
        Host            elasticsearch.logging.svc
        Port            9200
        Logstash_Format On

tolerations:
  - operator: Exists

serviceMonitor:
  enabled: true

Tuning de rendimiento

Fluent Bit es eficiente por defecto, pero en clusters con alto volumen de logs (mas de 10,000 registros/segundo por nodo) se requieren ajustes:

Memoria y buffering

[SERVICE]
    Flush         5
    # Buffer en filesystem en lugar de memoria
    storage.path              /var/log/flb-storage/
    storage.sync              normal
    storage.checksum          off
    storage.backlog.mem_limit 10M

[INPUT]
    Name              tail
    Path              /var/log/containers/*.log
    # Limitar memoria por input
    Mem_Buf_Limit     15MB
    # Evitar lineas muy largas que consumen memoria
    Skip_Long_Lines   On
    # Buffer en filesystem
    storage.type      filesystem

Recomendaciones de rendimiento

  • Mem_Buf_Limit: define el máximo de memoria que cada input puede usar para buffering. Si se alcanza el límite, Fluent Bit pausa la lectura hasta que se libere espacio.
  • storage.path: habilita buffering en disco para evitar perdida de datos si el output esta temporalmente indisponible.
  • Flush interval: un valor de 1 segundo genera mas I/O de red pero menor latencia; 5-10 segundos reduce la carga en el backend.
  • Workers: para outputs que lo soporten, configura Workers 2 o mas para paralelizar los envios.
  • Skip_Long_Lines: evita que una linea de log anomalamente larga (por ejemplo, un stack trace de 100 KB) consuma toda la memoria del buffer.

Monitoreo de Fluent Bit

Fluent Bit expone métricas en formato Prometheus en el puerto configurado con HTTP_Server. Las métricas clave a monitorear:

# Registros procesados por input
fluentbit_input_records_total

# Bytes procesados por output
fluentbit_output_proc_bytes_total

# Errores en outputs (retries, drops)
fluentbit_output_errors_total

# Registros retenidos (backpressure)
fluentbit_output_retries_total

Configura alertas cuando fluentbit_output_errors_total crece sostenidamente o cuando fluentbit_output_retries_total aumenta, lo que indica que el backend de destino esta saturado o inaccesible.

Conclusion

Fluent Bit es la opción mas eficiente para recolectar y procesar logs en entornos de contenedores. Su bajo consumo de recursos, su pipeline flexible de inputs-parsers-filters-outputs, y su integración nativa con Kubernetes lo hacen ideal tanto para clusters pequeños como para despliegues a gran escala. La clave para una implementación exitosa esta en configurar correctamente el parsing segun el formato de logs de tus aplicaciones, definir routing inteligente a multiples destinos segun la criticidad de los logs, y monitorear el propio Fluent Bit para detectar problemas de backpressure antes de que resulten en perdida de datos.

Recursos