Централизация логов Docker с помощью Fluentd и ElasticSearch в Ubuntu 16.04

При развёртывании контейнеров Docker в среде производства возникает острая необходимость хранить их логи в более надёжном месте. Docker предлагает встроенный драйвер для Fluentd, с помощью которого можно собирать и перемещать логи в другую точку системы, например, в Elasticsearch.

Fluentd – это открытый коллектор данных, предназначенный для объединения и систематизации инфраструктуры логов. С его помощью логирование становится простым и масштабируемым.

Ключевые возможности

Fluentd имеет четыре основные характеристики:

  • Логирование в JSON:  Fluentd пытается структурировать данные в JSON. Это позволяет Fluentd объединить все аспекты обработки логов: сбор, фильтрацию, буферизацию и вывод логов из нескольких источников. JSON упрощает последующую обработку данных, так как они имеют достаточно удобную структуру.
  • Сменная архитектура: Fluentd имеет гибкую систему плагинов, которая позволяет расширить функциональные возможности программы. С помощью плагинов вы можете использовать логи более производительно.
  • Минимум ресурсов: коллектор данных должен быть легковесным, чтобы пользователь мог запустить его на загруженной машине. Коллектор Fluentd написан на C в комбинации с Ruby и требует минимум системных ресурсов.
  • Встроенная защита данных: Fluentd не допустит потери данных. Программа поддерживает буферизацию для предотвращения потери данных между узлами. Также Fluentd можно настроить для обеспечения высокой доступности.

Данное руководство поможет установить Fluentd, собрать логи контейнеров Docker и сохранить их вне контейнеров (это позволит сохранить данные в случае сбоя контейнера). Данные будут переданы в другой контейнер на том же сервере Ubuntu 16.04, в котором будет запущена СУБД Elasticsearch.

Требования

  • Сервер Ubuntu 16.04 (начальная настройка подробно описана в этой статье).
  • 4 Гб оперативной памяти.
  • Доступ к команде sudo.
  • Предварительно установленная платформа Docker (инструкции можно найти здесь).

1: Установка Fluentd

Обычно для развёртывания Fluentd используется пакет td-agent. Компания Treasure Data, автор Fluentd, упаковывает Fluentd с Ruby, так что пользователям не нужно устанавливать Ruby самостоятельно.

Чтобы установить td-agent, загрузите сценарий:

\curl -L http://toolbelt.treasuredata.com/sh/install-ubuntu-xenial-td-agent2.sh -o install-td-agent.sh

Вы можете просмотреть содержимое сценария, прежде чем запустить его.

nano install-td-agent.sh

Запустите установку td-agent:

sh install-td-agent.sh

После завершения установки запустите td-agent:

sudo systemctl start td-agent

Чтобы убедиться, что пакет установлен успешно, проверьте логи:

tail /var/log/td-agent/td-agent.log

Команда вернёт примерно такой вывод:

port 8888
</source>
<source>
@type debug_agent
bind 127.0.0.1
port 24230
</source>
</ROOT>
2016-12-02 19:45:31 +0000 [info]: listening fluent socket on 0.0.0.0:24224
2016-12-02 19:45:31 +0000 [info]: listening dRuby uri="druby://127.0.0.1:24230" object="Engine"

Теперь нужно установить плагин Elasticsearch для Fluentd с помощью команды td-agent-gem:

sudo td-agent-gem install fluent-plugin-elasticsearch

Примечание: Также программа Fluentd доступна в качестве gem-а Ruby. Если у вас уже есть среда Ruby, вы можете установить Fluentd и Elasticsearch с помощью команд:

gem install fluentd --no-rdoc --no-ri
gem install fluentd-plugin-elasticsearch --no-rdoc --no-ri

2: Настройка Fluentd

Fluentd нужно знать, где собирать данные и куда их передавать. Эти правила можно определить в конфигурационном файле Fluentd, /etc/td-agent/td-agent.conf.

Откройте текстовый редактор:

sudo nano /etc/td-agent/td-agent.conf

Удалите всё содержимое файла и добавьте в него пользовательские правила.

Источники данных определяются с помощью раздела source. Добавьте в файл:

<source>
@type forward
port  24224
</source>

В качестве источника используется forward, протокол Fluentd, основанный на TCP.

В записях логов будут присутствовать дополнительные поля: time, tag, message, container_id. Используйте информацию поля _tag_, чтобы определить, куда Fluentd будет передавать данные. Это называется маршрутизации данных.

Для этого нужно добавить раздел match, который будет совпадать с содержимым поля tag. Добавьте в файл строки:

<match docker.**>
@type elasticsearch
logstash_format true
host 127.0.0.1
port 9200
flush_interval 5s
</match>

Теперь все записи, тег которых начинается с docker., будут переданы в Elasticsearch (127.0.0.1, порт 9200). Директива flush_interval указывает, как часто Fluentd нужно добавлять записи в Elasticsearch.

Примечание: Больше информации о сбросе и буферизации данных можно найти здесь.

Сохраните конфигурации. Перезапустите сервис td-agent, чтобы обновить настройки:

sudo systemctl restart td-agent

3: Запуск контейнера Elasticsearch

Используйте Docker-образ Elasticsearch, чтобы создать контейнер. Сначала нужно изменить max_map_count хоста Docker.

sudo sysctl -w vm.max_map_count=262144

Чтобы загрузить образ Elasticsearch и запустить контейнер, введите:

docker run -d -p 9200:9200 -p 9300:9300 elasticsearch

Чтобы убедиться, что контейнер работает, проверьте процессы Docker и найдите этот контейнер:

docker ps
CONTAINER ID    IMAGE           COMMAND                   STATUS        PORTS                                            NAMES
76e96943491f    elasticsearch   "/docker-entrypoint.s"    Up 51 seconds 0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp   gigantic_hawking

Если контейнер отсутствует в списке, запустите его на переднем плане (без опции –d).

docker run -p 9200:9200 -p 9300:9300 elasticsearch

Убедитесь, что команда не возвращает сообщений об ошибках. Наиболее распространённые ошибки на этом этапе связаны с недостаточным объемом системной памяти или низким значением max_map_count. Убедитесь, что вы выполнили все инструкции раздела, и повторите попытку.

4: Генерирование логов контейнера Docker

Docker может воспринимать логи как потоки данных через стандартный вывод (STDOUT) и поток ошибок (STDERR). Запуская приложение Docker, настройте Docker для использования встроенного драйвера Fluentd. Сервис Fluentd будет получать логи и передавать их в Elasticsearch.

Запустите в контейнере Docker такую команду:

docker run --log-driver=fluentd ubuntu /bin/echo 'Hello world'

Команда должна передать на стандартный вывод фразу Hello world, которая также будет перехвачена драйвером Fluentd и передана сервисом в указанное ранее место. Примерно через пять секунд записи будут сброшены в Elasticsearch. Этот интервал был настроен в разделе match конфигурационного файла Fluentd.

Теперь логи передаются в Elasticsearch.

Более подробную информацию можно найти в официальной документации Docker.

Осталось только убедиться, что Elasticsearch получает данные. Отправьте запрос с помощью curl:

curl -XGET 'http://localhost:9200/_all/_search?q=*'

Вывод будет содержать такие события:

{"took":2,"timed_out":false,"_shards":{"total":1,"successful":1,"failed":0},"hits":{"total":1,"max_score":1.0,"hits":[{"_index":"logstash-2016.12.02","_type":"fluentd","_id":"AVQwUi-UHBhoWtOFQKVx","_score":1.0,"_source":{"container_id":"d16af3ad3f0d361a1764e9a63c6de92d8d083dcc502cd904155e217f0297e525","container_name":"/nostalgic_torvalds","source":"stdout","log":"Hello world","@timestamp":"2016-12-02T14:59:26-06:00"}}]}}

Список событий может отличаться. Список начинается с {“took”: и заканчивается временной меткой. Здесь вы найдёте дополнительную информацию об исходном контейнере.

Заключение

Сбор логов контейнеров Docker – это лишь один из многих способов применения Fluentd. Многие используют Fluentd в качестве конвейера, который обеспечивает поиск по логам в режиме реального времени и долгосрочное хранение данных. Такая архитектура основана на возможности Fluentd копировать потоки данных и передавать их системам хранения. Например, вы можете использовать Elasticsearch для поиска в режиме реального времени, а MongoDB или Hadoop – для анализа и долговременного хранения данных.

Веб-приложения производят много записей, при этом данные часто произвольно отформатированы и хранятся в локальной файловой системе. Это может вызвать такие проблемы:

  • Во-первых, логи будет трудно обработать с помощью других программ. Для этого понадобятся регулярные выражения. Следовательно, такие данные будут недоступны для тех, кто хочет понять поведение пользователя на основе статистического анализа или просмотреть результаты A/B-тестирования.
  • Во-вторых, логи не доступны в режиме реального времени (так как текстовые логи загружаются в системы хранения данных большими объёмами). Кроме того, если диск будет повреждён между загрузками данных, вы потеряете много записей.

Fluentd устраняет обе эти проблемы, предоставляя библиотеки для различных языков программирования. Здесь вы найдёте библиотеки для Ruby, Node.js, Go, Python, Perl, PHP, Java и C++.

Существует ещё много вариантов применения Fluentd и Elasticsearch.

Читайте также:

Tags: , , ,

Добавить комментарий