Здесь я хочу рассказать о быстром старте с помощью Docker.
Напишу заранее, что статья ориентирована на тех кто уже знаком с Docker и имеет желание поднять стек ELK для ознакомления или будущего использования в продуктиве. А для тех кто не знает нужен ли им ELK, рекомендую причитать статью Kibana-мать или Зачем вам вообще нужны логи?.
Итак, в идеале задача сводится к тому, чтобы найти контейнер с ELK на hub.docker.com и запустить его. Предлагаю так и сделать с некоторыми доработками. В примере рассмотрим отправку логов nginx в elasticSearch.
Аббревиатура сервисов ELK предусматривает следующие задачи:
1) Обработку поступающих данных и доставку их в Elasticsearch — за это отвечает сервис Logstash
2) Поисковый движок и интерфейс доступа к данным — за это отвечают сам Elasticsearch и Kibana
Но по хорошему Logstash не должен отвечать за доставку данных. Доставку данных делегируем четвертому сервису — Filebeat.
Общая схема работы выглядит следующим образом:
В сети может находится различное количество сервисов, с которых необходимо собирать данные и сервис Filebeat является провайдером логов для сервиса Logstash.
Другими словами я веду к тому, что нам необходимо заиметь еще один контейнер с сервисом Filebeat.
Приступим к делу. Я настоятельно рекомендую вам пользоваться сервисом Docker Compose — описывать параметры в одном файле формата YAML, гораздо удобнее чем каждый раз выполнять команды с параметрами. А на этапе отладки запустить и остановить придется не 1 раз.
1. Создадим папку с проектом, например myElk и создадим там файл следующего имени docker-compose.yml, который мы будем дополнять.
2. Ищем и находим контейнер с filebeat. Я рекомендую взять вот этот olinicola/filebeat или выполнить docker pull olinicola/filebeat
Настройка контейнера с filebeat заключается в подготовке конфигурационного файла в формате YAML для сервиса filebeat.
У нас он будет выглядеть следующим образом:
prospectors:
-
paths:
- "/etc/logs/nginx/access.log"
document_type: nginx-access
-
paths:
- "/var/log/nginx/error.log"
document_type: nginx-error
output:
logstash:
hosts: ["elk:5044"]
tls:
certificate_authorities:
- /etc/pki/tls/certs/logstash-beats.crt
timeout: 15
file:
path: "/tmp/filebeat"
Если коротко, то берем логи nginx с определенного места сервера и отправляем их на ELK сервер, который готов принимать от нас сообщения на порт 5044.
В данном конфигурационном файле «elk» — имя прилинкованного контейнера — подробнее ниже.
Я также дополнительно указал выгрузку в файл, для более удобной отладке на этапе запуска.
На данном этапе вы уже можете дополнить docker-compose.yml следующим кодом:
version: '2'
services:
filebeat:
build: .
image: [ваш imageId образа filebeat]
volumes:
- /path/to/myElk/log/nginx:/etc/logs/nginx # логи nginx
- /path/to/myElk/filebeat:/etc/filebeat
- /path/to/myElk/filebeat/tmp:/tmp/filebeat
Вы уже можете запустить поднять контейнер командой docker-compose up. И посмотреть как при изменении файла access.log данные будут отправляться в файл "/tmp/filebeat", только на данном этапе еще нет контейнера elk, поэтому output logstash лучше закомментировать.
3. Ок, нас появился первый контейнер с filebeat. Теперь нам нужен второй контейнер с ELK. Идем на hub.docker.com и находим sebp/elk или выполняем команду docker pull sebp/elk.
Настройка контейнера ELK.
Единственное, что нужно настроить здесь это logstash, причем тут 2 варианта: а) оставить все как есть и это будет работать, так как logstash в данном контейнере уже настроен на получение логов nginx сервера.
Однако после того как вы запуститесь вам захочется пойти по пути б)-то есть настроить логи так как нужно именно вам. Потому что от того как будут переданы логи в elasticsearch вам будет более или менее удобно анализировать данные, приходящие с nginx.
Итак поясню файлы конфигурации logstash. Файлы логов, которые нас интересуют следующие:
Входные параметры:
02-beats-input.conf — можно не трогать
input {
beats {
port => 5044
ssl => true
ssl_certificate => "/etc/pki/tls/certs/logstash-beats.crt"
ssl_key => "/etc/pki/tls/private/logstash-beats.key"
}
}
Здесь мы видим, что сервис готов принимать данные по порту 5044.
Выходные параметры:
30-output.conf — можно не трогать
output {
elasticsearch {
hosts => ["localhost"]
sniffing => true
manage_template => false
index => "%{[@metadata][beat]}-%{+YYYY.MM.dd}"
document_type => "%{[@metadata][type]}"
}
stdout { codec => rubydebug }
}
Самое интересное — преобразование данных. По умолчанию файл 11-nginx.conf выглядит так
filter {
if [type] == "nginx-access" {
grok {
match => { "message" => "%{NGINXACCESS}" }
}
}
}
Но возможно после того как вы наиграетесь с шаблоном NGINXACCESS вы захотите обработать ваши логи именно так как нужно вам.
Для этого вам нужно будет изменять секцию filter. Там может быть несколько параметров — очень хорошо описано здесь Собираем, парсим и отдаём логи с помощью Logstash.
От себя хочу добавить, что для отладки grok фильтров хорошо подходит следующий сервис: Grok Debugger
3. Компоновка 2х контейнеров.
Здесь я настоятельно рекумендую вам пользоваться сервисом Docker Compose — описывать параметры в одном файле формата YAML, гораздо удобнее чем каждый раз выполнять команды с параметрами. А на этапе отладки запустить и остановить придется не 1 раз.
Для этого вам необходимо создать папку с проектом, например myElk и создать там файл следующего имени docker-compose.yml и например следующего содержания:
version: '2'
services:
filebeat:
build: .
image: [ваш imageId образа filebeat]
volumes:
- /path/to/myElk/log/nginx:/etc/logs/nginx # логи nginx
- /path/to/myElk/filebeat:/etc/filebeat
- /path/to/myElk/filebeat/tmp:/tmp/filebeat
- /path/to/myElk/filebeat/certs:/etc/pki/tls/certs
links:
- "elk"
depends_on:
- "elk"
#entrypoint: ./time-to-start.sh
elk:
image: [ваш imageId образа elk]
ports:
- "5601:5601" #kibana
- "9200:9200" #elastic
- "5044:5044" #logstash beats filebeat
Данный конфигурационный файл описывает два контейнера и их взаимосвязь, а т
Пробуйте запустить контейнер, если все ОК, то по адресу localhost:5601 вы увидите первую страницу Kibana, где вам нужно будет выбрать первый index, он будет сформирован вида filebeat-[дата], наберите filebeat и если данные начали поступать, то он будет сформирован автоматически.
Для тех кто запускает docker на mac — вам необходимо будет дополнительно пробросить порты через проброс портов VirtualBox, чтобы localhost:5601 был доступен на хостовой машине.
Комментарии (16)
k3NGuru
04.05.2016 05:04+1Вообще не понял, где тут ELK контейнер?
Вот тут https://github.com/sqshq/ELK-docker отличный docker-compose для сбора ELK.
dyakhnov
04.05.2016 05:43Если Kibana в Docker будет падать с OOM ошибкой:
https://github.com/elastic/kibana/issues/5170
kt97679
04.05.2016 06:04+1Прежде чем строить ELK инфраструктуру настоятельно рекомендую оценить потянет ли она ваши объемы логирования и во что выльется поддержка. Я уже больше года пытаюсь приручить этого зверя (в частности для логирования из контейнеров) и на данный момент принято решение отказаться от ELK, использовать обычный syslog, логи загружать в hadoop и анализировать уже там. Для отслеживания ситуации в реальном времени использовать стриминг on demand возможно с минимальной фильтрацией. ELK не взлетел, хотя мы очень старались.
Sheh
04.05.2016 08:53Расскажите подробнее. Стоит такая же задача.
Почему приняли решение отказаться?
Производительность сильно упала по сравнению с syslog? Что, если в ELK отправлять не всё подряд, а наиболее значимую информацию?
для отслеживания ситуации в реальном времени использовать стриминг on demand
Как вы это реализуете и с помощью чего?kt97679
04.05.2016 19:33+1Вот мои предыдущие комментарии на эту тему:
https://habrahabr.ru/company/uteam/blog/278729/#comment_8799489
https://habrahabr.ru/post/275815/#comment_8751947
Кратко подытоживая: причины отказа низкая производительность, плохое масштабирование и проблемы со стабильностью. На данный момент у меня кластер А 10 машин (каждая машина 24 ядра 48 гб памяти) с трудом тянет 15к логов в секунду. На кластере Б памяти 128 гб на машину, что дает порядка 50к логов в секунду. Это при дневных индексах, 7-ми дневно ретеншене и около 1000 шард на кластер А, около 3000 шард на кластер Б. Если переключится на часовые индексы и снизить ретеншен до 3-х дней количество шард на кластере Б поднимается до 25к и он начинает падать с завидной периодичностью. У всех машин стоит по 4 диска 1.8тб. На кластере А количество документов около 7г и диски заняты от 26% до 45%, на кластере Б документов около 3.5г, диски заняты от 9% до 14%. Полный траффик логов у меня 130 логов/с, что значит мне нужно кластер А расширить до как минимум 200 машин, что будет 2 миллиона долларов только на покупку железа, обслуживание встанет в отдельные деньги. Глядя на подобные суммы начинаешь уже задумываться о спланке, который безумно дорог, но тебе вообще не надо думать об инфраструктуре.
Real time log streaming пока в стадии обдумывания. Самое простое решение, которое на данный момент обсуждается, это логировать все в локальные файлы на лог сервере с очень короткой ротацией и tail-ом отдавать их по http возможно фильтруя grep-ом. Но это предварительно, возможно все будет сложнее.
Отвечая на ваш вопрос об ограничении трафика в ELK: да, на маленьких объемах все работает нормально. Только вот объяснить людям, что не надо лить в логи все подряд (у меня был прецедент, когда начали заливали целиком http ответы, каждый log entry был за 100к) задача крайне не простая. И опять же мое крайне субъективное мнение: когда кто-то требует ELK утверждая, что только так он может гарантировать нормальную работу своего сервиса скорее всего что-то сильно не так с самим сервисом.tolkkv
05.05.2016 11:08Интересный опыт, спасибо. Подскажите, а к какому решению в итоге пришли? Что занимается сбором/агрегацией потока логов у вас?
shuvalov
04.05.2016 09:11+1у sebp/elk есть один минус — до недавнего времени он не использовал тэги, кроме latest. Сейчас с этим чуть лучше. Мы на эти грабли наступили однажды, когда latest переключился на новый logstash, который стал несовместим с нашими конфигами. Рекомендую в продакшене использовать не один контейнер, а три, примерно по такой схеме:
logstash: image: logstash:2.1.1 links: - elasticsearch elasticsearch: image: elasticsearch:2.2.2 kibana: image: kibana:4.3.1 ports: - 5601:5601 links: - elasticsearch
tolkkv
Спасибо за статью, приятно видеть, что ELK стек активно развивается.
Я еще не пробовал filebeat, но у меня сразу возникают два вопроса:
1 — если будет рестарт filebeat, то как он узнает с какого места перечитывать файл? Или же он снова начнет отправлять все файлы?
2 — Вы сказали, что logstash не должен отвечать за доставку данных и этим должен заниматься filebeat. Но не объяснли — почему? :)
gibson_dev
Он хранит состояние работы и в частности смещение файла до которого он уже отправил данные
tolkkv
Интересно было как и где, но ссылка ниже дает исчерпывающий ответ)
deklin
Logstash может выступать в качестве шиппера логов, конечно, но футпринт, мягко говоря, значительный. Написан на JRuby, требует целую JVM и гору памяти. Ставить такого монстра на каждый хост — лучше ресурсы веб-серверу или аппликухе отдать… А вот filebeat — это наследник logstash-forwarder (экс. lumberjack) — написан на Go, быстрый, портабельный (один бинарник) и нетребовательный к ресурсам. Что еще надо от агента?
robertsz
Здравствуйте. Ответ на вопрос 1: filebeat ведет свой реестр, чтобы знать где было последнее чтение. Можно посмотреть здесь: https://www.elastic.co/guide/en/beats/filebeat/current/_updating_the_registry_file.html
Ответ на вопрос 2: Даже если посмотреть на сайт https://www.elastic.co то в разделении по продуктам вы увидете, что logstash занимается своими задачами, а доставка данных вынесена в отдельные сервисы. Этих сервисов у вас может быть много, а сервер обработки данных 1.