You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
New feature (Calico Enterprise): the LogCollector controller now deploys fluent-bit (calico-fluent-bit in calico-system) in place of fluentd, completing the log-collector migration on the operator side.
Configuration is rendered in fluent-bit's YAML schema into per-OS ConfigMaps (calico-fluent-bit-conf/-windows), subPath-mounted on Linux and directory-mounted on Windows, started with -c. The render loads the Go plugins via plugins_file, defines parsers inline, applies the record-transform Lua filter, and inlines user-provided fluent-bit YAML filter lists. A rendered-config hash annotation rolls the pods on config-only changes.
Tail inputs use the producing components' real log paths, with SQLite offset DBs and filesystem buffering under /var/log/calico/calico-fluent-bit; a pos-migrator init container (Linux and Windows) seeds offsets from the legacy fluentd .pos files and pre-creates the tailed directories. Windows tails the same log types the fluentd Windows variant shipped.
The linseed output matches only Linseed-bound tags, authenticates with mTLS + the pod's ServiceAccount token, and retries without limit against bounded filesystem storage. S3/Splunk/Syslog outputs mirror fluentd's per-type fan-out (standard AWS credential env vars, endpoint scheme honored, syslog ships the whole record as JSON via a per-output Lua processor with TLS properly enabled).
NonClusterHost renders the :9880 HTTP input with client-certificate verification; the input Service is cleaned up when the resource is removed.
eks-log-forwarder runs the fluent-bit image with a rendered in_eks → linseed pipeline and health probes (no startup init container; the input plugin resolves its resume point from Linseed).
Probes hit :2020/api/v1/health; the ServiceMonitor scrapes plain HTTP (fluent-bit's monitoring server has no TLS) with access restricted by the component NetworkPolicy, and legacy fluentd monitors are deleted.
The LogCollector controller no longer creates/owns the calico-system namespace (deleting the LogCollector must not garbage-collect it); the deprecated fluentdDaemonSet override is honored as an alias of the new calicoFluentBitDaemonSet field (with container-name translation); legacy tigera-fluentd resources — the namespace last — are cleaned up idempotently.
Testing: render, controller, and monitor unit suites updated/extended (ConfigMap-content assertions replacing the env-var assertions); the rendered configuration was validated against the real fluent-bit binary; the full migration was validated end-to-end on a test cluster — all log types flowing to Linseed/Elasticsearch, fluentd resources fully removed, tail-offset handover without re-shipping, NonClusterHost ingestion with client-certificate enforcement, and EKS/Windows render shapes verified.
Release Note
The LogCollector now deploys fluent-bit (calico-fluent-bit in calico-system) in place of fluentd, with operator-rendered configuration and automatic migration of fluentd tail positions.
Breaking changes and behavior changes in this migration:
- The tigera-fluentd namespace is removed; all log-collector resources are renamed and move to calico-system (DaemonSet/container calico-fluent-bit, TLS secret calico-fluent-bit-tls). Tooling referencing the old names (e.g. kubectl logs -c fluentd) must be updated. The LogCollector fluentdDaemonSet override field is deprecated in favor of calicoFluentBitDaemonSet; existing overrides (including legacy container names) keep applying for one release.
- User flow/DNS log filters: the fluentd-filters ConfigMap is no longer read. Filters must be recreated under the new fluent-bit-filters name as fluent-bit YAML filter lists; unparseable content raises a TigeraStatus warning while log shipping continues.
- Log-collector metrics are now fluent-bit's native Prometheus metrics (fluentbit_* metric names, plain HTTP on port 2020 at /api/v2/metrics/prometheus, guarded by NetworkPolicy). Dashboards and alerts keyed on fluentd_* metric names or the 9081 mTLS endpoint must be updated.
- S3 archive object keys change from fluentd's flat layout (<bucketPath>/flows20260101_<n>.gz) to directory-style keys (<bucketPath>/flows/20260101_<uuid>.gz), with non-cluster-host flows archived under their own non_cluster_flows/ directory. Downstream tooling anchored to the old flat patterns needs a one-time update.
- Log buffering moves from fluentd's in-memory buffers to fluent-bit filesystem storage under /var/log/calico/calico-fluent-bit/ on each node: buffered-but-unsent chunks now survive pod restarts, and host disk usage grows accordingly (capped per output by storage.total_limit_size).
- The direct Elasticsearch log output is removed (Linseed is the sole structured-log sink), and the Splunk output no longer has an L7 log type (deployed fluentd never enabled it).
- Non-cluster hosts can now forward DNS logs in addition to flow and policy-activity logs.
For PR author
Tests for change.
If changing pkg/apis/, run make gen-files
If changing versions, run make gen-versions
For PR reviewers
A note for code reviewers - all pull requests must have the following:
Milestone set according to targeted release.
Appropriate labels:
kind/bug if this is a bugfix.
kind/enhancement if this is a a new feature.
enterprise if this PR applies to Calico Enterprise only.
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR completes the operator-side migration of the LogCollector from fluentd to fluent-bit (Calico Enterprise), including updated resource identities (namespace/workload names), rendered configuration shape, and updated policy/monitoring expectations across the rendering and controllers.
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 49 out of 50 changed files in this pull request and generated 1 comment.
Files not reviewed (1)
api/v1/zz_generated.deepcopy.go: Generated file
Comments suppressed due to low confidence (2)
pkg/controller/monitor/monitor_controller.go:156
Monitor no longer scrapes fluent-bit over mTLS (serviceMonitorFluentBit is plain HTTP), so the controller shouldn't watch or require the fluent-bit TLS secret. Keeping it here creates an unnecessary dependency on the LogCollector controller and can degrade Monitor reconciliation when LogCollector isn't installed (secret not found).
for _, secret := range []string{
certificatemanagement.CASecretName,
esmetrics.ElasticsearchMetricsServerTLSSecret,
monitor.PrometheusServerTLSSecretName,
render.FluentBitTLSSecretName,
render.NodePrometheusTLSServerSecret,
kubecontrollers.KubeControllerPrometheusTLSSecret,
render.EKSLogForwarderTLSSecretName,
} {
pkg/controller/monitor/monitor_controller.go:345
Since fluent-bit metrics scraping is now plain HTTP, Monitor's trusted bundle no longer needs the fluent-bit certificate. Including it makes reconciliation fail with NotFound if LogCollector hasn't created the secret yet (or isn't installed).
for _, certificateName := range []string{
esmetrics.ElasticsearchMetricsServerTLSSecret,
render.FluentBitTLSSecretName,
render.NodePrometheusTLSServerSecret,
render.CalicoAPIServerTLSSecretName,
kubecontrollers.KubeControllerPrometheusTLSSecret,
} {
…-6164)
Calico Enterprise removes the fluentd log collector in favour of Fluent Bit
(calico-fluent-bit in calico-system; tigera/operator#4910). Update the
next-version Calico Enterprise and Calico Cloud docs to match:
- Rewrite "Filter flow logs" / "Filter DNS logs": examples move from
fluentd <filter> syntax to Fluent Bit YAML filter lists, the ConfigMap
is renamed fluentd-filters -> fluent-bit-filters, and an upgrade note
explains that old fluentd-syntax filters are not translated (the
operator raises a tigera status warning naming the offending key).
- Metrics pages: Fluent Bit's built-in Prometheus endpoint (port 2020,
/api/v2/metrics/prometheus, fluentbit_* metrics); the fluentd
buffer-space alert becomes fluentbit_output_chunk_available_capacity_percent
plus a dropped-chunks alert on fluentbit_output_retries_failed_total.
- BYO Prometheus: the fluent-bit tab needs no client TLS (plain HTTP
behind the allow-calico-fluent-bit policy); ServiceMonitor sample is
fluent-bit-metrics-service-monitor.yaml.
- Sweep of remaining pages: tigera-fluentd namespace -> calico-system,
fluentd-node -> calico-fluent-bit (labels, secrets, packet capture
retrieval via calico-node, diags output, resource override examples now
use calicoFluentBitDaemonSet, architecture/overview descriptions,
cc-arch-diagram ports, operator checklist).
Not touched: versioned docs, releases.json (historical), and the generated
installation API reference (regenerates from the operator release).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The reason will be displayed to describe this comment to others. Learn more.
Done — the controller now watches the rendered calico-fluent-bit-conf, calico-fluent-bit-conf-windows and eks-log-forwarder-conf ConfigMaps in calico-system, so tampering (or deletion) triggers reconciliation and the operator restores the rendered content.
The reason will be displayed to describe this comment to others. Learn more.
I think we should extract out a component that renders out the resources that are shared between the linux and windows instances of this component. As I understand it, some resources are unique to the specific instance via OS naming convention.
However, some resources are not unique. This means that each instance of the component needs to compute the same definition of such resources, otherwise we have contention like you described. This pattern is confusing and seems like it could be the cause bugs in the future like the one you described
The reason will be displayed to describe this comment to others. Learn more.
Done — added logcollector.FluentBitShared, rendered exactly once per reconcile, owning everything that is not OS-specific: the allow-calico-fluent-bit NetworkPolicy, the GKE ResourceQuota, the S3/Splunk credential copies, the managed-cluster tigera-linseed Service/RoleBinding, the PacketCapture Role/Binding, and the legacy-fluentd cleanup. The per-OS components now render only their own metrics Service, conf ConfigMap, RBAC/SA, DaemonSet (+ EKS forwarder and the NCH input service on Linux). That removes the render-the-same-object-twice contention class outright — the Windows cfg no longer needs NonClusterHost at all, and there's a test asserting the Linux and Windows renders produce disjoint object sets.
The reason will be displayed to describe this comment to others. Learn more.
Yes — fluent-bit's syslog mode only accepts tcp/udp (TLS comes from the encryption field, which selects mode tls on top of tcp framing), and an http:// endpoint would have rendered a broken output. The controller now rejects non-tcp/udp schemes with a ResourceValidationError degraded status, with a test. (Same behavior fluentd had implicitly via SYSLOG_PROTOCOL.)
The reason will be displayed to describe this comment to others. Learn more.
All taken: renderFluentBitConf now leads the file and reads as service+parsers → addInputs → addFilters → addOutputs, and the Linseed output helpers moved into outputs.go with the store outputs.
The reason will be displayed to describe this comment to others. Learn more.
Not operator E2Es. The calico-private side has the container fv (fluent-bit/fv/container/, design verification step 3) which drops fixture log lines per type and asserts delivery against local S3/Splunk/Syslog mocks using the real fluent-bit binary and the same config shapes the operator renders. On the operator side the golden-config suite added in this PR pins the exact rendered YAML per scenario. There is no e2e against real S3/Splunk/Syslog endpoints today (that was true of fluentd too).
The reason will be displayed to describe this comment to others. Learn more.
I think we need a test suite that has the exact level of coverage provided by test.sh for the fluentd equivalent of this code, especially given that we are performing a migration here. My ideal would be to see that we have each case from test.sh represented as a test in this repo, with the expectation as a raw YAML file that has a comment showing the fluentd equivalent.
The reason will be displayed to describe this comment to others. Learn more.
Added golden_test.go + testdata/rendered-configs/: 17 goldens of the exact rendered config, byte-compared (UPDATE_RENDERED_CONFIGS=1 regenerates), each table entry naming its test.sh ancestor, reusing test.sh's endpoint/bucket/log-type values so the goldens read side-by-side with the fluentd .cfg files. The README maps all 20 test.sh cases: the six ES-era cases are n/a (ES output retired with fluentd per EV-6164), -nch cases map to hostScope NonClusterOnly, and the honest divergences are documented — the operator's Audit syslog type always enables both audit kinds (fluentd's env could do kube-only), the "all log types" case is capped at the CRD's legal enum (Audit;DNS;Flows;IDSEvents — the L7/runtime/WAF syslog envs were never operator-exposed), and the dual-scheme splunk case is split into splunk-http/splunk-https since the CRD takes one endpoint.
The reason will be displayed to describe this comment to others. Learn more.
Might be worth touching base with @caseydavenport on the steps taken in this PR to remove direct ES connections - just to make sure you are aligned with what he had in mind
The reason will be displayed to describe this comment to others. Learn more.
Will do — the ES retirement steps here follow the EV-6164 design (ES output dropped with fluentd, Linseed as sole structured-log sink). Casey, the specific surface in this PR: fluentd's ES env plumbing and the ElasticsearchEksLogForwarderUserSecret/cluster-config watches are removed from the LogCollector controller; nothing else touches ES.
The reason will be displayed to describe this comment to others. Learn more.
Claude says:
Bug: fluent-bit's S3 object keys don't match fluentd's, despite a code comment in outputs.go claiming the archive layout is "preserved."
fluentd (out-s3-flows.conf): used fluent-plugin-s3's default s3_object_key_format = %{path}%{time_slice}_%{index}… with path "flows" — path and date concatenated, no separator → key flows20260101_0.gz.
fluent-bit (outputs.go): s3_key_format = "/flows/%Y%m%d_$INDEX.gz" — a / inserted between flows and the date → key flows/20260101_0.gz.
Impact: the extra / turns flowsYYYYMMDD… into flows/YYYYMMDD…. Any downstream tooling globbing or parsing the old flat prefix silently reads nothing after upgrade — directly contradicting the comment that says the segments preserve the layout so "existing downstream consumers keep reading the same prefixes."
The reason will be displayed to describe this comment to others. Learn more.
Good catch that the layout differed while the comment claimed parity. After weighing exact-parity against fluent-bit's directory-style keys, we're keeping the directory layout as a deliberate, release-noted change rather than inheriting fluentd's flat concatenation: keys are now <bucketPath>/<type>/%Y%m%d_<uuid>.gz (one directory per log type, non-cluster flows in their own non_cluster_flows/ directory instead of being mixed into flows/). Rationale: full parity was impossible anyway — the _<index> suffix had to become $UUID because out_s3 tracks its index in a store_dir that doesn't survive pod restarts, so a restarted pod would silently overwrite same-day objects (fluent-plugin-s3 avoided this by checking object existence, which out_s3 doesn't) — and given a documented break either way, the directory layout is materially better for the S3 console, lifecycle tooling and Athena/Glue partitioning. Prefix filters (<bucketPath>/flows) keep matching under both layouts; only patterns anchored to the flat form (flows2026*) need a one-time update, which the release note calls out. The code comment now states the break explicitly, and the goldens show the exact keys per scenario.
The reason will be displayed to describe this comment to others. Learn more.
Claude says:
Bug: the fluent-bit :9880 HTTP input — which receives non-cluster-host logs relayed by voltron — omits the body-size limit fluentd's HTTP source had, so large POSTs are silently rejected/truncated.
fluentd (fluent_sources.conf, port 9880): body_size_limit 100m.
fluent-bit (config.go, [INPUT] Name http port 9880): no size set → inherits in_http's much smaller default buffer_max_size (~4M).
Impact: a voltron-relayed non-cluster-host batch larger than ~4M is rejected → those flow/DNS/policy-activity records silently never reach Linseed. Nothing in the CRD or operator surfaces an error.
Fix: set buffer_max_size 100M (and a matching buffer_chunk_size) on the input.
The reason will be displayed to describe this comment to others. Learn more.
Confirmed and fixed — fluentd's :9880 source had body_size_limit 100m; the fluent-bit input now sets buffer_max_size 100M (plus buffer_chunk_size 5M so a full-size relayed batch doesn't grow 512K at a time), with a render test asserting both.
The reason will be displayed to describe this comment to others. Learn more.
I know this wasn't there before, but you might want to add a daemonset watch to trigger re reconciliation if the daemonset was removed. This is missing in a lot of places currently.
The reason will be displayed to describe this comment to others. Learn more.
It seems like, and I might be wrong, that this is all in service of just the config and every function that's called in this chain has nothing to do with rendering (which the component represents).
If this is true, consider attaching all the methods to the FluentBitConfiguration, or reversing the relationship so it's all attached to the fluendBitConfig struct and you pass the specific config options from the FluentBitConfiguration that pertain just to fluentd configuration.
This would be in further service of separating fluentd specific configuration (which is complex) from the component rendering.
The reason will be displayed to describe this comment to others. Learn more.
I'm imagining (please correct me if I'm wrong) that this just needs to be done once. If that's true, are we able to detect if we've already done the migration and not attach the init container?
I'm thinking that if we can skip this init container it's one less thing in the way of getting fluentd starting up. Might not be a huge deal in prod, but cutting out time to setup in the CI would be helpful.
Replace the fluentd DaemonSet with fluent-bit for log collection and
forwarding. The LogCollector controller now renders the calico-fluent-bit
DaemonSet (Linux and Windows) in calico-system, and pkg/render/fluentd.go is
replaced by fluentbit.go.
- Ship fluent-bit logs to Linseed through its built-in http output.
- Rename the FluentdDaemonSet* API types to FluentBitDaemonSet*
(fluentd_daemonset_types.go -> fluentbit_daemonset_types.go). Preserve the
deprecated fluentdDaemonSet override field name/json tag as an alias and
widen its enums to accept both the new calico-fluent-bit* names and the
legacy fluentd names so existing LogCollector specs still validate;
translateLegacyFluentdOverrides remaps the legacy names.
- Warn on invalid fluent-bit-filters ConfigMap content (e.g. left in fluentd
<filter> syntax) instead of silently dropping it.
- Drop the bogus "calico-fluent-bit" entry from the manager cluster-wide
namespace list; fluent-bit runs in calico-system, which is already listed.
- Regenerate deepcopy, the operator CRD and enterprise versions.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Jiawei Huang <jiawei@tigera.io>
Forward flow, DNS and policy-activity logs from non-cluster hosts through
voltron to the in-cluster calico-fluent-bit http input, and on to Linseed.
- Grant dnslogs (alongside flowlogs and policyactivity) on the
non-cluster-host ClusterRole so the minted host token passes voltron's
SubjectAccessReview for the DNS ingestion path instead of 403ing.
- Set VOLTRON_LOG_COLLECTOR_CA_BUNDLE_PATH on the manager so voltron verifies
the calico-fluent-bit http input's TLS server certificate against the
trusted CA bundle it already mounts (the config default
/etc/pki/tls/certs/ca.crt is not mounted, so the handshake otherwise fails).
- Pass NonClusterHost to the Windows fluent-bit configuration so the Linux
and Windows renders produce the shared allow-calico-fluent-bit NetworkPolicy
identically. Otherwise, on clusters with Windows nodes, the port-9880
ingress rule (voltron -> http input) flapped on every reconcile and
intermittently dropped voltron's access. Adds a controller regression test.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Jiawei Huang <jiawei@tigera.io>
pkg/render/fluentbit.go had grown to ~1900 lines. Move the fluent-bit /
EKS log-forwarder rendering into a new pkg/render/logcollector package,
split across focused files (logcollector core, config, outputs, daemonset,
rbac, networkpolicy, eks_log_forwarder) plus the moved tests.
A small set of symbols stays in package render (new pkg/render/logcollector.go)
to avoid a render -> render/logcollector import cycle, since Guardian, Manager,
compliance, apiserver, dex and intrusion detection reference them: the
log-collector network-policy identity (FluentBitSourceEntityRule,
EKSLogForwarderEntityRule, LogCollectorNamespace, the fluent-bit node names,
FluentBitInputService), the shared Linseed-token constants, and the
TrustedBundleVolume helper. The logcollector package aliases these. The shared
pod helper setNodeCriticalPod is exported as SetNodeCriticalPod (matching its
sibling SetClusterCriticalPod).
Pure code move; no behavior change. Build, vet, unit tests, format-check and
gen-files all pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Jiawei Huang <jiawei@tigera.io>
…t cert coupling
Live validation surfaced that every fluent-bit Prometheus target was down
with scrape timeouts: the calico-system.prometheus egress policy still
allowed only the fluentd-era metrics port 9081 (which stays — it is also
the elasticsearch-metrics port) and was never taught fluent-bit's 2020.
Add the egress rule and update the policy fixtures. Verified end-to-end
on a GCP kubeadm cluster: targets went from 0 up / 6 down to all up.
Since the fluent-bit metrics endpoint is scraped over plain HTTP, the
monitor controller has no use for the fluent-bit certificate: drop it
from Prometheus's trusted bundle and remove the fluent-bit and
EKS-log-forwarder secret watches (the latter was dead even in the
fluentd era — never in the bundle), decoupling the monitor controller
from the LogCollector controller entirely. Linseed's trust of the
fluent-bit client certificate (logstorage secrets controller) is
unchanged — that hop is real mTLS.
Also use the ServiceMonitor name constant in the watch error message
(review feedback) and refresh serviceMonitorFluentBit's godoc, which
still explained a TLS-era rationale.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…EKS RBAC
Legacy overrides (review: the container rename is a breaking change):
route the deprecated fluentdDaemonSet field through the shared
containerNameAliases mechanism in pkg/render/common/components instead
of a bespoke translation, mapping the fluentd-era container and
init-container names to their calico-fluent-bit equivalents, and add
render tests for the alias path and for calicoFluentBitDaemonSet
precedence when both fields are set.
EKS forwarder RBAC: the legacy-cleanup list deleted the cluster-scoped
eks-log-forwarder ClusterRoleBinding that the EKS render re-creates
under the same (fluentd-era) name; creates are processed before deletes,
so on EKS clusters every reconcile deleted the forwarder's Linseed RBAC.
The binding is reused in place, so drop it from the cleanup list (and
add the missed fluentd-node-windows Linseed token secret).
Additional-store parity with fluentd (verified against ee_entrypoint.sh,
syslog-config.sh, splunk-config.sh and the out-s3-*.conf templates):
- hostScope gates only cluster *flow* logs for all three stores, and
non-cluster flows always ship when a store is enabled; the previous
render dropped every cluster type but NCH flows under NonClusterOnly
and never shipped NCH flows under All.
- S3: preserve the legacy archive prefixes (audit_tsee, ...), gzip the
objects to match their .gz suffix (fluent-plugin-s3's default
store_as), and drop waf, which the entrypoint never archived. NCH
flows get their own non_cluster_flows/ prefix — out_s3's $INDEX is
per-output, so sharing flows/ would overwrite objects.
- syslog: drop syslog_severity_preset "info" — the property is an
integer (atoi("info") = 0 = Emergency) and the default 6 already is
info — and add syslog_hostname_preset ${NODENAME} as the node-name
fallback for tags whose records carry no host key, matching fluentd's
static SYSLOG_HOSTNAME.
- parse audit.* and ids.events event time (time_key) like the fluentd
sources did, so S3 day partitions and syslog timestamps use event
time. Rendered configs (default and all-stores) validated with the
real fluent-bit image via --dry-run.
Windows: pass Tenant/ExternalElastic into the Windows render so the
shared allow-calico-fluent-bit policy cannot flap on multi-tenant
management clusters with Windows nodes, and the Windows Linseed outputs
target the right namespace and tenant header.
Cleanup: remove the ES-era ElasticsearchEksLogForwarderUserSecret and
cluster-config watches (nothing reads them since the ES output was
dropped) and the unused /etc/fluent-bit/certs trusted-bundle mounts.
Add a controller test for the fluent-bit-filters warning path
(SetWarning on unparseable content, cleared once fixed, rendering
continues) and tighten the store-output render assertions.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…oller
Shared component (review): the resources both OS renders previously
duplicated — the allow-calico-fluent-bit NetworkPolicy, GKE
ResourceQuota, S3/Splunk credential copies, managed-cluster
tigera-linseed Service/RoleBinding, PacketCapture RBAC and the legacy
cleanup — move into a FluentBitShared component rendered exactly once
per reconcile, removing the duplicate-render contention class. The
Windows configuration no longer carries NonClusterHost at all.
Legacy cleanup: rewritten to the namespace-cascade pattern used for the
guardian/apiserver/policy-recommendation migrations — delete the
tigera-fluentd Namespace plus the cluster-scoped ClusterRole/Bindings
and the operator-namespace copy of tigera-fluentd-prometheus-tls.
Never-in-production entries (the allow-tigera-prefixed policy name and
the calico-system copy of the filters ConfigMap) are dropped.
DaemonSet: startup/liveness probes move to /api/v1/uptime so sustained
delivery errors cannot restart pods and drop in-memory buffers
(readiness keeps the error-aware /api/v1/health);
terminationGracePeriodSeconds 0 → 30 (grace 0 assumed the pos file made
buffers durable, which was never true); pos-migrator init container
unified across OS variants.
Outputs/config: S3 keys switch to directory-style
<bucketPath>/<type>/%Y%m%d_$UUID.gz — a deliberate, release-noted
layout change from fluentd's flat concatenation (full parity was
impossible anyway: out_s3's $INDEX is not restart-safe, so the suffix
had to become a UUID) — with non-cluster flows in their own directory;
the :9880 http input gains buffer_max_size 100M / buffer_chunk_size 5M
(fluentd's body_size_limit parity — the ~4M default silently rejected
larger relayed non-cluster-host batches); splunk drops l7, which
deployed fluentd never enabled; renderFluentBitConf now reads as
inputs → filters → outputs with the Linseed helpers moved next to the
store outputs; buffer-durability comments corrected (fluentd buffered
in memory only).
Controller: the rendered fluent-bit ConfigMaps are watched so tampering
triggers reconciliation, and syslog endpoints are validated to tcp/udp
schemes (fluent-bit's syslog mode accepts nothing else; TLS comes from
the encryption field).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Review ask: represent each case from fluentd's config test harness
(calico-private fluentd/test/test.sh) in this repo, with the
expectation as a raw file mapped to its fluentd equivalent.
TestRenderedConfigGoldens pins the full rendered fluent-bit config for
17 scenarios byte-for-byte under testdata/rendered-configs/, each table
entry naming its test.sh ancestor and reusing test.sh's endpoint,
bucket and log-type values so a golden reads side-by-side with its
fluentd .cfg counterpart. The README maps all 20 test.sh cases: the six
ES-era cases are n/a (the Elasticsearch output was retired with fluentd
per EV-6164), -nch cases map to hostScope NonClusterOnly, and the
divergences that cannot be mirrored are documented (the Audit syslog
type always enables both audit kinds, the CRD never exposed the
L7/runtime/WAF syslog toggles, and the dual-scheme splunk case splits
into splunk-http/splunk-https). UPDATE_RENDERED_CONFIGS=1 regenerates.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Remove the never-in-production calico-fluent-bit-metrics PodMonitor
from the monitor toDelete list (the pre-v1.25 PodMonitor was named
fluentd-metrics; the fluent-bit name never shipped) and simplify the
ServiceMonitor comment that duplicated the function godoc.
Drop the fluent-bit and eks-log-forwarder ingress rules from the
es-gateway policy: both components ship only to Linseed in every
topology (managed clusters use the tigera-linseed ExternalService via
Guardian, never tigera-secure-es-gateway-http), so the rules were
relics of fluentd's direct-Elasticsearch path. The equivalent source
rules on the Linseed policy are the live path and remain.
Remove an author-focused rationale comment from the tiers controller.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
New feature (Calico Enterprise): the LogCollector controller now deploys fluent-bit (
calico-fluent-bitincalico-system) in place of fluentd, completing the log-collector migration on the operator side.tigera-fluentd→calico-system; DaemonSet/ServiceAccountfluentd-node→calico-fluent-bit; TLS secret →calico-fluent-bit-tls; metrics port 9081 → 2020 (fluent-bit's built-in HTTP server).calico-fluent-bit-conf/-windows), subPath-mounted on Linux and directory-mounted on Windows, started with-c. The render loads the Go plugins viaplugins_file, defines parsers inline, applies the record-transform Lua filter, and inlines user-provided fluent-bit YAML filter lists. A rendered-config hash annotation rolls the pods on config-only changes./var/log/calico/calico-fluent-bit; apos-migratorinit container (Linux and Windows) seeds offsets from the legacy fluentd.posfiles and pre-creates the tailed directories. Windows tails the same log types the fluentd Windows variant shipped.:9880HTTP input with client-certificate verification; the input Service is cleaned up when the resource is removed.eks-log-forwarderruns the fluent-bit image with a renderedin_eks→linseedpipeline and health probes (no startup init container; the input plugin resolves its resume point from Linseed).:2020/api/v1/health; the ServiceMonitor scrapes plain HTTP (fluent-bit's monitoring server has no TLS) with access restricted by the component NetworkPolicy, and legacy fluentd monitors are deleted.calico-systemnamespace (deleting the LogCollector must not garbage-collect it); the deprecatedfluentdDaemonSetoverride is honored as an alias of the newcalicoFluentBitDaemonSetfield (with container-name translation); legacytigera-fluentdresources — the namespace last — are cleaned up idempotently.Testing: render, controller, and monitor unit suites updated/extended (ConfigMap-content assertions replacing the env-var assertions); the rendered configuration was validated against the real fluent-bit binary; the full migration was validated end-to-end on a test cluster — all log types flowing to Linseed/Elasticsearch, fluentd resources fully removed, tail-offset handover without re-shipping, NonClusterHost ingestion with client-certificate enforcement, and EKS/Windows render shapes verified.
Release Note
For PR author
make gen-filesmake gen-versionsFor PR reviewers
A note for code reviewers - all pull requests must have the following:
kind/bugif this is a bugfix.kind/enhancementif this is a a new feature.enterpriseif this PR applies to Calico Enterprise only.