ADG Оставить заявку
Блог DevOps 5 мин чтения

Zabbix на Docker-хостах: почему мы ушли на Prometheus и Grafana

Перевели мониторинг Docker-инфраструктуры клиента с Zabbix на Prometheus+Grafana: pull-модель сбора метрик органично ложится на среду с ephemeral-контейнерами.

Контекст момента

Prometheus и Grafana 3.x набирают популярность как стек метрик для контейнерных сред в начале 2016 года

Несколько недель назад мы обновили Docker до 1.10 на инфраструктуре одного из клиентов на сопровождении. Параллельно копилась другая проблема: Zabbix, который мониторил эти хосты, начал вести себя странно - не в смысле падений, а в смысле того, что данные по контейнерам получались неполные и запоздалые. Это был хороший момент, чтобы пересмотреть подход к мониторингу в целом.

В чём конкретно ломался Zabbix

Zabbix работает по push-модели с агентом на каждом хосте. Агент собирает метрики и отправляет на сервер. Для классических физических и виртуальных серверов это нормально: хост живёт месяцами, у него постоянный IP, агент зарегистрирован и всё идёт по расписанию.

С Docker ситуация другая. Контейнеры запускаются и останавливаются в ходе деплоев, при автомасштабировании, в CI-пайплайнах. У контейнера нет постоянного IP - точнее, он есть внутри Docker-сети, но это не тот IP, по которому Zabbix умеет регистрировать агент. В итоге:

  • Контейнер поднялся. Zabbix не знает о нём, пока не добавишь хост руками или через LLD-правило, которое срабатывает с задержкой.
  • Контейнер упал и поднялся на другом хосте. В Zabbix висит старый хост со статусом unreachable, новый нужно добавлять заново.
  • Метрики самих контейнеров. Через cAdvisor с Zabbix-интеграцией - можно, но кривовато. Нужны кастомные скрипты, шаблоны, которые надо поддерживать вручную.

Мы гоняли такую схему через Zabbix UserParameters и внешние скрипты несколько месяцев. Работало, но каждый раз при изменении инфраструктуры требовало ручного вмешательства. На инфраструктуре в 20-30 контейнеров это ещё терпимо. На 80+ - нет.

Почему Prometheus, а не InfluxDB+Telegraf

На момент, когда мы начали смотреть на альтернативы, популярны были два направления: InfluxDB с Telegraf как агентом-коллектором и Prometheus как самостоятельная система мониторинга со своей pull-моделью. Мы смотрели на оба.

InfluxDB + Telegraf - нормальный стек, Telegraf умеет собирать Docker-метрики через Docker Remote API. Но это всё та же push-схема: Telegraf-агент на хосте толкает данные в InfluxDB. Для нас это не решало основную проблему - регистрацию новых контейнеров.

Prometheus использует pull-модель: сервер сам ходит к экспортерам по HTTP и забирает метрики. Экспортер - это просто HTTP-эндпоинт, который отдаёт метрики в текстовом формате. Для Docker-хостов есть cAdvisor, который поднимается как контейнер и сразу экспортирует метрики всех контейнеров на хосте. Prometheus раз в 15 секунд ходит к cAdvisor - и получает актуальную картину по всем контейнерам, включая те, что только что запустились.

Ключевой момент: Prometheus не нужно знать о контейнерах заранее. Он знает о cAdvisor на хосте, а cAdvisor уже разбирается с контейнерами сам. Это принципиально меняет операционную нагрузку.

Что поставили и как это выглядит

Стек получился такой:

  • node_exporter на каждом хосте - метрики CPU, памяти, дисков, сети на уровне ОС.
  • cAdvisor на каждом хосте как контейнер - метрики по каждому контейнеру.
  • Prometheus 0.17 как центральный сервер - хранение метрик и алертинг через Alertmanager.
  • Grafana 2.6 как дашборд. (Grafana 3.0 пока в бете, стабильный релиз на подходе, но в продакшн ставить рано.)

Конфиг Prometheus для двух хостов выглядит примерно так:

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'node'
    static_configs:
      - targets:
          - 'host1.internal:9100'
          - 'host2.internal:9100'

  - job_name: 'cadvisor'
    static_configs:
      - targets:
          - 'host1.internal:8080'
          - 'host2.internal:8080'

cAdvisor поднимается одной строкой:

docker run -d \
  --name=cadvisor \
  --volume=/:/rootfs:ro \
  --volume=/var/run:/var/run:rw \
  --volume=/sys:/sys:ro \
  --volume=/var/lib/docker/:/var/lib/docker:ro \
  --publish=8080:8080 \
  google/cadvisor:latest

После этого http://host1.internal:8080/metrics сразу отдаёт метрики по всем контейнерам - без дополнительной настройки, без регистрации.

Grafana: вопросы к дашбордам

Grafana 2.6 работает, но дашборды для Prometheus/cAdvisor пришлось строить самим. Grafana.net с каталогом готовых дашбордов только появляется, и на русскоязычных проектах искать их не приходится. Потратили день на построение базовых дашбордов:

  • Обзор кластера: загрузка CPU и памяти по хостам, количество контейнеров.
  • Детальный вид по хосту: все контейнеры, потребление ресурсов в динамике.
  • Алерты: CPU хоста выше 80%, свободная память ниже 512 МБ, контейнер в состоянии OOMKilled.

PromQL - язык запросов Prometheus - поначалу непривычный. Не SQL, не InfluxQL. Но базовые паттерны берутся быстро. Пример - топ-5 контейнеров по потреблению CPU за последние 5 минут:

topk(5, rate(container_cpu_usage_seconds_total{image!=""}[5m]))

Что не понравилось

Честно: Prometheus сейчас - молодой проект, версия 0.17, и это ощущается.

Alertmanager - отдельный бинарь, конфиг в отдельном файле. Логика группировки и дедупликации алертов есть, но документация местами скудная. Потратили время на разбор.

Долгосрочное хранение - Prometheus хранит данные локально, retention по умолчанию 15 дней. Для трендов на месяц и квартал нужно либо увеличивать retention и объём диска, либо смотреть в сторону remote storage. Решения для этого только начинают появляться.

Service discovery при добавлении новых хостов - пока ручная правка конфига и reload. Поддержка Consul и EC2 в Prometheus есть, но для нашей инфраструктуры мы её ещё не настроили.

Текущий статус

Перевели два кластера - итого около 90 контейнеров. Prometheus опрашивает cAdvisor каждые 15 секунд и никакой ручной работы при деплоях не требует. Когда при нагрузке поднялись дополнительные контейнеры, Prometheus просто начал собирать с них метрики - мы это заметили уже по дашборду, не по событию регистрации.

На Zabbix переводить обратно не планируем. Он остался на legacy-хостах без Docker, где push-модель нормально работает. Разные задачи - разные инструменты.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.