Fluent Operator turns logging pipelines into Kubernetes objects
Operate Fluent Bit and Fluentd in the Kubernetes way - Previously known as FluentBit Operator
At a glance
- What is it?
- Fluent Operator is the Kubernetes operator for Fluent Bit and Fluentd, and its core idea is that a log pipeline should be described with custom resources and label selectors rather than hand-written config files. It defines twelve Fluent Bit CRDs and a matching set for Fluentd, and it solves the reload problem with a wrapper process that restarts Fluent Bit when its config changes.
- Who is it for?
- Adopt Fluent Operator if you run Fluent Bit or Fluentd on Kubernetes and want log pipelines expressed as version-controlled custom resources instead of ConfigMaps that drift from the cluster. Skip it if you have a handful of nodes and one log destination, since a DaemonSet with a mounted ConfigMap does that job, and if you cannot use the custom images, since the dynamic reload feature depends on them.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Three deployment modes, and the operator covers all of them
Fluent Operator provides great flexibility in building a logging layer based on Fluent Bit and Fluentd, and the flexibility starts with a decision the documentation spells out in three lines.
The framing is that although both Fluent Bit and Fluentd can collect, process, meaning parse and filter, and then forward logs to the final destinations, they have strengths in different aspects. Fluent Bit is a good choice as a logging agent because of its lightweight and efficiency, while Fluentd is more powerful for advanced processing on logs because of its rich plugins.
From that, the three modes. Fluent Bit only mode is for when you just need to collect logs and send them to the final destinations. Fluent Bit plus Fluentd mode is for when you also need to perform some advanced processing on the collected logs or send to more sinks. Fluentd only mode is for when you need to receive logs over the network, through HTTP or Syslog, and then process and send them to the final sinks.
The operator includes CRDs and controllers for both Fluent Bit and Fluentd, so you can configure your log processing pipelines in any of those three modes as you wish. The deployment shapes differ too: Fluent Bit goes out as a DaemonSet and Fluentd as a StatefulSet, and the components are pluggable, so either can be deployed separately.
That last point matters for a common migration. Plenty of teams start with Fluent Bit alone and add Fluentd later when a sink needs transformation, and the operator is built so that the second half can be added without reworking the first.
The project is Go, Apache-2.0 licensed, and was previously known as the FluentBit Operator. The last push was on 2026-10-15 and the releases are v3.10.1 from 2026-09-21, v3.10.0 from 2026-08-17 and v3.9.0 from 2026-06-09.
Thirteen CRDs for Fluent Bit, each one a config section
The Fluent Bit side is where most of the API surface lives, and the list of custom resources is the clearest description of the design.
`FluentBit` defines the Fluent Bit DaemonSet and its configs. `ClusterFluentBitConfig` selects cluster-level input, filter and output plugins and generates the final config into a Secret. `FluentBitConfig` selects namespace-level filter, output and parser plus cluster-level parser plugins and also generates the final config into a Secret.
Then the individual section types. `ClusterInput` defines cluster-level input config sections. `Parser` and `ClusterParser` define namespace-level and cluster-level parser config sections. `MultilineParser` and `ClusterMultilineParser` do the same for multiline parsers. `Filter` and `ClusterFilter` for filters. `Output` and `ClusterOutput` for outputs.
The naming pattern carries the whole model. The Cluster-prefixed resources are cluster-scoped and the unprefixed ones are namespace-scoped, and each pair represents the same kind of configuration section at two levels of scope. That is the mechanism behind multi-tenant log isolation, since a namespace owner can define their own filter and output without touching the cluster-wide ones.
How the pieces meet is described precisely. Each of the cluster-level input, parser, filter, multiline parser and output represents a Fluent Bit config section, and those are selected by `ClusterFluentBitConfig` through label selectors. The operator watches those objects, constructs the final config, and finally creates a Secret to store the config, which is mounted into the Fluent Bit DaemonSet.
So the composition is label-based rather than a nested structure. A `ClusterFluentBitConfig` names a label, and every cluster output carrying that label is folded into the generated config. Adding a sink is a matter of labelling an object, and a Fluent Bit config section that is not labelled is simply not in the output.
Dynamic reloading works by restarting the process from a wrapper
The reload story is the part of the design that looks odd until you read the reason, and the reason is a known limitation in Fluent Bit itself.
To enable Fluent Bit to pick up and use the latest config whenever it changes, a wrapper called the Fluent Bit watcher is added to restart the Fluent Bit process as soon as a config change is detected. The Fluent Bit pod need not be restarted to reload the new config, and the config is reloaded this way because there is no reloading interface in Fluent Bit itself. The documentation points at the upstream issue for the detail.
So the dynamic reload feature is a process supervisor inside the pod. The operator writes a new Secret, the watcher sees the file change, and it restarts the collector process so the new configuration is picked up. The pod survives, the process does not, and the difference matters because a pod restart is a scheduling event while a process restart is not.
That mechanism has a hard prerequisite, and it is stated in the CRD description. A custom Fluent Bit image, `ghcr.io/fluent/fluent-operator/fluent-bit`, is required to work with the FluentBit Operator for dynamic configuration reloading. The Fluentd side has the mirror of the same requirement, with a custom Fluentd image at `kubesphere/fluentd` required for the Fluentd Operator's dynamic configuration reloading.
The dependency list in the project file shows the watcher is a separate program rather than a library, since there is a cmd/ directory in the tree and the makefile derives the image tags from version files under cmd/fluent-watcher for the fluentbit and fluentd subtrees. The watcher is therefore versioned independently of the operator itself, which is why the makefile reads a separate version for each.
If you cannot use the custom images, you lose dynamic reloading and fall back to a pod restart when the configuration changes, which is exactly the behaviour the operator is trying to avoid.
The Fluentd side adds multi-tenant isolation
The Fluentd CRDs follow the same pattern as the Fluent Bit ones, with the addition that matters for a shared cluster.
`Fluentd` defines the Fluentd StatefulSet and its configs, again with the custom image requirement for dynamic reloading. The rest of the resources mirror the Fluent Bit structure, with namespace-level and cluster-level config sections for the plugin types Fluentd supports.
The feature that distinguishes the Fluentd side is multi-tenant log isolation, which the feature list calls out explicitly. Fluentd supports it through the label-router plugin, and the documentation links that plugin directly.
That is the point of the label-router. A shared logging backend collecting logs from many namespaces is a compliance problem unless each tenant's logs are separated, and a router that filters by Kubernetes label is the mechanism. The operator's own model of label-based selection is what makes this possible, because the same labels that select a config section also identify the tenant the log belongs to.
The Fluentd and Fluent Bit resources are also independently deployable, which is what the pluggable deployment components feature means. You can run the Fluent Bit operator resources without any Fluentd resources at all, and the two never need to know about each other beyond the shared Secret contract.
The project is a controller-runtime operator on a recent Kubernetes
The go.mod file shows what kind of codebase this is, and the dependency versions place it in time.
The module is `github.com/fluent/fluent-operator/v3`, on Go 1.26.6, and the Kubernetes libraries are recent: k8s.io/api, k8s.io/apimachinery and k8s.io/client-go all at 0.37.1, with controller-runtime at 0.25.1.
The rest of the direct dependencies are the ones an operator needs and nothing else. fsnotify for watching files, which is how the config watcher notices a Secret change, go-kit/log and go-logr/logr for the two logging interfaces in play, godotenv for loading environment files at development time, oklog/run for the group-of-processes pattern that operators use to run several controllers in one binary, ginkgo and gomega for the test framework, and go-openapi/errors, sigs.k8s.io/yaml and golang.org/x/sync.
The absence of any HTTP client, database driver or message queue library is the point. An operator talks to the API server and watches the cache, and everything else comes from the client-go libraries.
The repository layout follows the standard operator shape. There is an apis/ directory for the custom resource types, controllers/ for the reconcile loops, cmd/ for the manager binary and the watcher, pkg/ for shared code, charts/ for the Helm chart, manifests/ for the raw YAML, config/ and conf/ for the configuration, plus hack/, tests/, docs/ and a .devcontainer/ directory for local development.
The makefile shows how the images are built and versioned, and it is worth noting the shape of the image naming. The operator image, the Fluent Bit image and the Fluentd image are three separate artifacts with three separate version variables, and the operator SDK version used for the CRD tooling is pinned as well.
Best practice documentation covers grouping, monitoring and custom parsers
The documentation has a best practice section, and its contents are a good indication of what operators struggle with in practice.
Plugin grouping is the first topic, which follows from the label-based model. Because every config section is selected by a label, how you group your inputs, filters and outputs into labels is what determines the shape of the generated config, and getting that wrong produces a config you cannot reason about.
Monitoring is the second. An operator that manages the log path for a whole cluster needs its own observability, since the logging system failing silently is the worst possible outcome.
Custom parser is the third, and it is the one that shows the parser resources earning their place. The `Parser` and `ClusterParser` resources let you define parsing rules as objects rather than as embedded config text, which is what makes a multiline or structured log format manageable when the same rule applies to many namespaces.
Then there is Misc and Custom Plugin, and the custom plugin item is the interesting one. Because the config sections are modelled as resources with a plugin type and a config string, adding a plugin that the operator does not know about is a matter of using the generic mechanism rather than asking the operator to be extended.
The rest of the project documentation covers the walkthroughs for collecting Kubernetes logs and audit logs, each with a YAML route and a Helm route, and the plugins sections for both Fluent Bit and Fluentd. The roadmap, the development requirements, the contribution guide and the manifests documentation are all present, and the community section points at a Slack channel with 600 or more members, which is the scale indicator for an operator that has been adopted widely.
Editorial conclusion
Adopt Fluent Operator if you run Fluent Bit or Fluentd on Kubernetes and want log pipelines expressed as version-controlled custom resources instead of ConfigMaps that drift from the cluster. Skip it if you have a handful of nodes and one log destination, since a DaemonSet with a mounted ConfigMap does that job, and if you cannot use the custom images, since the dynamic reload feature depends on them. Verify first which of the three deployment modes you need, that the Fluent Bit and Fluentd versions you use are supported by the operator release you pick, and that your cluster has the labels your plugin selection relies on, because the whole configuration model is built on label selectors.
Frequently asked questions
What is Fluent Operator and what does it manage?
It is a Kubernetes operator that manages Fluent Bit and Fluentd. Fluent Bit is deployed as a DaemonSet and Fluentd as a StatefulSet, and you can deploy either one separately. It provides deployment and destruction, plugin selection through labels, dynamic configuration reloading, and multi-tenant log isolation for Fluentd through the label-router plugin.
Which deployment modes does Fluent Operator support?
Three. Fluent Bit only, for collecting and forwarding logs. Fluent Bit plus Fluentd, when you also need advanced processing or more sinks. And Fluentd only, when you receive logs over the network through HTTP or Syslog and then process and forward them. The operator includes CRDs and controllers for both, so any of the three can be configured.
How does Fluent Operator reload Fluent Bit configuration without restarting the pod?
It adds a wrapper called the Fluent Bit watcher that restarts the Fluent Bit process as soon as a config change is detected, because there is no reloading interface in Fluent Bit itself. This requires the custom Fluent Bit image at ghcr.io/fluent/fluent-operator/fluent-bit, and the Fluentd side has the same requirement with a custom Fluentd image.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/fluent-fluent-operator)Was this useful?