Fluent Bit - кроссплатформенное решение по сбору, обработке и маршрутизации логов. Может использоваться в качестве агента на уровне сервера и агента на уровне пода.
Содержание
Fluent Bit собирает, парсит и фильтрует сообщения из различных источников ввода и сохраняет их в хранилище (в памяти или файловой системе). После успешного сохранения, сообщения поступают из хранилища на вход в маршрутизатор, который определяет в какой выход оно будет отправлено.
Ключевая особенность Fluent Bit - использование корутин. Сетевые задержки минимизируются за счет дешевого переключения контекста между разными потоками.
С точки зрения производительности Fluent Bit имеет лучшие показатели в производительности и использовании ОЗУ. Исследование AWS показало что Fluent Bit в ~5 раз меньше утлизировал процессор и память чем Fluentd.
Позволяют получать сообщения из различных источников. К основным можно отнести:
systemd
- журнал операционной системы;kmsg
- журнал ядра операционной системы;tail
- чтение файла из файловой системыПод обработкой сообщения подразумевается парсинг и фильтрация/модификация сообщений. К основным можно отнести:
json
- парсер json
сообщений;decoder
- позволяет декодировать структуры из строки (например, экранированный json
);kubernetes
- позволяет дополнять сообщения метаданными о поде в кластере kubernetesrecord_modifier
- позволяет добавлять/удалять поля из сообщенийХранение сообщений позволяет решить классическую проблему "Fast publisher, slow subscriber". С помощью хранилища организуется "обратное давление" на источник сообщений, вплоть до его полной остановки. Всего реализовано 2 типа хранилищ: в памяти и файловой системе.
Позволяют отправлять сообщения в различные источники. К основным можно отнести:
file
- записывать сообщения в файл;pgsql
- сохранять сообщения в PostgreSQL;es
- сохранять сообщения в Elasticsearch;Существует несколько подходов к cluster-level журналированию в kubernetes. Fluent Bit можно применить в каждом из них, а так же он может быть использован совместно с Fluentd. Для упрощения примера далее будет использован подход журналирования на уровне сервера.
Daemon set лучше всего подходит для журналирования на уровне сервера. Kubernetes сам запустит Fluent Bit на новых узлах.
Манифест основан на репозитории fluent/fluent-bit-kubernetes-logging. В нём дополнительно монтируется хост директория /run/log
для интеграции с systemd-journald
:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluent-bit
namespace: monitoring
labels:
k8s-app: fluent-bit
spec:
selector:
matchLabels:
k8s-app: fluent-bit
template:
metadata:
labels:
k8s-app: fluent-bit
spec:
priorityClassName: system-node-critical
containers:
- name: fluent-bit
image: fluent/fluent-bit:1.7.0
imagePullPolicy: Always
ports:
- containerPort: 2020
name: http
protocol: TCP
volumeMounts:
- name: config
mountPath: /fluent-bit/etc/fluent-bit.conf
subPath: fluent-bit.conf
- name: config
mountPath: /fluent-bit/etc/custom_parsers.conf
subPath: custom_parsers.conf
- name: var-log
mountPath: /var/log
- name: run-log
mountPath: /run/log
- name: etcmachineid
mountPath: /etc/machine-id
readOnly: true
volumes:
- name: config
configMap:
defaultMode: 420
name: fluent-bit
- name: var-log
hostPath:
path: /var/log
- name: run-log
hostPath:
path: /run/log
- name: etcmachineid
hostPath:
path: /etc/machine-id
type: File
Манифест задействует 3 точки монтирования: /var/log
, /run/log
и /etc/machine-id
. Fluent Bit, при открытии журнала sd_journal_open()
, использует флаг SD_JOURNAL_LOCAL_ONLY
- открывать только локальные журналы. Для их фильтрации используется идентификатор machine-id
хранящийся в одноименном файле. В режиме Storage=auto
файлы журналов могут храниться в одной из двух директорий: /var/log/journal
, /run/log/journal
. Если директория /var/log/journal
не существует, journald
будет использовать /run/log/journal
для ведения журнала.
Конфигурация описывает одну цепочку обработки логов. Стандартный вывод docker.service
дополняется мета-информацией из kubernetes api server и записываются в файл /var/log/k8s.log
:
apiVersion: v1
kind: ConfigMap
metadata:
labels:
k8s-app: fluent-bit
name: fluent-bit
namespace: monitoring
data:
fluent-bit.conf: |
[SERVICE]
Flush 1
Daemon Off
Log_Level info
Parsers_File parsers.conf
HTTP_Server On
HTTP_Listen 0.0.0.0
HTTP_Port 2020
[INPUT]
Name systemd
Tag kube.*
Systemd_Filter _SYSTEMD_UNIT=docker.service
Read_From_Tail On
[FILTER]
Name kubernetes
Match kube.*
Kube_URL https://192.168.1.57:6443
Use_Journal On
tls.verify Off
Merge_Log On
Keep_Log Off
K8S-Logging.Parser On
K8S-Logging.Exclude On
[OUTPUT]
Name file
Match *
Path /var/log/k8s.log
Установка и применение изменений производится с помощью команды kubectl apply
:
~ % ~ % kubectl apply -f fluent-bit-configmap.yaml && kubectl apply -f fluent-bit-ds.yaml
После этого можно убедиться в успехе установки:
~ % kubectl -n monitoring get ds fluent-bit
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
fluent-bit 1 1 1 1 1 <none> 27s
~ % kubectl -n monitoring get pods -lk8s-app=fluent-bit
NAME READY STATUS RESTARTS AGE
fluent-bit-mf8k2 1/1 Running 0 30s
~ % kubectl -n monitoring exec -ti ds/fluent-bit -- tail -f /var/log/k8s.log
{"kubernetes":{"container_hash":"k8s.gcr.io/ingress-nginx/controller@sha256:e6019e536cfb921afb99408d5292fa88b017c49dd29d05fc8dbc456aa770d590","container_image":"k8s.gcr.io/ingress-nginx/controller:v0.41.0","container_name":"controller","docker_id":"d7802a01649248c5aa781548192528f67666c5ed27061860384f192e07053ae5","host":"inf-1","labels":{"k8s-app":"ingress-nginx","pod-template-hash":"84d9759c66"},"namespace_name":"kube-system","pod_id":"b0bd1b8d-5a21-4cec-91af-30a250d3610b","pod_name":"ingress-nginx-84d9759c66-vgkk6"},"log":"10.10.0.1 - - [01/Mar/2021:05:36:53 +0000] \"GET /healthz HTTP/1.1\" 200 13 \"\" \"dashboard/v2.0.0\"","stream":"stdout","time":"2021-03-01T05:36:53.900282242Z"}
...
Fluent Bit обладает схожей с rsyslog функциональностью. Различные плагины ввода и вывода позволяют встраивать его в различные схемы cluster level журналирования.
Разработка Fluent Bit ведется с пониманием того, что с высокой долей вероятности сервис будет запущен в контейнеризированном окружении. За счет этого интеграция в kubernetes состоит из нескольких шагов.