Наш watchdog перезапустил службы, которые мы остановили намеренно
Операции
Один из наших watchdog запускает любую из наших служб, которая включена, но не работает. Дважды в октябре он запускал службы, которые мы остановили намеренно. Во второй раз посетители одного из наших сайтов получали ошибки примерно в течение 45 минут.
Зачем нужен этот watchdog
Служба, которая корректно завершается при получении SIGTERM, например потому, что ее убили по имени, не считается «failed» для systemd. Restart=on-failure не возвращает ее, а systemctl --failed не показывает ее в списке. Она остается остановленной, пока кто-нибудь случайно не заметит. Поэтому watchdog ищет службы, которые включены, но не работают, и запускает их.
Проблема в том, что служба, которую вы остановили вручную, выглядит точно так же.
Первый случай
7 октября мы остановили видеорабочий процесс с помощью systemctl stop в 12:47, чтобы изменить его очередь задач. В 12:55 он снова работал: watchdog его запустил.
Второй случай
21 октября нам потребовалась память машины, которая также обслуживает два наших сайта, для теста модели. Скрипт остановил веб-приложения сайтов, задачу синхронизации и контейнер базы данных, снова с помощью systemctl stop. Примерно через пять минут таймер, который следит за сайтами, а в 19:14 watchdog, вернули туннель и веб-приложения.
Туннель снова начал принимать трафик, но веб-приложения не могли отвечать: тестируемая модель занимала 114 ГиБ памяти машины. Примерно с 19:14 до 20:00 некоторые посетители получали ошибки 502. В 20:00 мы отключили туннель, веб-приложения и задачу синхронизации, а также остановили таймер наблюдения.
Правило, которое мы используем теперь
- Приостанавливайте службу, отключая ее:
sudo systemctl disable --now <unit>. Возвращайте ее с помощьюsudo systemctl enable --now <unit>. Наш watchdog смотрит только на включенные службы, поэтому отключенную он не трогает. - Приостановите все, что может ее вернуть: туннель перед ней и любой таймер, который за ней следит.
- Кратковременная остановка — это гонка. Если вы используете только
stop, закончите до следующей проверки, которая на наших машинах происходит в течение нескольких минут.
Еще две ловушки systemd за те же месяцы
systemctl mask --runtimeничего не делает для unit-файла в /etc/systemd/system. Unit-файлы в /etc имеют приоритет над runtime-маской в /run, поэтому команда завершается успешно, но сервис всё равно запускается. Чтобы удержать сервис, мы используем drop-in сConditionPathExists=!/etc/<name>.hold: пока этот файл существует, сервис не запустится ни при загрузке, ни вручную.systemctl is-activeсчитает запущенный oneshot-сервис неактивным. Пока сервисType=oneshotработает, его состояние — «activating», поэтомуis-activeвыводит это значение и возвращает 3. Цикл видаwhile systemctl is-active --quiet job.service; do sleep 60; done, предназначенный для ожидания ночной задачи, завершается сразу. Вместо этого проверяйте состояние: active, activating, reloading или deactivating означают, что процесс ещё идёт.
Factory Floor следит за включёнными сервисами, которые не запущены. По умолчанию он только сообщает о них и запускает их, только если вы включите эту опцию. Начиная с версии 1.0.3 в его оповещении также указано, как намеренно приостановить сервис, и в его runbook сказано то же самое.