Рубрика: Без рубрики

  • Сбор логов с помощью FluentBit

    В разделе представлена реализация интеграции между YDB и инструментом захвата логов FluentBit с целью сохранения данных логов в YDB для последующего просмотра или анализа.

    Введение

    FluentBit – инструмент, который может собирать текстовые данные, манипулировать ими (изменять, преобразовывать, объединять) и отправлять в различные хранилища для дальнейшей обработки. Для поставки логов в таблицы YDB с помощью FluentBit разработана библиотека-плагин. Исходный код библиотеки доступен здесь.

    Чтобы развернуть схему доставки логов с помощью FluentBit с последующим сохранением их в YDB, необходимо:

    1. Создать таблицы YDB для хранения логов
    2. Развернуть FluentBit и библиотеку-плагин для поддержки YDB
    3. Сконфигурировать FluentBit для сбора и обработки логов в соответствии с документацией
    4. Настроить сохранение логов в таблицы YDB

    Создание таблиц для хранения логов

    Для сохранения логов необходимо создать таблицы в выбранной базе данных YDB. Структура создаваемых таблиц определяется набором полей конкретного лога, поставляемого с помощью FluentBit. Типичный набор полей включает в себя:

    • метку времени;
    • уровень критичности сообщения;
    • имя хоста, с которого получено сообщение;
    • наименование сервиса;
    • текст сообщения либо его структурированные данные в формате JSON.

    В таблицах YDB обязательно наличие первичного ключа, уникально идентифицирующего конкретную запись. Поскольку метка времени не обеспечивает уникальной идентификации записи лога, в состав хранимых полей обычно добавляют значение хеш-кода над данными сообщения, которое включают в состав первичного ключа.

    Поддерживается хранение логов как в строковых, так и колоночных таблицах. Рекомендуется использование колоночных таблиц, как обеспечивающих более эффективное сканирование данных при выполнении запросов.

    Пример команды создания строковой таблицы для хранения логов:

    CREATE TABLE `fluent-bit/log` (
        `timestamp`         Timestamp NOT NULL,
        `hostname`          Text NOT NULL,
        `input`             Text NOT NULL,
        `datahash`          Uint64 NOT NULL,
        `level`             Text NULL,
        `message`           Text NULL,
        `other`             JsonDocument NULL,
        PRIMARY KEY (
             `datahash`, `timestamp`, `hostname`, `input`
        )
    );
    

    Пример команды создания колоночной таблицы для хранения логов:

    CREATE TABLE `fluent-bit/log` (
        `timestamp`         Timestamp NOT NULL,
        `hostname`          Text NOT NULL,
        `input`             Text NOT NULL,
        `datahash`          Uint64 NOT NULL,
        `level`             Text NULL,
        `message`           Text NULL,
        `other`             JsonDocument NULL,
        PRIMARY KEY (
             `timestamp`, `hostname`, `input`, `datahash`
        )
    ) PARTITION BY HASH(`timestamp`, `hostname`, `input`)
      WITH (STORE = COLUMN);
    

    Команда создание колоночной таблицы отличается от команды создания строковой таблицы следующими деталями:

    • указанием в двух последних строках колоночного режима хранения и отдельного ключа партиционирования;
    • колонка timestamp указана первой в составе первичного ключа таблицы, что является оптимальным и рекомендованным для колоночных таблиц, и не рекомендовано для строчных таблиц. См. также рекомендации по выбору первичного ключа для колоночных таблиц и для строчных таблиц.

    Опционально можно настроить TTL для строк таблицы, ограничив срок хранения и обеспечив автоматическое удаление устаревших данных. Для этого при создании таблицы в секции WITH указываются настройки TTL, например TTL = Interval("P14D") ON timestamp устанавливает срок хранения записей в 14 дней на основе значения поля timestamp.

    Развертывание FluentBit и настройка сбора логов

    Развертывание FluentBit осуществляется в соответствии с собственной документацией.

    Плагин для поддержки YDB в FluentBit доступен в репозитории вместе с инструкциями по сборке. Для установки в формате контейнера предусмотрен Docker-образ ghcr.io/ydb-platform/fluent-bit-ydb.

    Общая логика и порядок настройки процессов получения, обработки и поставки логов в среде FluentBit изложены в документации FluentBit.

    Настройка записи логов в YDB

    Перед использованием выходного плагина для YDB, его необходимо включить в настройках FluentBit. Перечень используемых плагинов FluentBit определяется в отдельном файле (например, plugins.conf), путь к которому устанавливается параметром plugins_file секции SERVICE основного файла настроек FluentBit. Пример файла плагинов со ссылкой на библиотеку плагина для записи в YDB (путь к библиотеке в вашей системе может отличаться):

    # plugins.conf
    [PLUGINS]
        Path /usr/lib/fluent-bit/out_ydb.so
    

    Состав конфигурационных параметров, поддерживаемых выходным плагином YDB для FluentBit, приведен в таблице ниже.

    КлючОписание
    NameТип плагина, константа ydb
    Match(опционально) Выражение для отбора тегов записей, направляемых в YDB
    ConnectionURLURL для подключения к БД, включая протокол, хост, номер порта и путь к базе данных (см. документацию)
    TablePathПуть к таблице, начиная от корня базы данных (пример: fluent-bit/log)
    ColumnsJSON-структура, состоящая из пар имен колонок, и устанавливающая соответствие между исходными колонками записи и целевыми колонками таблицы. Может включать перечисленные далее служебные псевдо-колонки
    CredentialsAnonymousУстанавливается в значение 1 для использования анонимной аутентификации
    CredentialsTokenЗначение токена аутентификации, для использования аутентификации непосредственно по значению токена
    CredentialsYcMetadataУстанавливается в значение 1 для использования аутентификации через метаданные виртуальной машины
    CredentialsStaticЛогин и пароль для использования статического режима аутентификации, указанные в формате Логин:Пароль@
    CredentialsYcServiceAccountKeyFileПуть к файлу ключа сервисного аккаунта, для аутентификации по ключу сервисного аккаунта
    CredentialsYcServiceAccountKeyJsonJSON-данные ключа сервисного аккаунта, для аутентификации по ключу сервисного аккаунта без указания имени файла (удобно в среде K8s)
    CertificatesПуть к файлу с сертификатом CA, либо непосредственно содержимое сертификата CA
    LogLevelУровень логирования для плагина, одно из значений disabled (по умолчанию), tracedebuginfowarnerrorfatal либо panic

    Для использования в карте сопоставления колонок (параметр Columns), в дополнение к полям записи FluentBit, доступны следующие служебные псевдо-колонки:

    • .timestamp — метка времени сообщения (обязательная)
    • .input — имя входного потока сообщений (обязательная)
    • .hash — uint64 хеш-код, вычисленный над всеми полями сообщения, кроме псевдо-колонок (опциональная)
    • .other — документ JSON, содержащий все поля сообщения, которые не были явным образом сопоставлены с конкретной выходной колонкой (опциональная)

    Пример значения параметра Columns:

    {".timestamp": "timestamp", ".input": "input", ".hash": "datahash", "log": "message", "level": "level", "host": "hostname", ".other": "other"}
    

    Сбор логов в кластере Kubernetes

    FluentBit очень часто используется для сбора логов в кластерах Kubernetes. Принципиальная схема доставки логов запущенных приложений в Kubernetes с помощью FluentBit с последующим сохранением их в YDB выглядит следующим образом:

    FluentBit in Kubernetes cluster

    На этой схеме:

    • Поды приложений пишут логи в stdout/stderr
    • Текст из stdout/stderr сохраняется в виде файлов на рабочих узлах Kubernetes
    • Под с FluentBit:
      • Монтирует каталог с лог-файлами рабочего узла Kubernetes
      • Вычитывает из лог-файлов содержимое
      • Обогащает записи дополнительными метаданными
      • Сохраняет записи в базу данных YDB

    Таблица для хранения логов Kubernetes

    Структура таблицы YDB для хранения логов Kubernetes:

    CREATE TABLE `fluent-bit/log` (
        `timestamp`         Timestamp NOT NULL,
        `file`              Text NOT NULL,
        `pipe`              Text NOT NULL,
        `message`           Text NULL,
        `datahash`          Uint64 NOT NULL,
        `message_parsed`    JSON NULL,
        `kubernetes`        JSON NULL,
    
        PRIMARY KEY (
             `timestamp`, `file`, `datahash`
        )
    ) PARTITION BY HASH(`timestamp`, `file`)
      WITH (STORE = COLUMN, TTL = Interval("P14D") ON `timestamp`);
    

    Предназначение колонок:

    • timestamp – временная метка лога;
    • file – название источника, из которого прочитан лог. В случае Kubernetes это будет имя файла, на worker ноде, в который записываются логи определенного pod;
    • pipe – stdout или stderr поток, куда была осуществлена запись на уровне приложения;
    • datahash – хеш-код, вычисленный над записью лога;
    • message – текстовая часть записи лога;
    • message_parsed – структурированное представление записи лога, если его удалось разобрать из текстовой части с помощью настроенных парсеров FluentBit;
    • kubernetes – информация о pod, включая название, неймспейс и аннотации.

    Опционально, можно установить TTL для строк таблицы, как показано в примере выше.

    Конфигурация FluentBit

    Перед развертыванием FluentBit в среде Kubernetes необходимо подготовить файл настроек (обычно values.yaml), в котором указываются параметры сбора и обработки логов. В этом разделе представлены необходимые пояснения по заполнению этого файла с примерами.

    Необходимо указать репозиторий и версию образа контейнера FluentBit:

    image:
      repository: ghcr.io/ydb-platform/fluent-bit-ydb
      tag: latest
    

    В данном образе, по сравнению со стандартным, добавлена библиотека-плагин для поддержки YDB.

    В следующих строках определены правила монтирования папок с логами в поды FluentBit:

    volumeMounts:
      - name: config
        mountPath: /fluent-bit/etc/conf
    
    daemonSetVolumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibcontainers
        hostPath:
          path: /var/lib/containerd/containers
      - name: etcmachineid
        hostPath:
          path: /etc/machine-id
          type: File
    
    daemonSetVolumeMounts:
      - name: varlog
        mountPath: /var/log
      - name: varlibcontainers
        mountPath: /var/lib/containerd/containers
        readOnly: true
      - name: etcmachineid
        mountPath: /etc/machine-id
        readOnly: true
    

    Также необходимо переопределить команду и аргументы запуска FluentBit:

    command:
      - /fluent-bit/bin/fluent-bit
    
    args:
      - --workdir=/fluent-bit/etc
      - --plugin=/fluent-bit/lib/out_ydb.so
      - --config=/fluent-bit/etc/conf/fluent-bit.conf
    

    Требуется настроить пайплайн сбора, преобразования и доставки логов:

    config:
      inputs: |
        [INPUT]
            Name tail
            Path /var/log/containers/*.log
            multiline.parser cri
            Tag kube.*
            Mem_Buf_Limit 5MB
            Skip_Long_Lines On
    
      filters: |
        [FILTER]
            Name kubernetes
            Match kube.*
            Keep_Log On
            Merge_Log On
            Merge_Log_Key log_parsed
            K8S-Logging.Parser On
            K8S-Logging.Exclude On
    
        [FILTER]
            Name modify
            Match kube.*
            Remove time
            Remove _p
    
      outputs: |
        [OUTPUT]
            Name ydb
            Match kube.*
            TablePath fluent-bit/log
            Columns {".timestamp":"timestamp",".input":"file",".hash":"datahash","log":"message","log_parsed":"message_structured","stream":"pipe","kubernetes":"metadata"}
            ConnectionURL ${OUTPUT_YDB_CONNECTION_URL}
            CredentialsToken ${OUTPUT_YDB_CREDENTIALS_TOKEN}
    

    Описание конфигурационных блоков:

    • inputs — в этом блоке указываются откуда считывать и как разбирать логи. В данном случае, будет осуществляться чтение файликов *.log из папки /var/log/containers/, которая была смонтирована с хоста
    • filters — в этом блоке указывается как будет осуществляться обработка логов. В данном случае: для каждого лога будут найдены соответствующие метаданные (в помощью kubernetes фильтра), а также, вырезаны неиспользуемые поля (_p, time)
    • outputs — в этом блоке указывается, куда будут отгружены логи. В данном случае в таблицу fluent-bit/log в базе данных YDB. Параметры подключения к базе данных (в данном случае ConnectionURL и CredentialsToken) задаются с помощью переменных окружения – OUTPUT_YDB_CONNECTION_URLOUTPUT_YDB_CREDENTIALS_TOKEN. При необходимости настройки аутентификации и состав используемых переменных окружения корректируются в зависимости от настроек используемого кластера YDB.

    Переменные окружения определяются следующим образом:

    env:
      - name: OUTPUT_YDB_CONNECTION_URL
        value: grpc://ydb-endpoint:2135/path/to/database
      - name: OUTPUT_YDB_CREDENTIALS_TOKEN
        valueFrom:
          secretKeyRef:
            key: token
            name: fluent-bit-ydb-plugin-token
    

    Данные аутентификации необходимо сохранить в конфигурации кластера Kubernetes в виде секрета. Пример команды для создания секрета:

    kubectl create secret -n ydb-fluent-bit-integration generic fluent-bit-ydb-plugin-token --from-literal=token=<YDB TOKEN>
    

    Развертывание FluentBit в кластере Kubernetes

    HELM – это инструмент пакетирования и установки приложений в кластере Kubernetes. Для развертывания FluentBit необходимо добавить репозиторий с соответствующим чартом (сценарием установки) с помощью команды:

    helm repo add fluent https://fluent.github.io/helm-charts
    

    После этого установка FluentBit в кластер Kubernetes выполняется с помощью следующей команды:

    helm upgrade --install fluent-bit fluent/fluent-bit \
      --version 0.37.1 \
      --namespace ydb-fluent-bit-integration \
      --create-namespace \
      --values values.yaml
    

    В команде выше в аргументе --values указывается ранее подготовленный файл с настройками FluentBit.

    Проверка установки

    Проверяем что FluentBit запустился, читая его логи (должны отсутствовать записи уровня [error]):

    kubectl logs -n ydb-fluent-bit-integration -l app.kubernetes.io/instance=fluent-bit
    

    Проверяем, что записи в таблице YDB есть (появятся спустя примерно несколько минут после запуска FluentBit):

    SELECT * FROM `fluent-bit/log` LIMIT 10 ORDER BY `timestamp` DESC
    

    Очистка ресурсов

    Для удаления FluentBit достаточно удалить Kubernetes namespace, в который была выполнена установка:

    kubectl delete namespace ydb-fluent-bit-integration
    

    Далее можно удалить таблицу с логами в базе данных YDB:

    DROP TABLE `fluent-bit/log`
  • Привет, мир!

    Добро пожаловать в WordPress. Это ваша первая запись. Отредактируйте или удалите ее, затем начинайте создавать!