Статьи

Централизованное ведение журнала системы и док-станции с помощью стека ELK

В Docker не было необходимости хранить журналы в файлах. Мы должны вывести информацию в stdout / stderr, а остальное позаботится сам Docker. Когда нам нужно проверить журналы, все, что мы должны сделать, это запустить docker logs [CONTAINER_NAME] .

Благодаря Docker и все более популярному использованию микросервисов количество развернутых контейнеров быстро растет. Журналы мониторинга для каждого контейнера в отдельности быстро становятся кошмаром. Мониторинг нескольких или даже десяти контейнеров по отдельности несложно. Когда это число начинает приближаться к десяткам или сотням, индивидуальная регистрация в лучшем случае нецелесообразна. Если мы добавим распределенные сервисы, ситуация станет еще хуже. Мало того, что у нас много контейнеров, но они распределены по многим серверам.

Решение заключается в использовании некоторого централизованного ведения журнала. Нашим любимым сочетанием является стек ELK ( ElasticSearch , LogStash и Kibana ). Однако централизованное ведение журнала с помощью Docker в больших масштабах не было тривиальной задачей (до выпуска версии 1.6). У нас было несколько решений, но ни одно из них не казалось достаточно хорошим.

Мы можем выставить каталог контейнера с журналами как том. С этого момента мы можем сказать LogStash отслеживать этот каталог и отправлять записи журнала в ElasticSearch. В качестве альтернативы мы могли бы использовать LogStash Forwarder и немного сэкономить на ресурсах сервера. Однако реальная проблема заключалась в том, что не было необходимости хранить журналы в файлах. С Docker мы должны выводить логи только в stdout, а об остальном нужно было позаботиться. Кроме того, показ томов — одна из моих самых нелюбимых вещей, связанных с Docker. Без открытых томов контейнеры гораздо проще рассуждать и перемещаться по разным серверам. Это особенно верно, когда набор серверов рассматривается как центр обработки данных, а контейнеры развертываются с помощью инструментов оркестрации, таких как Docker Swarm или Kubernetes .

Были и другие варианты, но все они были взломаны, сложны в настройке или требовали ресурсов.

Драйвер регистрации Docker

В версии 1.6 Docker представил функцию драйвера логирования. Хотя он прошел в основном незамеченным, это очень крутая возможность и огромный шаг вперед в создании комплексного подхода к регистрации в средах Docker.

В дополнение к стандартному драйверу json-файла, который позволяет нам просматривать журналы с помощью команды docker logs , теперь у нас есть выбор использовать syslog в качестве альтернативы. Если установлено, он будет направлять вывод контейнера (stdout и stderr) в системный журнал . В качестве третьего варианта также возможно полностью запретить запись вывода контейнера в файл. Это может сэкономить использование HD, когда это важно, но в большинстве случаев это то, что вряд ли кому-то понадобится.

В этой статье мы сконцентрируемся на syslog и способах централизации всех журналов в одном экземпляре ELK .

Docker Централизованная регистрация

Мы настроим стек ELK , используем драйвер журнала Docker syslog и, наконец, отправим все записи журнала в центральное место с помощью rsyslog . И syslog, и rsyslog предустановлены почти во всех дистрибутивах Linux.

Сначала мы пройдем ручные шаги. В конце статьи будут инструкции, как все настроить автоматически с помощью Ansible . Если вы нетерпеливы, просто прыгните до конца.

бродяга

Примеры в этой статье основаны на Ubuntu и предполагают, что Docker запущен и работает. Если это так, пожалуйста, пропустите эту главу. Для тех, у кого нет простого доступа к Ubuntu, мы подготовили Vagrant VM со всем необходимым. Если у вас его еще нет, установите VirtualBox и Vagrant . Когда все настроено, выполните следующие команды:

1
2
3
4
git clone https://github.com/vfarcic/docker-logging-elk.git
cd docker-logging-elk
vagrant up monitoring
vagrant ssh monitoring

После выполнения этих команд вы должны быть внутри оболочки Ubuntu с установленным Docker. Теперь мы готовы настроить ELK .

ElasticSearch

Мы будем хранить все наши журналы в базе данных ElasticSearch . Поскольку он использует формат JSON для хранения данных, будет легко отправить любой тип структуры журнала. Что еще более важно, ElasticSearch оптимизирован для поиска и анализа в реальном времени, что позволяет нам легко перемещаться по нашим журналам.

Давайте запустим официальный контейнер ElasticSearch с открытым портом 9200. Мы будем использовать том для сохранения данных БД в каталоге / data /asticsearch.

1
2
3
4
5
sudo mkdir -p /data/elasticsearch
sudo docker run -d --name elasticsearch
    -p 9200:9200
    -v /data/elasticsearch:/usr/share/elasticsearch/data
    elasticsearch

LogStash

LogStash — это идеальное решение для централизации обработки данных любого типа. Его плагины дают нам большую свободу для обработки любого ввода, фильтрации данных и создания одного или нескольких выходов. В этом случае входом будет системный журнал . Мы отфильтруем и изменим записи Docker, чтобы мы могли отличить их от остальной части системного журнала. Наконец, мы выведем результаты в ElasticSearch, который мы уже настроили.

Контейнер будет использовать официальное изображение LogStash. Он предоставит порт 25826, общий том хоста / data / logstash / config, который обеспечит требуемую конфигурацию, и, наконец, будет связан с ElasticSearch.

1
2
3
4
5
6
7
sudo docker run -d --name logstash
    --expose 25826
    -p 25826:25826
    -p 25826:25826/udp
    -v $PWD/conf:/conf
    --link elasticsearch:db
    logstash logstash -f /conf/syslog.conf

Этот контейнер был запущен с флагом -f, который позволяет нам указать конфигурацию, которую мы хотели бы использовать. Тот, который мы используем ( syslog.conf ), выглядит следующим образом.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
input {
  syslog {
    type => syslog
    port => 25826
  }
}
 
filter {
  if "docker/" in [program] {
    mutate {
      add_field => {
        "container_id" => "%{program}"
      }
    }
    mutate {
      gsub => [
        "container_id", "docker/", ""
      ]
    }
    mutate {
      update => [
        "program", "docker"
      ]
    }
  }
}
 
output {
  stdout {
    codec => rubydebug
  }
  elasticsearch {
    host => db
  }
}

Те, кто не используется в формате конфигурации LogStash, могут быть немного запутаны, поэтому давайте рассмотрим его. Каждая конфигурация может иметь, помимо прочего, секции ввода, фильтрации и вывода.

В разделе ввода мы говорим LogStash прослушивать события системного журнала на порту 25826 .

Секция фильтра немного более сложна и, в двух словах, она ищет docker как программу (драйвер регистрации Docker регистрируется как программа в формате docker / [CONTAINER_ID] ). Когда он находит такую ​​программу, он изменяет ее значение в новое поле container_id и обновляет программу, чтобы она была просто docker .

Наконец, мы выводим результаты в стандартный вывод (используя кодек rubydebug) и, что более важно, ElasticSearch .

Когда ElasticSearch запущен и запущен, а LogStash прослушивает события системного журнала, мы готовы установить rsyslog .

Rsyslog

rsyslog — очень быстрая система для обработки логов. Мы будем использовать его для доставки наших записей системного журнала в LogStash . Он уже предустановлен в Ubuntu, поэтому все, что нам нужно сделать, это настроить его для работы с LogStash.

1
2
sudo cp conf/10-logstash.conf /etc/rsyslog.d/.
sudo service rsyslog restart

Мы скопировали новую конфигурацию rsyslog и перезапустили сервис. Конфигурационный файл очень прост.

1
*.* @@10.100.199.202:25826

Он сообщает rsyslog об отправке всех записей системного журнала ( *.* ) В удаленное ( @@ ) местоположение ( 10.100.199.202:25826 ). В данном случае 10.100.199.202 — это IP Vagrant VM, который мы создали. Если вы используете свой собственный сервер, измените его на правильный IP. Кроме того, IP-адрес не является удаленным, поскольку в этом примере мы используем только один сервер. В сценариях «реального» мира вы должны установить rsyslog на каждом сервере так, чтобы он указывал на центральное расположение, в котором развернута ELK.

Теперь, когда мы собираем все события системного журнала и отправляем их в ElasticSearch , пришло время визуализировать наши данные.

Kibana

Kibana — это платформа для аналитики и визуализации, предназначенная для работы с данными в реальном времени. Он легко интегрируется с ElasticSearch.

В отличие от ElasticSearch и LogStash, официального изображения Kibana не существует, поэтому мы создали его для вас. Его можно найти в Docker Hub под vfarcic / kibana .

Мы выставим порт 5601 и свяжем его с контейнером ElasticSearch .

1
2
3
4
sudo docker run -d --name kibana
    -p 5601:5601
    --link elasticsearch:db
    vfarcic/kibana

Kibana позволяет нам легко настраивать информационные панели для удовлетворения потребностей, специфичных для проекта или организации. Если вы являетесь новым пользователем, вам лучше использовать пример Dashboard, созданный для демонстрации использования системных журналов и журналов Docker, поступающих из системного журнала.

Следующая команда с примером импорта настроек Kibana. Он будет использовать контейнер с инструментом ElasticDump , который предоставляет инструменты импорта и экспорта для ElasticSearch. Контейнер изготовлен по индивидуальному заказу и находится в Docker Hub по адресу vfarcic /astic-dump .

1
2
3
4
sudo docker run --rm
    -v $PWD/conf:/data
    vfarcic/elastic-dump --input=/data/es-kibana.json
    --output=http://10.100.199.202:9200/.kibana --type=data

После запуска этого контейнера конфигурация Kibana из файла es-kibana.json была импортирована в базу данных ElasticSearch, работающую 10.100.199.202:9200 .

Теперь мы можем взглянуть на панель управления Kibana, которую мы только что настроили. Откройте http: // localhost: 5601 в вашем любимом браузере.

На первом экране отображаются все нефильтрованные журналы. Вы можете добавлять столбцы в левой части экрана, создавать новые поиски и т. Д. Среди импортированных нами настроек Kibana есть сохраненный поиск, называемый ошибкой . Он фильтрует журналы так, что отображаются только те, которые содержат ошибку слова. Мы могли бы сделать это многими другими способами, но этот казался самым простым и простым. Откройте его, щелкнув значок « Загрузить сохраненный поиск» в правом верхнем углу экрана. На данный момент он показывает очень мало или вообще не содержит ошибок, поэтому давайте сгенерируем несколько поддельных.

1
2
3
logger -s -p 1 "This is fake error..."
logger -s -p 1 "This is another fake error..."
logger -s -p 1 "This is one more fake error..."

Обновите экран Kibana, и вы должны увидеть эти три сообщения об ошибках.

Помимо просмотра журналов в формате списка, мы можем создавать собственные панели мониторинга. Например, нажмите на верхнее меню Dashboard , затем Load Saved Dashboard и выберите error (еще одну, которую мы импортировали ранее).

kibana

Запуск контейнера с системным журналом

До этого момента мы видели только системные журналы, поэтому давайте запустим новый контейнер Docker и настроим его для использования драйвера журнала syslog .

1
2
3
4
sudo docker run -d --name bdd
    -p 9000:9000
    --log-driver syslog
    vfarcic/bdd

Если мы вернемся в Кибану, нажмем « Обнаружить» и откроем « Сохраненный поиск» с именем docker , должно быть не менее трех записей.

Вот и все. Теперь мы можем масштабировать это до необходимого количества контейнеров и серверов. Все, что нужно сделать, это настроить rsyslog на каждом сервере и запустить контейнеры с --log-driver syslog . Имейте в виду, что стандартная команда docker logs больше не будет работать. Это ожидаемое поведение. Журналы должны быть в одном месте, их легко найти, отфильтровать, визуализировать и т. Д.

Мы закончили с этой виртуальной машиной, поэтому давайте выйдем и остановим ее.

1
2
exit
vagrant halt

анзибль

Репозиторий, который мы клонировали в начале этой статьи, содержит еще две виртуальные машины Vagrant. Один ( лось ) содержит ElasticSearch, LogStash и Kibana. Другой ( docker-node ) — это отдельная машина с одним работающим контейнером Docker. Хотя ручная настройка хороша как учебное упражнение, оркестровка и развертывание должны быть автоматизированы. Один из способов сделать это с помощью Ansible, поэтому давайте повторим тот же процесс полностью автоматически.

1
2
vagrant up elk
vagrant up docker-node

Откройте Kibana в http: // localhost: 5601 . Это точно такая же настройка, как мы сделали вручную, но сделали это автоматически с Ansible.

Полный исходный код можно найти в репозитории GitHub vfarcic / docker-logging-elk . Не стесняйтесь взять и изменить настройку Ansible и адаптировать ее к своим потребностям.

Если у вас возникли проблемы с этой статьей или у вас возникли дополнительные вопросы, пожалуйста, оставьте комментарий или свяжитесь со мной по электронной почте (информация находится в разделе « О программе »).