Problem:
You want send container logs from self-managed kubernetes cluster pods to AWS S3 bucket using Fluent Bit. Actually this is possible now because starting Oct 2020, Fluent Bit supports AWS S3 as a destination to route container logs. In this article we will learn how to setup Fluent Bit to send logs to S3 bucket.
Solution:
In order to send records into Amazon S3, follow these steps-
1. Create a ClusterRole (cluster-role.yaml). Set your namespace name.
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: fluent-bit-read namespace: fluentbit2S3 rules: - apiGroups: ["", "extensions", "apps"] resources: ["deployments", "pods", "namespaces"] verbs: ["get", "list", "watch"]
2. Create ServiceAccount (service-account.yaml). Set your serviceaccount and namespace name.
apiVersion: v1 kind: ServiceAccount metadata: name: fluent-bit namespace: fluentbit2S3
3. Create ClusterRoleBinding (cluster-role-binding.yaml). Set your serviceaccount and namespace name.
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: fluent-bit-read namespace: fluentbit2S3 roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: fluent-bit-read subjects: - kind: ServiceAccount name: fluent-bit namespace: fluentbit2S3
4. Create Configmap for Fluent Bit (config-map.yaml). Update namespace and S3 bucket name.
apiVersion: v1
kind: ConfigMap
metadata:
name: fluent-bit
namespace: fluentbit2S3
labels:
app: fluent-bit
data:
fluent-bit.conf: |
[SERVICE]
Parsers_File parsers.conf
@INCLUDE input-*.conf
@INCLUDE output-*.conf
@INCLUDE filters.conf
parsers.conf: |
[PARSER]
Name s3_logs
Format json
Time_Key requestReceivedTimestamp
Time_Format %Y-%m-%dT%H:%M:%S.%LZ
Time_Keep On
[PARSER]
Name kubernetes-tag
Format regex
Regex (?<namespace_name>.+)\.(?<pod_name>.+)\.(?<container_name>.+)
input-s3logs.conf: |
[INPUT]
Name tail
Tag kube.<namespace_name>.<pod_name>.<container_name>
Tag_Regex (?<pod_name>[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)_(?<namespace_name>[^_]+)_(?<container_name>.+)-
Path /var/log/containers/*.log
Exclude_Path /var/log/containers/*_fluentbit2S3_*.log
Parser s3_logs
DB /var/log/flb_kube.db
Mem_Buf_Limit 5MB
Skip_Long_Lines On
Refresh_Interval 10
output-s3.conf: |
[OUTPUT]
Name s3
Match *
bucket /fluentbit2S3/
region ap-southeast-2
use_put_object On
s3_key_format /$TAG[1]/$TAG[3]/%Y/%m/%d/
s3_key_format_tag_delimiters .
total_file_size 5M
upload_timeout 1m
[OUTPUT]
Name stdout
Match *
filters.conf: |
[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.
Merge_Log On
Merge_Log_Key log_processed
K8S-Logging.Parser On
K8S-Logging.Exclude On
Regex_Parser kubernetes-tag
Labels Off
Annotations Off
5. Create Daemonset file (daemon-set.yaml). Update namespace name, secretKeyRef name.
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluent-bit
namespace: fluentbit2S3
labels:
k8s-app: fluent-bit
version: v1
kubernetes.io/cluster-service: "true"
spec:
selector:
matchLabels:
app: fluent-bit
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
template:
metadata:
labels:
app: fluent-bit
k8s-app: fluent-bit
version: v1
kubernetes.io/cluster-service: "true"
spec:
containers:
- env:
- name: AWS_REGION
value: ap-southeast-2
- name: AWS_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: fluentbit-s3-key
key: AWS_ACCESS_KEY_ID
- name: AWS_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: fluentbit-s3-key
key: AWS_SECRET_ACCESS_KEY
image: 906394416424.dkr.ecr.ap-southeast-2.amazonaws.com/aws-for-fluent-bit:2.8.0
imagePullPolicy: Always
name: fluent-bit
volumeMounts:
- name: fluentbitconfigvol
mountPath: /etc/fluent-bit/conf/
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
command: ["/fluent-bit/bin/fluent-bit"]
args: ["-c", "/etc/fluent-bit/conf/fluent-bit.conf"]
imagePullSecrets:
- name: aws-registry
volumes:
- name: fluentbitconfigvol
configMap:
name: fluent-bit
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
6. Create a secret into Pod as environment variable. Set the name of the secret in daemonset file.
kubectl create secret generic fluentbit-s3-key --from-literal=AWS_ACCESS_KEY_ID=<REPLACE THE KAY ID HERE> --from-literal=AWS_SECRET_ACCESS_KEY=<REPLACE THE ACCESS KEY STRING HERE>
Now run this Fluent Bit DaemonSet on Kubernetes cluster. It will start sending the container logs to S3 bucket.
Note: Follow this doc for more options to configure AS S3 plugin – https://docs.fluentbit.io/manual/pipeline/outputs/s3#getting-started