June 2026
This document describes how to deploy and configure Fluent Bit as the log forwarding agent on a VKS guest cluster, shipping logs to VCF Operations for Logs over HTTPS.
Unlike the Supervisor cluster — which ships a managed Fluent Bit DaemonSet that operators can only partially configure — a VKS guest cluster gives full control over the logging stack. Fluent Bit is installed as a package from the VKS Standard Packages bundle using the VCF CLI package manager. This approach is consistent with how other platform add-ons (Cilium, Prometheus, cert-manager) are deployed on VKS, and it supports the full Fluent Bit configuration surface: inputs, parsers, filters, and outputs are all defined in a data values file before installation.
Four log streams are collected from the cluster:
| Stream | Source | Tag | Description |
|---|---|---|---|
| Container logs | /var/log/containers/*.log |
kube.* |
All pod stdout/stderr across every namespace |
| Systemd daemon logs | /var/log/journal |
kube_systemd.* |
kubelet and containerd service logs from the systemd journal |
| API server audit logs | /var/log/kubernetes/kube-apiserver.log |
apiserver_audit.* |
Kubernetes API audit trail in audit.k8s.io/v1 JSON
format |
| Linux auth logs | /var/log/audit/audit.log |
auth.* |
Node-level authentication and authorisation events from the Linux audit daemon |
All four streams are forwarded in a single HTTP output to VCF Operations for Logs, enriched with structured metadata fields for filtering and search.
Prerequisite: The VKS Standard Packages bundle must already be accessible — either from the public Broadcom registry or from a local Harbor mirror. Follow the air-gapped setup guide before proceeding if the cluster has no direct internet access.
The procedures and configurations in this document were validated against the following platform versions:
| Component | Version |
|---|---|
| VMware Cloud Foundation | 9.0.2.0 |
| Supervisor | v1.32.9+vmware.2-fips.vsc9.0.2.0100-25262241 |
| vSphere Kubernetes Service | 3.6.0+v1.35 |
| Kubernetes Release | v1.35.2+vmware.1-vkr.3 |
| Fluent Bit Package | 4.2.3+vmware.1-vks.1 |
| VCF Operations for Logs | 8.x (API v2) |
Fluent Bit runs as a DaemonSet — one pod per cluster node — and reads
log files directly from the node’s filesystem via hostPath
mounts. All pods write to the same VCF Operations for Logs HTTPS
endpoint.
┌────────────────────────────────────────────────────────────────────┐
│ VKS Guest Cluster: dev-cluster-04 │
│ │
│ Node 1..N │
│ /var/log/containers/*.log ◄── pod stdout / stderr │
│ /var/log/journal ◄── kubelet, containerd │
│ /var/log/kubernetes/kube-apiserver.log ◄── API audit trail │
│ /var/log/audit/audit.log ◄── Linux audit daemon │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ vks-system-logging │ │
│ │ │ │
│ │ fluent-bit (DaemonSet, one pod per node) │ │
│ │ │ │ │
│ │ ├─ INPUT tail kube.* (CRI parser) │ │
│ │ ├─ INPUT systemd kube_systemd.* (kubelet+containerd)│ │
│ │ ├─ INPUT tail apiserver_audit.* (JSON parser) │ │
│ │ ├─ INPUT tail auth.* (authlog parser) │ │
│ │ │ │ │
│ │ ├─ FILTER record_modifier (add vks_cluster, environment) │ │
│ │ ├─ FILTER kubernetes (enrich kube.* with K8s meta) │ │
│ │ ├─ FILTER nest/lift (flatten kubernetes object) │ │
│ │ ├─ FILTER modify (add per-stream text label) │ │
│ │ │ │ │
│ │ └─ OUTPUT http (TLS, JSON, match *) │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │ │
└─────────────┼──────────────────────────────────────────────────────┘
│ HTTPS POST :9543/api/v2/events
▼
┌─────────────────────────────────────────┐
│ VCF Operations for Logs │
│ 192.168.200.40:9543 │
└─────────────────────────────────────────┘
package plugin
available9543Set the following environment variables before running any commands:
export CLUSTER_NAMESPACE='lab-poc-namespace-dev'
export CLUSTER_NAME='dev-cluster-04'
export SUPERVISOR_IP='10.77.68.3'
export VCF_CLI_VSPHERE_USERNAME='administrator@vsphere.local'
export VCF_CLI_VSPHERE_PASSWORD='<password>'Create a VCF CLI context that points directly to the VKS guest cluster. This context connects through the Supervisor API endpoint and targets the specific workload cluster by namespace and name.
vcf context delete ${CLUSTER_NAME} -y
vcf context create ${CLUSTER_NAME} \
--endpoint ${SUPERVISOR_IP} \
--username ${VCF_CLI_VSPHERE_USERNAME} \
--workload-cluster-namespace ${CLUSTER_NAMESPACE} \
--workload-cluster-name ${CLUSTER_NAME} \
--insecure-skip-tls-verify
vcf context list
vcf context use ${CLUSTER_NAME}:${CLUSTER_NAME}Verify connectivity to the guest cluster:
kubectl get nodesThe Fluent Bit package is distributed as part of the VKS Standard
Packages bundle. Add the repository to the tkg-system
namespace, which is the package management namespace that
Carvel/kapp-controller monitors on every VKS cluster.
If the VCF CLI package plugin is not yet installed:
vcf plugin install packagevcf package repository add standard-repo \
--url projects.packages.broadcom.com/vsphere/supervisor/vks-standard-packages/3.6.0-20260416/vks-standard-packages:3.6.0-20260416 \
-n tkg-systemvcf package repository list -n tkg-systemExpected output:
NAME SOURCE STATUS
standard-repo (imgpkg) Reconcile succeeded
projects.packages.broadcom.com/vsphere/supervisor/vks-standard-packages/3.6.0-20260416/vks-standard-packages:3.6.0-20260416
The Reconcile succeeded status confirms that
kapp-controller on the cluster has successfully pulled and indexed the
package metadata. You can also verify at the Kubernetes level:
kubectl get pkgr -n tkg-systemExpected output:
NAME AGE DESCRIPTION PAUSED
standard-repo 2m45s Reconcile succeeded
List all available versions of the Fluent Bit package from the repository:
vcf package available list fluent-bit.kubernetes.vmware.com -n tkg-systemExpected output:
NAME VERSION RELEASED-AT
fluent-bit.kubernetes.vmware.com 4.0.8+vmware.1-vks.1 2025-10-22 14:00:00 -0400 EDT
fluent-bit.kubernetes.vmware.com 4.0.8+vmware.2-vks.1 2025-12-18 13:00:00 -0500 EST
fluent-bit.kubernetes.vmware.com 4.1.1+vmware.1-vks.1 2025-12-18 13:00:00 -0500 EST
fluent-bit.kubernetes.vmware.com 4.2.2+vmware.1-vks.1 2026-02-11 13:00:00 -0500 EST
fluent-bit.kubernetes.vmware.com 4.2.3+vmware.1-vks.1 2026-04-16 14:00:00 -0400 EDT
Extract the default data values schema for the target version. This generates a YAML template with all configurable fields and their defaults:
vcf package available get fluent-bit.kubernetes.vmware.com/4.2.3+vmware.1-vks.1 \
--default-values-file-output fluent-bit-data-values.yaml \
-n tkg-systemReview the generated file to understand the full configuration surface before customising it in the next step.
The data values file controls the complete Fluent Bit configuration: the pipeline (inputs, parsers, filters, outputs) as well as the DaemonSet resource requests and the target namespace. Each configuration section is described below before the complete manifest is shown.
The [SERVICE] block sets global Fluent Bit
behaviour:
| Parameter | Value | Notes |
|---|---|---|
Flush |
1 |
Flush buffered records to outputs every second |
Log_Level |
info |
Set to debug temporarily when troubleshooting |
Daemon |
off |
Fluent Bit runs as a foreground process inside the container |
HTTP_Server |
On |
Enables the built-in metrics endpoint at :2020 for
Prometheus scraping |
HTTP_Port |
2020 |
Default port for /api/v1/metrics and
/api/v1/health |
Four input sources are configured.
Input 1 — Container logs (kube.*)
Tails all container log files written by the CRI (containerd) runtime. Each file corresponds to one running container; the filename encodes the pod name, namespace, and container name.
| Parameter | Value | Notes |
|---|---|---|
Tag |
kube.* |
Fluent Bit replaces * with the file path, producing
tags like
kube.var.log.containers.etcd-dev-cluster-04_kube-system_etcd-<hash>.log |
Parser |
cri |
CRI log format:
<timestamp> <stream> <flags> <message>
— defined in the custom parsers section |
DB |
/var/log/flb_kube.db |
SQLite file persisting the read position; prevents re-shipping historical logs after a pod restart |
Mem_Buf_Limit |
50MB |
Maximum in-memory buffer per input before backpressure is applied |
Input 2 — Systemd daemon logs
(kube_systemd.*)
Reads structured log entries from the systemd journal for the two
core Kubernetes node services. The systemd input reads from
the binary journal (not text files), which preserves the original log
priority, unit, and PID fields.
| Parameter | Value | Notes |
|---|---|---|
Systemd_Filter |
_SYSTEMD_UNIT=kubelet.service |
Restricts collection to kubelet; excludes unrelated system services |
Systemd_Filter |
_SYSTEMD_UNIT=containerd.service |
Adds containerd runtime logs to the same stream |
Read_From_Tail |
On |
Only new journal entries are read on startup |
Strip_Underscores |
On |
Removes leading _ from systemd field names (e.g.,
_PID becomes PID) for cleaner output |
Input 3 — API server audit logs
(apiserver_audit.*)
Collects the Kubernetes API audit log from the VKS control plane
node. Each line is a self-contained JSON object in
audit.k8s.io/v1 format containing the requesting user,
target resource, HTTP verb, and response.
| Parameter | Value | Notes |
|---|---|---|
Path |
/var/log/kubernetes/kube-apiserver.log |
Standard audit log location on VKS Ubuntu nodes |
Parser |
json |
Each audit line is a complete JSON document |
Mem_Buf_Limit |
50MB |
Verbose RequestResponse level audit events can be
large |
Input 4 — Linux auth logs (auth.*)
Collects the Linux audit daemon log from cluster nodes. This stream captures node-level security events: PAM authentication, sudo usage, file permission changes, and kernel audit rules. It is independent of the Kubernetes audit log.
| Parameter | Value | Notes |
|---|---|---|
Path |
/var/log/audit/audit.log |
Standard Linux audit daemon log path |
Parser |
authlog |
Custom syslog-style regex parser defined in the parsers section |
Three custom parsers are defined.
cri — Parses container runtime log
lines. CRI-O and containerd both write logs in the format
<RFC3339Nano> <stream> <flags> <message>:
2026-06-05T17:19:50.764323889Z stderr F I0605 17:19:50 controller.go:109] message text
authlog — Parses traditional
syslog-formatted Linux auth log lines. The regex captures the timestamp,
hostname, process name, optional PID, and message body.
Time_Keep On preserves the original log timestamp as a
field alongside the ingestion timestamp.
json — Parses JSON audit log lines.
Time_Key time maps the time field in the JSON
object to the Fluent Bit record timestamp.
The filter pipeline runs in declaration order. Each filter is applied
to events whose tag matches the Match pattern.
Stage 1 — Global metadata (record_modifier,
match *)
Applied to every event regardless of source. Adds three fields that identify the log’s origin environment:
| Field | Value | Purpose |
|---|---|---|
log_type |
kubernetes |
Top-level classification for all logs from this cluster |
vks_cluster |
dev-cluster-04 |
Identifies the specific VKS cluster; essential when multiple clusters forward to the same Operations for Logs instance |
environment |
vcf902 |
Identifies the VCF environment |
Stage 2 — Kubernetes metadata enrichment
(kubernetes, match kube.*)
This filter contacts the Kubernetes API server from within the pod to look up metadata for the pod that produced each log line. It parses the tag (which encodes the container filename path) to extract the pod name, namespace, and container name, then fetches the corresponding pod object.
Metadata fields added include: pod_name,
namespace_name, container_name,
container_image, pod_id,
docker_id, labels, and
annotations.
Key parameters:
| Parameter | Value | Notes |
|---|---|---|
Merge_Log |
On |
If the message field contains JSON, it is parsed and
merged into the top-level record as log_processed |
Merge_Log_Key |
log_processed |
Nested key under which the parsed JSON message is stored |
K8S-Logging.Parser |
On |
Allows per-pod parser selection via the
fluentbit.io/parser pod annotation |
K8S-Logging.Exclude |
On |
Allows per-pod log exclusion via the
fluentbit.io/exclude: "true" pod annotation |
Stage 3 — Flatten Kubernetes metadata (modify +
nest, match kube.*)
VCF Operations for Logs indexes top-level fields as searchable facets
but treats nested JSON objects as opaque strings. To make Kubernetes
metadata fields (pod name, namespace, labels) individually searchable,
the kubernetes nested object is lifted to the top
level:
modify: Copy kubernetes → k8s (preserve original nested copy)
nest: lift fields from kubernetes object to top level
After this stage, pod_name, namespace_name,
and container_name are top-level fields on the event.
Stage 4 — Text labels (modify,
per-stream)
Each stream receives a text field whose value identifies
the stream by name. VCF Operations for Logs full-text search operates on
the text field, so these labels enable targeted searches
without parsing nested JSON or audit record structures:
| Match pattern | text value |
|---|---|
kube.* |
Kubernetes Container Logs |
kube_systemd.* |
Linux Daemon Logs |
auth.* |
Linux Auth Logs |
apiserver_audit.* |
Kubernetes API Server Audit Logs |
A single HTTP output with Match * forwards all four
streams to VCF Operations for Logs. Sending all streams through one
output simplifies configuration and ensures consistent delivery
semantics across all log types.
| Parameter | Value | Notes |
|---|---|---|
Format |
json |
VCF Operations for Logs API v2 accepts JSON event arrays |
tls |
on |
Traffic is encrypted in transit |
tls.verify |
off |
Server certificate is not validated — see the security note in Step 4.5 below |
Retry_Limit |
False |
Events are retried indefinitely on delivery failure; no log data is silently dropped during connectivity issues |
json_date_key |
timestamp |
Maps the record timestamp to the timestamp field
required by the Operations for Logs API |
Security note — TLS without certificate verification:
tls.verify offencrypts traffic but does not validate the VCF Operations for Logs server certificate. For production, mount the Operations for Logs CA certificate into the Fluent Bit pods and configuretls.verify onwithtls.ca_file <path>. The CA certificate can be distributed via a KubernetesSecretand referenced in the DaemonSet volume mounts.
cat << 'EOF' > ${CLUSTER_NAME}-fluentbit-data-values.yaml
fluent_bit:
config:
service: |
[SERVICE]
Flush 1
Log_Level info
Daemon off
Parsers_File parsers.conf
HTTP_Server On
HTTP_Listen 0.0.0.0
HTTP_Port 2020
inputs: |
###########################################################################
# Container logs — all pod stdout/stderr across every namespace
###########################################################################
[INPUT]
Name tail
Tag kube.*
Path /var/log/containers/*.log
Parser cri
DB /var/log/flb_kube.db
Mem_Buf_Limit 50MB
Skip_Long_Lines On
Refresh_Interval 10
###########################################################################
# Systemd daemon logs — kubelet and containerd services
###########################################################################
[INPUT]
Name systemd
Tag kube_systemd.*
Path /var/log/journal
DB /var/log/flb_kube_systemd.db
Systemd_Filter _SYSTEMD_UNIT=kubelet.service
Systemd_Filter _SYSTEMD_UNIT=containerd.service
Read_From_Tail On
Strip_Underscores On
###########################################################################
# Kubernetes API server audit logs
###########################################################################
[INPUT]
Name tail
Tag apiserver_audit.*
Parser json
Path /var/log/kubernetes/kube-apiserver.log
DB /var/log/flb_kube_audit.db
Mem_Buf_Limit 50MB
Refresh_Interval 10
Skip_Long_Lines On
###########################################################################
# Linux auth logs — PAM, sudo, node-level authentication events
###########################################################################
[INPUT]
Name tail
Tag auth.*
Path /var/log/audit/audit.log
Parser authlog
DB /var/log/flb_system_auth.db
Mem_Buf_Limit 50MB
Refresh_Interval 10
Skip_Long_Lines On
filters: |
###########################################################################
# Global metadata — applied to all streams
###########################################################################
[FILTER]
Name record_modifier
Match *
Record log_type kubernetes
Record vks_cluster dev-cluster-04
Record environment vcf902
###########################################################################
# Kubernetes metadata enrichment — container logs only
###########################################################################
[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
K8S-Logging.Parser On
K8S-Logging.Exclude On
###########################################################################
# Flatten Kubernetes metadata to top-level fields
###########################################################################
[FILTER]
Name modify
Match kube.*
Copy kubernetes k8s
[FILTER]
Name nest
Match kube.*
Operation lift
Nested_Under kubernetes
###########################################################################
# Per-stream text labels for VCF Operations for Logs full-text search
###########################################################################
[FILTER]
Name modify
Match kube.*
Add text "Kubernetes Container Logs"
[FILTER]
Name modify
Match kube_systemd.*
Add text "Linux Daemon Logs"
[FILTER]
Name modify
Match auth.*
Add text "Linux Auth Logs"
[FILTER]
Name modify
Match apiserver_audit.*
Add text "Kubernetes API Server Audit Logs"
outputs: |
###########################################################################
# Output — all streams to VCF Operations for Logs
###########################################################################
[OUTPUT]
Name http
Match *
Host 192.168.200.40
Port 9543
URI /api/v2/events
Format json
tls on
tls.verify off
Retry_Limit False
json_date_key timestamp
parsers: |
###########################################################################
# CRI — container runtime log format (containerd / CRI-O)
###########################################################################
[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
###########################################################################
# authlog — traditional syslog format for Linux auth/audit logs
###########################################################################
[PARSER]
Name authlog
Format regex
Regex ^(?<time>[A-Za-z]+ {1,2}\d+ \d+:\d+:\d+) (?<host>[^ ]*) (?<ident>[a-zA-Z0-9_\/\.\-]*)(?:\[(?<pid>[0-9]+)\])?(?:[^\:]*\:)? *(?<message>.*)$
Time_Key time
Time_Format %b %e %H:%M:%S
Time_Keep On
###########################################################################
# json — Kubernetes API audit log (audit.k8s.io/v1 JSON objects)
###########################################################################
[PARSER]
Name json
Format json
Time_Key time
Time_Format %Y-%m-%dT%H:%M:%S.%LZ
streams: ""
plugins: ""
daemonset:
env: []
podAnnotations: {}
priorityClassName: ""
resources:
limits:
cpu: ""
memory: ""
requests:
cpu: 200m
memory: 256Mi
ipv6Primary: false
namespace: vks-system-logging
nsLimitRange:
defaultLimits:
cpu: ""
memory: ""
defaultRequests:
cpu: 200m
memory: 256Mi
EOFCreate the target namespace and install the package. The
--verbose 9 flag produces detailed output from
kapp-controller during reconciliation, which is useful for diagnosing
image pull or RBAC issues on first install.
kubectl create ns vks-system-logging
vcf package install fluent-bit \
-p fluent-bit.kubernetes.vmware.com \
--version 4.2.3+vmware.1-vks.1 \
--values-file ${CLUSTER_NAME}-fluentbit-data-values.yaml \
-n vks-system-logging \
--verbose 9Package installation is managed by kapp-controller, which reconciles the Helm chart defined by the package. Installation typically completes within 2–3 minutes.
Verify that the package installation has reconciled successfully:
kubectl get packageinstall fluent-bit -n vks-system-loggingExpected output:
NAME PACKAGE NAME PACKAGE VERSION DESCRIPTION AGE PAUSED
fluent-bit fluent-bit.kubernetes.vmware.com 4.2.3+vmware.1-vks.1 Reconcile succeeded 13h
The underlying kapp App resource shows the same
status:
kubectl get apps fluent-bit -n vks-system-loggingExpected output:
NAME DESCRIPTION SINCE-DEPLOY AGE PAUSED
fluent-bit Reconcile succeeded 8m54s 13h
Confirm that one Fluent Bit pod is running on every node:
kubectl get all -n vks-system-loggingExpected output (six-node cluster — 3 control plane + 3 workers):
NAME READY STATUS RESTARTS AGE
pod/fluent-bit-9whdv 1/1 Running 0 4m42s
pod/fluent-bit-h5hdn 1/1 Running 0 4m42s
pod/fluent-bit-hf4n9 1/1 Running 0 4m42s
pod/fluent-bit-lm5qd 1/1 Running 0 4m42s
pod/fluent-bit-pznvs 1/1 Running 0 4m42s
pod/fluent-bit-t96d2 1/1 Running 0 4m42s
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR
daemonset.apps/fluent-bit 6 6 6 6 6 kubernetes.io/os=linux
DESIRED must equal READY. A pod that is not
Running indicates an image pull failure, a missing volume,
or a configuration parse error.
Check the Fluent Bit output across all pods for successful input initialisation and output connectivity:
kubectl -n vks-system-logging logs -l app=fluent-bit \
--all-containers=true \
--tail=200Look for lines confirming each input has opened its source successfully:
[info] [input:tail:tail.0] inotify_fs_add(): inode=... filename=/var/log/containers/...log
[info] [input:systemd:systemd.1] seeking to tail of journal
[info] [output:http:http.0] worker #0 started
To stream live logs:
kubectl -n vks-system-logging logs -l app=fluent-bit -fVCF Operations for Logs exposes a REST API for searching ingested events. Authentication uses short-lived session tokens.
LOGS_HOST='192.168.200.40'
LOGS_USER='admin'
LOGS_PASS='<password>'
SESSION_ID=$(curl -sk \
-H "Content-Type: application/json" \
-X POST "https://${LOGS_HOST}:9543/api/v2/sessions" \
-d "{
\"username\":\"${LOGS_USER}\",
\"password\":\"${LOGS_PASS}\",
\"provider\":\"Local\"
}" | jq -r '.sessionId')
echo "Session ID: ${SESSION_ID}"SEARCH="Kubernetes Container Logs"
curl -sk \
-H "Authorization: Bearer ${SESSION_ID}" \
"https://${LOGS_HOST}:9543/api/v1/events/text/CONTAINS%20$(python3 -c "import urllib.parse; print(urllib.parse.quote('${SEARCH}'))")/timestamp/LAST%203600000" \
| jq .Example event returned. Note the Kubernetes metadata fields lifted to
the top level — pod_name, namespace_name,
container_name, container_image — making them
individually searchable in the Operations for Logs UI:
{
"text": "Kubernetes Container Logs",
"timestamp": 1780674175933,
"timestampString": "2026-06-05 15:42:55.933 GMT+00:00",
"fields": [
{ "name": "message", "content": "{\"level\":\"info\",\"ts\":\"2026-06-05T15:42:55.273296Z\",\"caller\":\"mvcc/index.go:214\",\"msg\":\"compact tree index\",\"revision\":123094}" },
{ "name": "pod_name", "content": "etcd-dev-cluster-04-jfjss-4q796" },
{ "name": "namespace_name", "content": "kube-system" },
{ "name": "container_name", "content": "etcd" },
{ "name": "container_image", "content": "localhost:5000/vmware.io/etcd:v3.5.27_vmware.1-fips" },
{ "name": "pod_id", "content": "d8a868ae-e8d5-43e6-b106-9a1ff8541d5e" },
{ "name": "stream", "content": "stderr" },
{ "name": "host", "content": "dev-cluster-04-jfjss-4q796" },
{ "name": "vks_cluster", "content": "dev-cluster-04" },
{ "name": "log_type", "content": "kubernetes" },
{ "name": "environment", "content": "vcf902" },
{ "name": "source", "content": "10.88.36.2" }
]
}The screenshot below shows the event as it appears in the VCF
Operations for Logs event viewer. Each Kubernetes metadata
field — pod_name, namespace_name,
container_name, container_image — is indexed
as a discrete, searchable facet rather than a nested JSON property. This
is the direct result of the nest/lift filter stage in the
pipeline: without it, the entire kubernetes object would
arrive as an opaque string and none of its subfields would be
individually queryable.
The vks_cluster and environment fields
appended by the global record_modifier filter make it
possible to scope queries to a specific cluster when multiple VKS
clusters forward logs to the same Operations for Logs instance. The
text field value Kubernetes Container Logs
serves as the primary stream discriminator in the field query builder —
selecting text CONTAINS Kubernetes Container Logs on the
interactive timeline isolates container log events from all other
ingested streams without requiring full-text search.
SEARCH="Kubernetes API Server Audit Logs"
curl -sk \
-H "Authorization: Bearer ${SESSION_ID}" \
"https://${LOGS_HOST}:9543/api/v1/events/text/CONTAINS%20$(python3 -c "import urllib.parse; print(urllib.parse.quote('${SEARCH}'))")/timestamp/LAST%203600000" \
| jq .Example event returned. Audit log fields (auditID,
verb, requestURI, level,
stage) are top-level fields because the JSON audit record
was parsed by the json input parser and its fields were
flattened directly into the event:
{
"text": "Kubernetes API Server Audit Logs",
"timestamp": 1780674338933,
"timestampString": "2026-06-05 15:45:38.933 GMT+00:00",
"fields": [
{ "name": "apiVersion", "content": "audit.k8s.io/v1" },
{ "name": "kind", "content": "Event" },
{ "name": "level", "content": "Metadata" },
{ "name": "stage", "content": "ResponseComplete" },
{ "name": "auditID", "content": "5714b0a3-c78b-452b-866a-7fe43e021aff" },
{ "name": "verb", "content": "get" },
{ "name": "requestURI", "content": "/readyz" },
{ "name": "userAgent", "content": "kube-probe/1.35" },
{ "name": "requestReceivedTimestamp", "content": "2026-06-05T15:45:38.382182Z" },
{ "name": "stageTimestamp", "content": "2026-06-05T15:45:38.382612Z" },
{ "name": "vks_cluster", "content": "dev-cluster-04" },
{ "name": "log_type", "content": "kubernetes" },
{ "name": "environment", "content": "vcf902" },
{ "name": "source", "content": "10.88.36.2" }
]
}The screenshot below shows a Kubernetes API server audit event in VCF
Operations for Logs. Because the Fluent Bit json input
parser processes the full audit.k8s.io/v1 record before it
enters the filter pipeline, each audit field is promoted directly to a
top-level indexed field. Fields such as verb,
requestURI, level, stage,
auditID, and userAgent are individually
queryable without nested path syntax or post-ingestion
transformation.
This structure enables precise compliance and security queries. For
example, filtering on verb = delete and
requestURI CONTAINS secrets and
namespace_name = kube-system surfaces all destructive
operations against cluster secrets in a single view. Combined with the
vks_cluster field, the same Operations for Logs instance
can enforce consistent audit retention policies across every VKS cluster
in the environment, differentiating events per cluster without separate
ingestion pipelines.
To modify the Fluent Bit configuration after initial deployment — for example, to add a new input, change a filter, or update the output endpoint — edit the data values file and apply the update:
vcf package installed update fluent-bit \
-n vks-system-logging \
--values-file ${CLUSTER_NAME}-fluentbit-data-values.yamlkapp-controller reconciles the change and rolls out an updated DaemonSet. The pods are restarted rolling to apply the new configuration.
To uninstall the Fluent Bit package:
vcf package installed delete fluent-bit -n vks-system-loggingIf the deletion stalls — this can occur when kapp-controller finalizers are not cleared automatically — remove the finalizers manually:
kubectl patch packageinstall fluent-bit -n vks-system-logging \
--type=merge --patch '{"metadata":{"finalizers":[]}}'
kubectl patch app fluent-bit -n vks-system-logging \
--type=merge --patch '{"metadata":{"finalizers":[]}}'Verify that all resources have been removed:
kubectl get all -n vks-system-logging
kubectl get packageinstall -A
kubectl get app -A| Symptom | Likely Cause | Resolution |
|---|---|---|
Reconcile failed in
kubectl get packageinstall |
Image pull failure or kapp-controller RBAC error | Check kapp-controller logs:
kubectl logs -n tkg-system -l app=kapp-controller --tail=50;
verify the package repository is reachable |
Fluent Bit pods in CrashLoopBackOff |
Configuration parse error in the data values file | Check pod logs:
kubectl -n vks-system-logging logs <pod> --previous;
look for [error] [config] lines |
| No events in VCF Operations for Logs | Output not connecting, or wrong host/port | Run
kubectl -n vks-system-logging logs -l app=fluent-bit --tail=50
and look for HTTP error codes; verify port 9543 is
reachable from cluster nodes |
kube.* events missing Kubernetes metadata fields |
kubernetes filter API call failing | Check that the Fluent Bit ServiceAccount has permissions to read
pods; look for [error] [filter:kubernetes] in pod logs |
| API audit log input collecting nothing | Audit log file does not exist at the configured path | Verify /var/log/kubernetes/kube-apiserver.log exists on
a control plane node; audit logging may be disabled or path may
differ |
DESIRED does not equal READY in
DaemonSet |
Pod scheduling failure on a specific node | Run
kubectl describe pod -n vks-system-logging <pod> on
the non-ready pod for scheduling or image pull errors |
| Package deletion stalls | kapp-controller finalizers not cleared | Patch out finalizers on both the packageinstall and
app resources as shown in the Removing Fluent Bit
section |
Mem_Buf_Limit reached warnings in logs |
Log volume exceeds buffer allocation | Increase Mem_Buf_Limit for the affected input, or
reduce log verbosity at the source |
| Name | URL |
|---|---|
| Broadcom — VKS Standard Packages Release Notes | https://techdocs.broadcom.com/us/en/vmware-cis/vcf/vsphere-supervisor-services-and-standalone-components/latest/release-notes/vks-standard-packages-release-notes.html |
| Fluent Bit — tail Input Plugin | https://docs.fluentbit.io/manual/pipeline/inputs/tail |
| Fluent Bit — systemd Input Plugin | https://docs.fluentbit.io/manual/pipeline/inputs/systemd |
| Fluent Bit — Kubernetes Filter | https://docs.fluentbit.io/manual/pipeline/filters/kubernetes |
| Fluent Bit — HTTP Output Plugin | https://docs.fluentbit.io/manual/pipeline/outputs/http |
| VCF Operations for Logs — API Reference | https://developer.broadcom.com/xapis/aria-operations-for-logs/latest/ |