Send data to XPLG using Fluent-Bit (AWS EKS)

Send data to XPLG using Fluent-Bit (AWS EKS)

diagram-export-7-1-2025-2_54_31-PM.png

Prerequisites

  • Access to an AWS account with permission to configure EKS

  • EKS cluster deployed (fluentbit-andrey in this case)

  • kubectl, aws-cli and eksctl installed

  • Fluent Bit-compatible XPLG listener with a valid token

  • Kubernetes >= 1.32

  • VPC and networking set up for cluster internal communication

 

  1. Connect to AWS & Your Cluster

Configure AWS credentials:

aws configure
image-20250608-122027.png
  1. Connect kubectl to EKS:

aws eks update-kubeconfig --region <cluster_region> --name <cluster_name>
image-20250608-122305.png

Optional: Set environment variables:

export CLUSTER="fluentbit-andrey" export REGION="eu-north-1" export ACCOUNT_ID="655536767854"
  1. Create (or verify) the Kubernetes namespace and Service Account.

# Create namespace only if it doesn't exist kubectl create namespace logging # Create ServiceAccount only if it doesn't exist kubectl create serviceaccount fluent-bit-controlplane -n logging
image-20250608-122358.png
  1. Configure RBAC

RBAC (Role-Based Access Control) ensures Fluent Bit can read Kubernetes metadata like pod names and labels, but without giving it write access.

  • ClusterRole: Grants read-only access to pods and namespaces.

  • ServiceAccount: Identity for Fluent Bit pods.

  • ClusterRoleBinding: Links the role to the ServiceAccount.

Create RBAC config for Fluent Bit

apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: fluent-bit-read rules: - apiGroups: [""] resources: ["pods", "namespaces"] verbs: ["get", "list", "watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: fluent-bit-read roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: fluent-bit-read subjects: - kind: ServiceAccount name: fluent-bit namespace: logging

Apply it:

kubectl apply -f rbac.yaml

 

  1. Create Fluent Bit Configuration (ConfigMap)

nano fluent-bit-config.yaml

Full yaml includes RBAC. Just change the token and requirements

# --- NAMESPACE --- apiVersion: v1 kind: Namespace metadata: name: logging # Create a dedicated namespace for Fluent Bit and logging components # --- SERVICE ACCOUNT --- --- apiVersion: v1 kind: ServiceAccount metadata: name: fluent-bit # Service account Fluent Bit will use namespace: logging # Must be in the same namespace as the DaemonSet # --- RBAC: Role and Binding --- --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: fluent-bit-read rules: - apiGroups: [""] resources: - namespaces - pods # Needed to get metadata for enrichment verbs: ["get", "list", "watch"] # Read-only permissions --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: fluent-bit-read roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: fluent-bit-read subjects: - kind: ServiceAccount name: fluent-bit namespace: logging # Binds the role to our ServiceAccount # --- CONFIGMAP: Fluent Bit Configuration Files --- --- apiVersion: v1 kind: ConfigMap metadata: name: fluent-bit-config namespace: logging labels: app.kubernetes.io/name: fluent-bit data: fluent-bit.conf: | [SERVICE] Flush 5 # Flush logs every 5 seconds Daemon Off # Run in foreground Log_Level info # Log verbosity Parsers_File parsers.conf # Use custom parser HTTP_Server On # Enable health check server HTTP_Listen 0.0.0.0 HTTP_Port 2020 # Health check port @INCLUDE inputs.conf # Include log input config @INCLUDE filters.conf # Include filter config (e.g., enrich with metadata) @INCLUDE outputs.conf # Include output config (e.g., send logs to XPLG) inputs.conf: | [INPUT] Name tail # Tail log files Tag kube.* # Tag format for filtering Path /var/log/containers/*.log # Path to container logs Parser docker # Use docker-style parser Mem_Buf_Limit 5MB # Buffer limit per file Skip_Long_Lines On # Skip lines too long Refresh_Interval 10 # Check for new files every 10 sec filters.conf: | [FILTER] Name kubernetes Match kube.* # Match logs from inputs with kube.* tag Kube_Tag_Prefix kube.var.log.containers. # Strip this prefix Merge_Log On # Merge log line with Kubernetes metadata Merge_Log_Key log # Field name for original log line Keep_Log Off # Discard original log if merged outputs.conf: | [OUTPUT] Name http # Output plugin (HTTP) Match * # Send all logs Host xpolog-service.default.svc.cluster.local # XPLG service DNS name in-cluster Port 30303 # Port XPLG listens on URI /logeye/api/logger.jsp?token=d450a348-6353-405c-a980-27c51f5f7131 # Auth token in URI Format json_lines # Format logs as newline-delimited JSON Json_date_key time # Key for timestamp Json_date_format iso8601 # Format timestamps in ISO8601 Header X-Xpolog-Sender eks-pod-logs # Custom HTTP header Retry_Limit 5 # Retry up to 5 times on failure parsers.conf: | [PARSER] Name docker # Parser name Format json # Input format Time_Key time # Field to use as timestamp Time_Format %Y-%m-%dT%H:%M:%S.%L%z # Timestamp format (ISO8601 with ms and timezone) Time_Keep On # Preserve original time Decode_Field_As escaped log do_next # Decode any escaped characters in log Decode_Field_As json log # Parse nested JSON from "log" field # --- DAEMONSET: Deploy Fluent Bit on Each Node --- --- apiVersion: apps/v1 kind: DaemonSet metadata: name: fluent-bit namespace: logging labels: app.kubernetes.io/name: fluent-bit spec: selector: matchLabels: app.kubernetes.io/name: fluent-bit template: metadata: labels: app.kubernetes.io/name: fluent-bit spec: serviceAccountName: fluent-bit # Use previously created service account tolerations: - operator: Exists # Run on any tainted node (master, control-plane, etc.) containers: - name: fluent-bit image: public.ecr.aws/aws-observability/aws-for-fluent-bit:2.32.0 # AWS-optimized Fluent Bit image resources: requests: cpu: 50m memory: 100Mi # Minimal required resources limits: cpu: 100m memory: 200Mi # Maximum allowed usage volumeMounts: - name: config mountPath: /fluent-bit/etc/ # Mount config from ConfigMap - name: varlog mountPath: /var/log # Mount logs directory readOnly: true - name: varlibdockercontainers mountPath: /var/lib/docker/containers readOnly: true # For container log metadata livenessProbe: httpGet: path: /api/v1/health # Health check endpoint port: 2020 initialDelaySeconds: 10 periodSeconds: 60 volumes: - name: config configMap: name: fluent-bit-config # Reference to the above ConfigMap - name: varlog hostPath: path: /var/log # Mount node log path - name: varlibdockercontainers hostPath: path: /var/lib/docker/containers # Mount container metadata
kubectl apply -f fluent-bit-config.yaml
  1. Deploy Fluent Bit as a DaemonSet

nano fluent-bit-daemonset.yaml
apiVersion: apps/v1 kind: DaemonSet metadata: name: fluent-bit namespace: logging labels: app.kubernetes.io/name: fluent-bit spec: selector: matchLabels: app.kubernetes.io/name: fluent-bit template: metadata: labels: app.kubernetes.io/name: fluent-bit spec: serviceAccountName: fluent-bit tolerations: - operator: Exists containers: - name: fluent-bit image: public.ecr.aws/aws-observability/aws-for-fluent-bit:2.32.0 resources: requests: cpu: 50m memory: 100Mi limits: cpu: 100m memory: 200Mi volumeMounts: - name: config mountPath: /fluent-bit/etc/ - name: varlog mountPath: /var/log readOnly: true - name: varlibdockercontainers mountPath: /var/lib/docker/containers readOnly: true livenessProbe: httpGet: path: /api/v1/health port: 2020 initialDelaySeconds: 10 periodSeconds: 60 volumes: - name: config configMap: name: fluent-bit-config - name: varlog hostPath: path: /var/log - name: varlibdockercontainers hostPath: path: /var/lib/docker/containers
kubectl apply -f fluent-bit-daemonset.yaml

Summary

Component

Purpose

Component

Purpose

ServiceAccount

Allows Fluent Bit to interact with Kubernetes API

ConfigMap

Stores Fluent Bit config (input, filter, output)

DaemonSet

Runs Fluent Bit on all nodes

XPLG HTTP

Fluent Bit sends logs directly to XPLG via HTTP

References

  1. Fluent Bit Official Documentation
    https://docs.fluentbit.io

    • Full configuration options for inputs, filters, outputs, parsers, and service settings.

  2. AWS for Fluent Bit (AWS Distro)
    GitHub - aws/aws-for-fluent-bit: The source of the amazon/aws-for-fluent-bit container image

    • Official Fluent Bit image optimized for AWS with pre-installed plugins and performance tuning.

  3. Amazon EKS Documentation
    https://docs.aws.amazon.com/eks/latest/userguide/what-is-eks.html

    • Guides for managing and connecting to EKS clusters.

  4. Kubernetes RBAC Authorization
    https://kubernetes.io/docs/reference/access-authn-authz/rbac/

    • Role, ClusterRole, RoleBinding, and ClusterRoleBinding explained.

  5. Kubernetes DaemonSet
    https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/

    • Explains the controller that ensures a pod runs on every node.

  6. Kubernetes ConfigMap
    https://kubernetes.io/docs/concepts/configuration/configmap/

    • How to inject configuration into your containers via ConfigMaps.

  7. kubectl command-line tool
    Command line tool (kubectl)

    • Reference for all kubectl commands used during deployment.

  8. AWS CLI – eks update-kubeconfig
    https://docs.aws.amazon.com/cli/latest/reference/eks/update-kubeconfig.html

    • Connect kubectl to your EKS cluster.