Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 77

Deploying Fluent Bit as a DaemonSet for Cluster-Wide Log Collection

Recommended resources

Hello! Welcome back to our module on the Kubernetes Ecosystem and Operations.

In our previous lesson, you successfully deployed a full Prometheus and Grafana stack, giving you powerful capabilities for metrics collection and visualization—the first pillar of observability. We saw how the Prometheus Operator and the ServiceMonitor CRD provide a declarative, Kubernetes-native way to manage monitoring.

This lesson builds directly on that foundation by tackling the second pillar of observability: logging. We will deploy Fluent Bit, a lightweight and high-performance log processor, to create a centralized logging pipeline for your entire cluster.

Our goal is to deploy Fluent Bit as a DaemonSet for cluster-wide log collection and forwarding. You will learn how it automatically discovers and collects logs from all your applications, enriches them with valuable Kubernetes metadata, and forwards them to a destination of your choice.

1. The Role of a Log Agent in Kubernetes

In a distributed system like Kubernetes, application logs are scattered across many nodes and containers. A log agent's job is to run on every node, collect these logs, process them, and ship them to a centralized logging backend (like Elasticsearch, Loki, or a cloud service like AWS CloudWatch Logs).

Fluent Bit is a CNCF-graduated project designed for this exact purpose. It's written in C, making it extremely lightweight and performant, which is critical for an agent that runs on every single node in your cluster.

Fluent Bit Log Collection Architecture in GKE with Splunk
This diagram illustrates the standard architecture for log collection in Kubernetes. Fluent Bit is deployed as a DaemonSet, ensuring an instance runs on each node. It collects logs from all pods on that node and forwards them to a centralized backend, in this case, Splunk.

To get a solid overview of Fluent Bit's architecture and its core components, the following video provides an excellent introduction.

Logging in Kubernetes | Fluent Bit | Observability | ADITYA JOSHI |

This video, "Logging in Kubernetes | Fluent Bit" by Aditya Joshi, clearly explains why logging is important in Kubernetes and breaks down the internal pipeline of Fluent Bit.

Please watch the following two segments: Introduction to Logging and Fluent Bit (00:00:00 - 00:01:46): This section covers the basics of logging in a distributed system and introduces Fluent Bit. Fluent Bit's Data Pipeline (00:02:23 - 00:04:04): This is a key section. Pay close attention to the explanation of the five stages: Input, Parser, Filter, Buffer, and Routing/Output. Understanding this pipeline is fundamental to configuring Fluent Bit effectively.

As you saw in the video, every log record flows through a configurable pipeline. This modular design allows you to tailor log processing to your specific needs.


2. The DaemonSet Deployment Model

Fluent Bit is almost always deployed as a DaemonSet in Kubernetes. This ensures that one Fluent Bit pod runs on every node in the cluster. This is the ideal model for a log agent because it needs access to the log files generated by containers on the node's local filesystem (typically located at /var/log/containers/*.log).

To function correctly, the Fluent Bit DaemonSet requires specific permissions:

  • Volume Mounts: It needs to mount host directories like /var/log to access container log files.
  • RBAC Permissions: It needs a ServiceAccount, ClusterRole, and ClusterRoleBinding to communicate with the Kubernetes API server. This allows it to fetch metadata about pods and nodes to enrich the logs—a process we'll explore in detail later.

The video you just watched begins to demonstrate a deployment using raw manifests. Let's watch the section that sets up these permissions and the main configuration.

Logging in Kubernetes | Fluent Bit | Observability | ADITYA JOSHI |

Continuing with the same video, let's see how the necessary RBAC resources and the core configuration (via a ConfigMap) are created.

Watch the segment from 00:04:04 to 00:13:14. Focus on understanding: Why a ServiceAccount, ClusterRole, and ClusterRoleBinding are necessary for Fluent Bit to get, list, and watch Kubernetes resources. How the ConfigMap is used to define the Fluent Bit pipeline configuration, including [INPUT], [PARSER], and [OUTPUT] sections. The configuration of the tail input plugin to read logs from /var/log/containers/*.log. The use of tags (kube.*) to route logs through the pipeline. The configuration of an elasticsearch output plugin as an example destination.


3. Deploying Fluent Bit with Helm

While applying raw manifests is a great way to understand the individual components, in a real-world scenario, you would use a Helm chart to manage the deployment. This aligns with the approach we took for the kube-prometheus-stack and makes managing configuration, upgrades, and dependencies much easier.

We will use the official Fluent Bit Helm chart to deploy our logging agent.

How to Set Up Centralized Logging in Kubernetes with Fluent Bit

The article "How to Set Up Centralized Logging in Kubernetes with Fluent Bit" from OneUptime provides a clear, production-oriented guide for deploying Fluent Bit using its Helm chart. We'll follow its steps.

Read the sections titled "Step 1: Install Fluent Bit with Helm" and "Step 4: Deploy Fluent Bit". Execute the commands to add the fluent Helm repository, create a logging namespace, and install the chart. We will create our own configuration in the next step, so for now, you can skip the creation of the values file and run the basic install command.

Here are the commands for your convenience:




# 1. Add the Fluent Bit Helm repository
helm repo add fluent https://fluent.github.io/helm-charts
helm repo update




# 2. Create a namespace for logging components
kubectl create namespace logging




# 3. Install the chart (we will configure it properly in a moment)
helm install fluent-bit fluent/fluent-bit --namespace logging

After installation, you can verify that the DaemonSet has scheduled a pod on each of your cluster's nodes:

kubectl get pods -n logging -l app.kubernetes.io/name=fluent-bit -o wide

4. Enriching Logs with the Kubernetes Filter

The single most powerful feature of Fluent Bit in a Kubernetes environment is its ability to enrich logs with metadata. A raw log line like Payment processed successfully is not very useful without knowing which application, which pod, and which container produced it.

This is where the Kubernetes Filter comes in. It automatically adds context like pod name, namespace, labels, and annotations to every log record.

Let's see a practical demonstration of its impact.

Logging in Kubernetes | Fluent Bit | Observability | ADITYA JOSHI |

Let's return to the Aditya Joshi video one last time. He does an excellent job of showing the difference in log quality before and after enabling the Kubernetes filter.

Watch the final demonstration from 00:21:45 to 00:25:05. Observe how adding the [FILTER] section for Kubernetes to the ConfigMap transforms the logs from simple messages into richly-detailed records containing kubernetes.pod_name, kubernetes.container_image, and other essential fields.


5. Creating a Production-Ready Configuration

Now, let's combine everything we've learned to create a robust configuration for Fluent Bit and apply it using Helm.

Create a file named fluent-bit-values.yaml. This file will tell the Helm chart how to configure the Fluent Bit DaemonSet and its associated resources.

fluent-bit-values.yaml




# Run on all nodes, including control plane
tolerations:
  - operator: Exists




# Configure the pipeline via a ConfigMap
config:



  # Define inputs, filters, and outputs
  inputs: |
    [INPUT]
        Name              tail
        Tag               kube.*
        Path              /var/log/containers/*.log
        Parser            cri
        DB                /var/log/flb_kube.db
        Mem_Buf_Limit     5MB
        Skip_Long_Lines   On
        Refresh_Interval  10

  filters: |
    [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
        Keep_Log            Off
        K8S-Logging.Parser  On
        K8S-Logging.Exclude On

    [FILTER]
        Name record_modifier
        Match *



        # Remove noisy and redundant fields
        Remove_key logtag
        Remove_key stream

  outputs: |
    [OUTPUT]
        Name   stdout
        Match  *




  # Define the parsers used in the input section
  parsers: |
    [PARSER]
        Name   cri
        Format regex
        Regex  ^(?<time>[^ ]+) (?<stream>stdout|stderr) (?<logtag>[^ ]*) (?<log>.*)$
        Time_Key time
        Time_Format %Y-%m-%dT%H:%M:%S.%L%z

Let's break down this configuration:

  • tolerations: Allows Fluent Bit to be scheduled on control-plane nodes, ensuring complete log coverage.
  • config.inputs: Uses the tail input to read all container logs. The cri parser is specified to handle the log format used by containerd.
  • config.filters:
    • The kubernetes filter enriches logs with metadata. Merge_Log On cleverly merges the actual log message into the top-level JSON object.
    • The record_modifier filter cleans up the output by removing redundant fields.
  • config.outputs: For this exercise, we use the stdout output, which simply prints the processed logs to the Fluent Bit pod's standard output. This is perfect for learning and debugging.

Now, apply this configuration using helm upgrade:

helm upgrade --install fluent-bit fluent/fluent-bit \
  --namespace logging \
  -f fluent-bit-values.yaml

To see the processed, enriched logs in real-time, you can tail the logs of one of the fluent-bit pods:




# Get the name of a fluent-bit pod
POD_NAME=$(kubectl get pods -n logging -l app.kubernetes.io/name=fluent-bit -o jsonpath='{.items[0].metadata.name}')




# Tail its logs
kubectl logs -n logging $POD_NAME -f

You will see a structured JSON output for every log line generated in your cluster, now enriched with Kubernetes context!


6. Forwarding to a Real Backend (Example: AWS CloudWatch)

The stdout output is great for testing, but in production, you'll forward logs to a durable backend. Fluent Bit's plugin architecture makes this a simple configuration change.

Given your strong AWS background, let's look at how you would configure Fluent Bit to send logs to Amazon CloudWatch. You don't need to implement this now, but it's important to see how the pattern works.

Integrate Fluent Bit into CloudWatch Container Insights for Amazon EKS | Amazon Web Services

The video "Integrate Fluent Bit into CloudWatch Container Insights" from AWS demonstrates this exact use case for an EKS cluster.

Watch the short segment from 00:01:22 to 00:03:02. This shows how to deploy a pre-configured Fluent Bit DaemonSet that forwards logs to CloudWatch. Notice that the core principle is the same: deploy a DaemonSet with the right permissions and configuration. The only major difference is the [OUTPUT] section of the ConfigMap is configured for CloudWatch instead of stdout.

This principle applies to any backend. To send logs to Loki, you would use the loki output plugin. For Elasticsearch, the es plugin. The pipeline structure remains the same, showcasing the power and flexibility of Fluent Bit.


Conclusion

Congratulations! You have now deployed a cluster-wide logging agent and configured a complete log processing pipeline. This is a fundamental capability for operating any production Kubernetes cluster.

Key Takeaways:

  • Fluent Bit is a lightweight, high-performance log processor ideal for Kubernetes.
  • It is deployed as a DaemonSet to ensure it runs on every node and can access local container log files.
  • The log processing pipeline consists of Inputs, Parsers, Filters, and Outputs, which are configured in a ConfigMap.
  • The kubernetes filter is essential for enriching logs with metadata (pod name, namespace, labels), making them searchable and useful.
  • Helm is the recommended tool for managing a Fluent Bit deployment, allowing you to manage its complex configuration declaratively.

What's Next?

So far, we have covered metrics (Prometheus) and logging (Fluent Bit). The third pillar of observability is tracing. In the next lesson, we will dive into this topic by exploring service meshes. You will learn to explain the purpose of a service mesh and deploy a simple application with Linkerd to observe traffic, giving you insight into request flows and latencies between your microservices.