Уведомления на почту об остановленных docker контейнерах

Система домашней автоматизации Home Assistant может быть установлена в различных конфигурациях, часть которых представляют собой набор контейнеров (например, hass.io и hassOS). Сам Home Assistant, supervisor и прочие компоненты бегут в своих собственных контейнерах, также как и различные полезные аддоны для hass.io. Кроме этого, дополнительное ПО также удобнее держать в отдельных контейнерах, например, zerotier-one для создания VPN или отдельного MQTT брокера.

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

Очевидно, невозможно использовать правила автоматизации Home Assistant для мониторинга доступности самого Home Assistant, поэтому нужно найти другое решение. В итоге я остановился на monit как на самом зрелом и распространённом решении для мониторинга всего.

Идея очень простая - нужно создать shell скрипт, который будет запрашивать у docker статус контейнеров. Если какой-либо из контейнеров остановился, скрипт вернёт код, отличный от нуля. monit будет периодически запускать скрипт и отправляь сообщение на электронную почту или другим доступным способом, в случае, если один или несколько контейнеров остановлены.

Docker healthcheck

Docker предлагает встроенные возможности мониторинга состояния контейнера, которые позволяют отрабатывать ситуации, когда статус контейнера не меняется, но сервис внутри него перестаёт выполнять свои функции. Чтобы использовать инструкцию HEALTHCHECK необходимо внести изменения в Dockerfile контейнера, что, в случае аддонов hassio, является довольно сложной задачей. Кроме того, наличие инструкции HEALTHCHECK не обеспечит отправки нотификаций пользователю, это всё равно нужно делать самому. Описанный ниже скрипт, хотя и не сможет определить зависший сервис внутри “работающего” контейнера, позволяет отлавливать большую часть ошибок и при этом добавление новых контейнеров требуют минимальное количество усилий. Скрипт, при желании, можно изменить так, чтобы вместо команды docker status он использовал docker inspect для проверки здоровья контейнера.

Shell скрипт

Создадим скрипт мониторинга:

$ mkdir ~/monit
$ cd ~/monit
$ touch monit_docker_check.sh
$ chmod +x monit_docker_check.sh

Содержимое скрипта дано ниже. Нужно заменить список контейнеров именами из вашего собственного docker, разделёнными пробелами. Список имён контейнеров можно получить командой docker ps (колонка “Names”).

#!/bin/sh
list_of_containers="homeassistant addon_a0d7b954_appdaemon3 hassio_supervisor"
containers=`docker ps -f status=running --format "{{.Names}}"`
for container in $list_of_containers
do
  if echo $containers |grep -q $container
    then  echo "$container online "
  else echo "$container offline"
    exit 1
  fi
done
exit 0

Чтобы убедиться, что скрипт работает, его нужно запустить и проверить код ошибки, который он возвратит. Если хотя бы один контейнер из списка остановлен, скрипт должен вернуть 1.

$ ./monit_docker_check.sh
appdaemon online
hassio_supervisor online
homeassistant offline
$ echo $?
1

Настройка сервера почты в monit

Если почта в monit не была настроена ранее, ниже инструкция как это сделать. В большинстве linux дистрибутивов конфигурацонный файл monit находится в /etc/monit/monitrc . Откройте файл в редакторе

$ sudo nano /etc/monit/monitrc

и добавьте следующие строчки в конец файла:

set mailserver smtp.gmail.com port 587
    username "user" password "password"
    using tlsv1

set alert mymail@gmail.com

Если в качестве почты используется gmail, необходимо получить пароль приложения, так как обычный пароль работать не будет. Чтобы проверить работу почтовых уведомлений, добавьте следующие строчки в конец файла monitrc.

check file alerttest with path /.nonexistent
   alert mymail@gmail.com

Сохраните файл и обновите конфигурацию monit:

$ sudo monit reload
Reinitializing monit daemon

На почту должно придти тестовое уведомление, после чего тестовое правило можно удалить.

Add a check rule to monitrc

Теперь нужно добавить правило проверки docker контейнеров. Добавьте следующие строчки в конец файла monitrc (замените /home/user/monit на правильное местоположение shell скрипта).

check program docker_check with path /home/user/monit/monit_docker_check.sh
with timeout 500 seconds
if status = 1 then alert

Monit будет проверять состояние контейнеров и отправлять сообщение на почту, если что-то пойдёт не так. Перезагрузите конфигурацию monit:

$ sudo monit reload
Reinitializing monit daemon 

Проверка работоспособности

Остановите один из контейнеров командой docker stop либо добавьте несуществующий контейнер в shell скрипт. Monit должен прислать на почту уведомление об остановленном контейнере. Когда контейнер придёт в работоспособное состояние, monit пришлёт второе уведомление о том, что всё в порядке. Главное, не забывать добавлять вновь созданные контейнеры в список проверки, иначе monit не будет знать об их существовании.