Очень легкая система мониторинга с Телеграмом и Консулом

в 14:11, , рубрики: consul, docker, docker-compose, Go, telegram, Программирование

Очень легкая система мониторинга с Телеграмом и Консулом - 1

Всем счастья и добра!

Эволюционно так получилось, что в моем личном владении оказался не маленький зоопарк различных серверов: от дешевого Supermicro до топового (на момент выпуска) HP Gen 8. Все конечно связано оптикой и прочими радостями жизни.

Но сказ не про то, как сеть класть, и даже не про то, как сервера настраивать, а про то, как правильно просто на всем этом деле docker-compose сервисы поднимать и радоваться.

ИМХО про сервера

HP — классные ребята, мощная и надежная начинка, но только обслуживать с точки зрения физики ну очень не удобно после supermicro.
Supermicro — дешевые, удобные ребята, но функционала (ILO, прошивки, Smart Array ...) сильно таки меньше.

Казалось бы, что может быть проще: взял, сделал docker-compose.yaml, пару-тройку Dockerfile, запустил — профит. Но демон кроется в мелочах..

Прелюдия про сервера дана не просто так: а что если в каждом сервер по десятку-другому виртуалок, а в каждой виртуалке по сотни сервисов из десяток compose файлов? В довесок, нельзя забывать, что часть компонент просто как независимые сервисы существуют.

И вроде все работает. Но иногда наступает тот дивный чудный момент, когда приходит потребитель одного из сервисов с вопросом вида "а чего-то у меня уже неделю сервис такой-то немного не живой".
И вроде как клиент лояльный (сервис-то для него бесплатный), и вроде как трагедии не произошло, но возникает странное ощущение надвигающегося шторма нежданчиков и звонков в три ночи.

Поскольку важнейшим навыком любого программиста/девопсера/админа является способность вовремя реагировать на сигналы со стороны самой мягкой части тела чуть пониже спины, то я начал предпринимать соответствующие меры.

Но я был бы не я и не инженером-математиком, если бы не постарался сформулировать причины и возможные решения проблемы.

Дано

  • Зоопарк сервисов, запущенных как в докере, так и без него
  • Количество сервисов будет увеличиваться
  • Некоторые группы сервисов полностью изолированы (обычно в целях разграничения видимости/доступа)

Задача

  • Сделать так, чтобы ничего не падало. Чтобы поднималось само при падении
  • Использовать решения, которые возможны как для малого количества сервисов, так и для большого
  • Знать когда и что упало. Желательно не позже клиента.
  • Не тратить на настройку много времени

Решение

Во-первых, соблазн запускать сервисы с restart=always был отмечен судрожными воспоминаниями о багнутых контейнерах с нулевой задержкой при старте.
Во-вторых, курение docker-compose v3 показало, что что-то вроде такого есть, но при близком рассмотрении работает с большим количеством условностей.
В-третьих, использование Kubernetus и co., выглядело как выстрел из СРЗО Смерч в комара на расстоянии 100 метров.

После пары кружек крепкого рома кофе, в голову пришло воспоминание о Consul и consul-template.

consul-template

Изначально consul-template был сделан в качесве генерации конфигов на основе данных в Consul с авто обновлением, но сейчас его можно использовать в качестве некого аналога supervisord'a.

Образовалась следующая цепочка:

  • consul-template запускает приложение,
  • регистрируется как сервис в Consul (Service Register),
  • а я прикручиваю мониторинг на том-же консуле за счет событий и мониторинга изменений

Радуги, единороги и бабочки… Пока не осознал, что consul-template не умеет регистрироваться в Consul. 0_о
ссылка на Issue, которая ведет на Issue 2016 года

Однако идея все же была проста:

Очень легкая система мониторинга с Телеграмом и Консулом - 2

Уважаемый основатель Microsoft завещал нам всем быть ленивыми, ну а поскольку кто я такой, чтобы с ним спорить, то пошел искать альтернативные решения.

Внезапно оказалось, что легкого решения нет. Supervisord — тянет за собой питон (ничего против не имею, но как бы место жалко, особенно учитывая количество сервисов). Zabbix'ы и иже с ним — вроде хорошо, но либо тяжелые агенты, либо большая задержка.

#яжепрограммист, так что за готовку. Рецепт простой: возьмем go (итоговые файлы небольшие и самодостаточные, а крос-компилиция элементарна), горсть знаний по unix-процессам и много-много чая.

Хронология (Д — день старта):

  • Д+1 готовый, рабочий прототип
  • Д+2 исправлены все найденные баги
  • Д+3 отдано на растерзания коллегам
  • Д+4 аварийно исправлены найденные коллегами ошибки
  • Д+7 все было переписано заново
    ...

Наши дни

Сделан ультра легкий супервизор с возможностью конфигурирования количества перезапусков, интервалов между ними, автоматической (де)регистрацией в Consul, нотификацией в Telegram.
Параметры запуска можно сохранить в конфигурационный файл. Корневая часть вынесена как отдельная библиотека, добавлена возможность простой разработки расширений.

Пример

Допустим, есть сервис (назовем его /usr/local/bin/dummy) с большим количеством флагов для настройки. Он может иногда падать (не он такой, жизнь такая =( ).

Запускаем его с регистрацией в локальном агенте Consul:

monexec run --consul -- /usr/local/bin/dummy -a 1 -b 2 -c 3 --foo bar --foo baz --foo etc

Профит! По-умолчанию, monexec будет перезапускать его вечно с интервалом в 5 секунд.

Далее, мы хотим передать это администраторам для дальнейшего использования. Километровую строку запуска отправлять как-то не комильфо.

Генерируем скрипт запуска (все тоже самое, просто добавим флаг --generate):

 monexec run --generate --consul -- /usr/local/bin/dummy -a 1 -b 2 -c 3 --foo bar --foo baz --foo etc > dummy.yml

dummy.yml

services:
- label: stinger-desert
  command: /usr/local/bin/dummy
  args:
  - -a
  - "1"
  - -b
  - "2"
  - -c
  - "3"
  - --foo
  - bar
  - --foo
  - baz
  - --foo
  - etc
  stop_timeout: 5s
  restart_delay: 5s
  restart: -1
consul:
  url: http://localhost:8500
  ttl: 3s
  timeout: 1m0s
  register:
  - stinger-desert

Это нам создаст конфигурационный файл для дальнейшего использования.
Запускать его так:

 monexec start /path/to/dir/with/dummy

Важно! /path/to/dir/with/dummy — именно директория, а не путь до файла. (Навеяно Dockerfile'ами)

Теперь добавим счастливой жизни и грамма безумия: подключим оповещения в Telegram. Для этого нужно создать бота и узнать свой номер

dummy with telegram

services:
- label: stinger-desert
  command: /usr/local/bin/dummy
  args:
  - -a
  - "1"
  - -b
  - "2"
  - -c
  - "3"
  - --foo
  - bar
  - --foo
  - baz
  - --foo
  - etc
  stop_timeout: 5s
  restart_delay: 5s
  restart: -1
consul:
  url: http://localhost:8500
  ttl: 3s
  timeout: 1m0s
  register:
  - stinger-desert
telegram:
  token: "123456789:AAAAAAAAAAAAAAAAAAAAAA_BBBBBBBBBBBB"
  services:
      - "stinger-desert"
  recipients:
      - 123456789
  template: |
    *{{.label}}*
    Service {{.label}} {{.action}}
    {{if .error}}️ *Error:*  {{.error}}{{end}}
    _time: {{.time}}_
    _host: {{.hostname}}_

Итог

Как говорил один человек, создание чего-либо нового состоит из трех этапов:

  1. Идея
  2. Реализация
  3. Публикация

Хорошая или плохая идея и реализация (это решать вам) — все это не имеет ценности, если другие не могут этим пользоваться.

Я постарался создать документированный исходный код, руководство к использованию и собрать бинарные файлы под большинство платформ

Всем удачи!

Автор: LeshiyUrban

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js