MAATRIX / Блог / Graylog в Docker Compose: готовый файл

Graylog в Docker Compose: готовый файл

MAATRIX

Логи разбросаны по десятку серверов, grep по SSH превращается в квест, а найти причину сбоя за пределами последних суток невозможно — знакомая ситуация для любого, кто вырос из одиночного VPS. Graylog закрывает эту задачу без тяжести полного ELK-стека: один compose-файл, три контейнера, и через 15 минут у вас центральный поиск по логам с алертами. Ниже — рабочая конфигурация с граблями, на которые обычно наступают при первом запуске.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Что такое Graylog и чем он отличается от ELK

Graylog — платформа централизованного сбора, поиска и алертинга по логам с открытым ядром. По сути это надстройка с готовым UI, ролями, стримами и алертами над поисковым движком — в отличие от связки Elasticsearch + Kibana + Logstash, где UI и логику обработки приходится собирать из отдельных частей самостоятельно.

Технически Graylog состоит из трёх компонентов:

  • MongoDB — хранит конфигурацию: пользователей, стримы, правила обработки, настройки алертов. Логи в ней не лежат, нагрузка минимальная.
  • OpenSearch (или Elasticsearch в старых версиях) — поисковый и индексный движок, куда фактически попадают сами события. Основной потребитель RAM и диска.
  • Graylog Server — принимает логи через инпуты (GELF, Syslog, Beats, HTTP), обрабатывает их через pipeline-правила и отдаёт веб-интерфейс.

Если нужен просто быстрый просмотр логов контейнеров без стримов и алертов, для небольшого проекта иногда достаточно связки полегче — сравнение подходов есть в статье Grafana или Kibana: что выбрать для сервера и в статье про логи в Grafana Loki. Graylog оправдан, когда логов становится много, источников — несколько, а искать и алертить по ним нужно из одного места с ролевым доступом для команды.

Что подготовить на хосте до запуска

OpenSearch внутри Graylog требует тех же настроек ядра, что и обычный Elasticsearch/OpenSearch — это частый источник «контейнер не стартует» на первом запуске.

vm.max_map_count. OpenSearch использует mmap для файлов индекса и без правки лимита либо не запускается, либо падает через минуту-две с ошибкой max virtual memory areas vm.max_map_count [65530] is too low:

sudo sysctl -w vm.max_map_count=262144
echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.d/99-opensearch.conf
sudo sysctl --system

Память. Три контейнера сразу — MongoDB (легкая, обычно достаточно 512 МБ–1 ГБ), OpenSearch (главный потребитель, минимум 2 ГБ для теста, от 4 ГБ для рабочей нагрузки) и сам Graylog Server (1–2 ГБ на JVM). Итого для стабильного старта закладывайте от 6 ГБ RAM на сервер, для активного приёма логов с нескольких источников — от 8–12 ГБ.

Диск. Индексы в OpenSearch занимают больше, чем исходный объём логов — закладывайте 1.5–2x от сырого объёма плюс запас под retention (сколько дней логи хранятся до ротации индексов — настраивается в самом Graylog).

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Готовый docker-compose.yml

Однопиточная (single-node) конфигурация для теста и небольшого прод-инстанса без отказоустойчивости:

services:
  mongodb:
    image: mongo:6.0
    container_name: graylog-mongodb
    restart: unless-stopped
    volumes:
      - graylog_mongo:/data/db
    networks:
      - graylog-net

  opensearch:
    image: opensearchproject/opensearch:2.15.0
    container_name: graylog-opensearch
    restart: unless-stopped
    environment:
      - "OPENSEARCH_JAVA_OPTS=-Xms2g -Xmx2g"
      - bootstrap.memory_lock=true
      - discovery.type=single-node
      - action.auto_create_index=false
      - plugins.security.disabled=true
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536
    mem_limit: 4g
    volumes:
      - graylog_opensearch:/usr/share/opensearch/data
    networks:
      - graylog-net

  graylog:
    image: graylog/graylog:6.1
    container_name: graylog
    restart: unless-stopped
    depends_on:
      - mongodb
      - opensearch
    environment:
      - GRAYLOG_PASSWORD_SECRET=${GRAYLOG_PASSWORD_SECRET}
      - GRAYLOG_ROOT_PASSWORD_SHA2=${GRAYLOG_ROOT_PASSWORD_SHA2}
      - GRAYLOG_HTTP_EXTERNAL_URI=http://YOUR_SERVER_IP:9000/
      - GRAYLOG_MONGODB_URI=mongodb://mongodb:27017/graylog
      - GRAYLOG_ELASTICSEARCH_HOSTS=http://opensearch:9200
    mem_limit: 2g
    ports:
      - "9000:9000/tcp"     # веб-интерфейс и REST API
      - "12201:12201/udp"   # GELF UDP input
      - "12201:12201/tcp"   # GELF TCP input
      - "1514:1514/udp"     # Syslog UDP input
    volumes:
      - graylog_journal:/usr/share/graylog/data/journal
    networks:
      - graylog-net

volumes:
  graylog_mongo:
  graylog_opensearch:
  graylog_journal:

networks:
  graylog-net:
    driver: bridge

Версии образов указаны для примера — перед запуском сверьте актуальные теги в Docker Hub для graylog/graylog и opensearchproject/opensearch и зафиксируйте конкретную версию вместо latest. Важный нюанс: конкретный релиз Graylog поддерживает конкретный диапазон версий OpenSearch — сверьтесь с матрицей совместимости в документации перед выбором тегов, иначе Graylog Server откажется подниматься с ошибкой несовместимости.

Файл .env рядом с compose:

GRAYLOG_PASSWORD_SECRET=минимум-16-случайных-символов
GRAYLOG_ROOT_PASSWORD_SHA2=sha256-хеш-пароля-администратора

PASSWORD_SECRET — генерируется один раз и используется для подписи сессий, менять его после первого запуска нельзя (все сессии слетят):

openssl rand -hex 32

ROOT_PASSWORD_SHA2 — это не сам пароль, а его SHA-256 хеш, Graylog никогда не хранит пароль в открытом виде даже в переменной окружения:

echo -n "ваш-пароль-администратора" | sha256sum | awk '{print $1}'

Логин по умолчанию — admin, пароль — тот, что вы захешировали выше.

Первый вход и приём логов

После docker compose up -d MongoDB и OpenSearch стартуют быстро, а Graylog Server ждёт их готовности и может подниматься 1–2 минуты. Прогресс видно в логах:

docker compose logs -f graylog

Веб-интерфейс — http://ваш-сервер:9000. Порт 9000 в конфиге выше открыт наружу для простоты примера — на боевом сервере правильнее держать его за реверс-прокси с TLS и ограничением доступа по IP или VPN; общий подход к такой связке разобран в статье про изоляцию сервисов через Docker.

Логи в Graylog попадают не сами — нужно завести input. В интерфейсе: System → Inputs → выбираете тип → Launch new input.

Для приложений и Docker-контейнеров чаще всего используют GELF (родной формат Graylog, компактнее обычного JSON):

docker run --log-driver gelf --log-opt gelf-address=udp://ваш-сервер:12201 ваш-образ

Для системных логов и сетевого оборудования — Syslog UDP на порту 1514, большинство роутеров и Linux-хостов умеют слать syslog «из коробки» через rsyslog:

# /etc/rsyslog.d/90-graylog.conf на источнике
*.* @ваш-сервер:1514

Быстрая проверка, что GELF-инпут вообще принимает данные:

echo '{"version":"1.1","host":"test","short_message":"hello graylog"}' | \
  nc -u -w1 ваш-сервер 12201

Сообщение должно появиться в разделе Search в интерфейсе в течение нескольких секунд.

Стримы и алерты

Стрим в Graylog — правило, которое сортирует входящие сообщения по условиям (источник, уровень, текст) в отдельную «папку» для поиска. Без стримов всё летит в общий Default Stream, и найти нужное на большом потоке становится тяжело.

Создаётся в Streams → Create Stream, дальше добавляются правила через Manage Rules — например, «все сообщения, где application_name равен вашему сервису» или «уровень (level) меньше либо равен 3» (error и выше по синтаксису syslog severity).

Алерты строятся поверх стримов через Alerts → Event Definitions: указываете условие (например, больше N сообщений с уровнем error за 5 минут в конкретном стриме) и notification — куда слать уведомление. Из коробки есть email и HTTP-webhook, поэтому оповещение в Telegram настраивается через промежуточный вебхук-бот — общий принцип такой настройки для VPS описан в статье про алерты в Telegram, Graylog в этой схеме просто ещё один источник, дергающий тот же вебхук-эндпоинт.

Практический совет: не заводите один алерт «на всё подряд» — с ростом трафика он превратится в шум, который команда начнёт игнорировать. Лучше несколько узких алертов на конкретные стримы с разумным порогом срабатывания — Graylog умеет ограничивать частоту повторных уведомлений по одному условию (throttling).

Ресурсы, retention и типичные ошибки при старте

Ориентир по ресурсам в зависимости от объёма (именно ориентир — точные цифры зависят от размера сообщений и глубины retention):

СценарийRAM всегоOpenSearch heapДиск
Тест / один проект, немного логов4–6 ГБ1–2g20–30 ГБ
Небольшая инфраструктура, 3–5 серверов8 ГБ2–3gот 100 ГБ
Активный сбор логов с алертингом12–16 ГБ4gот 200 ГБ, растёт
Логи нескольких команд/сервисов16 ГБ+4–8gпо объёму + запас на индексы

Retention (сколько хранить логи до удаления старых индексов) настраивается в System → Indices — по умолчанию Graylog ротирует индексы по размеру или по времени и удаляет самые старые, когда их накопится больше заданного количества. Если диск начинает расти быстрее, чем ожидалось, стоит свериться с общим подходом к ротации логов — в статье про ротацию логов разобраны похожие механизмы для файловых логов, идея та же: хранить не «всё вечно», а разумный горизонт под задачу.

Частые причины проблем при первом запуске:

  • OpenSearch не стартует, в логах max virtual memory areas ... is too low — не выставлен vm.max_map_count=262144 на хосте (см. выше).
  • Graylog Server крутится в рестарте, в логах ошибка про несовместимость версий OpenSearch — версия образа opensearchproject/opensearch не входит в поддерживаемый диапазон для выбранной версии graylog/graylog; проверьте матрицу совместимости в документации перед фиксацией тегов.
  • GRAYLOG_PASSWORD_SECRET too short — секрет должен быть не короче 16 символов, иначе Graylog Server откажется стартовать с явной ошибкой в логе.
  • Вход по admin не проходит — чаще всего ROOT_PASSWORD_SHA2 содержит хеш с лишним переносом строки; используйте echo -n, а не echo, при генерации хеша.
  • Логи не появляются в Search, хотя input запущен — проверьте, что порт инпута (12201/UDP или 1514/UDP) действительно проброшен и не блокируется файрволом на хосте между источником и Graylog.

Диагностика в целом:

docker compose ps
docker compose logs --tail 100 graylog
curl -s http://localhost:9000/api/system/lbstatus   # ALIVE = сервер готов принимать трафик

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

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Чем Graylog принципиально отличается от связки Elasticsearch + Kibana?

Тем, что UI, роли пользователей, стримы и алерты идут в комплекте и настраиваются через интерфейс, а не собираются из отдельных инструментов. Под капотом всё равно поисковый движок (OpenSearch), но работать с ним приходится намного меньше.

Обязательно ли использовать именно OpenSearch, а не Elasticsearch?

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

Сколько логов Graylog способен принимать на одном сервере?

Зависит от размера сообщений, числа полей и объёма RAM под OpenSearch — универсальной цифры нет. Начинайте с конфигурации из раздела «Ресурсы» под ваш объём и следите за docker stats в первую неделю, чтобы понять реальный профиль нагрузки.

Можно ли использовать Graylog для соответствия требованиям по хранению логов (комплаенс)?

Технически да — retention настраивается гибко, есть ролевой доступ и аудит действий. Но сама по себе платформа не заменяет юридическую консультацию по срокам и составу хранимых данных для конкретной отрасли.

Нужен ли отдельный сервер под Graylog или можно на общем с приложением?

Для теста — можно на общем, но OpenSearch довольно требователен к CPU при активной записи и поиске, и на общем сервере с продакшен-приложением может создавать заметную конкуренцию за ресурсы. Для рабочей нагрузки лучше выносить на отдельный инстанс.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →