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

Перестаём делать руками: cron и скрипты на каждом сервере

Набор shell-скриптов и cron-расписаний, которые мы держим на каждом Linux-сервере: чистка логов, ротация бэкапов, контроль свободного места и уведомления на почту.

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

скрипты и планировщик cron - основа автоматизации рутины на Linux-серверах

Есть задачи, которые не требуют ума - только регулярности. Проверить, не переполнился ли диск. Почистить старые логи. Убедиться, что вчерашний бэкап вообще существует. Отправить кому надо письмо, если что-то пошло не так.

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

Решение не новое - cron существует столько, сколько существует Unix. Но собрать из него рабочий набор, который не разваливается при первом исключении и не заваливает ящик мусорными письмами, - уже требует некоторого опыта.

Что вошло в базовый набор

Мы выделили четыре группы задач, которые теперь крутятся на каждом сервере автоматически.

Контроль свободного места. Самое простое и самое полезное. Скрипт проверяет все смонтированные разделы и, если заполненность превышает порог (держим 85%), отправляет письмо дежурному. Не 100%, не «когда уже всё умерло», а заранее - пока ещё есть время разобраться. Реализация - десять строк bash, запуск каждые два часа:

#!/bin/bash
THRESHOLD=85
MAILTO="admin@company.ru"
df -H | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{print $5 " " $1}' | while read output; do
    usage=$(echo $output | awk '{print $1}' | sed 's/%//')
    partition=$(echo $output | awk '{print $2}')
    if [ $usage -ge $THRESHOLD ]; then
        echo "Заполнен на ${usage}%: $partition" | mail -s "DISK ALERT: $(hostname)" $MAILTO
    fi
done

Чистка логов. logrotate на Debian ставится и настраивается, но мы дополнительно чистим руками то, что он не трогает: логи приложений в нестандартных местах, временные файлы, накопившийся мусор в /tmp. Скрипт с find ... -mtime +30 -delete по нужным директориям, запуск раз в неделю в воскресенье ночью. Раньше эти директории росли тихо и незаметно - пока однажды не съедали диск в самый неподходящий момент.

Проверка бэкапов. После того как мы наладили автоматические дампы баз, возник следующий вопрос: а дамп-то вообще создался? Скрипт проверяет, что в директории бэкапов есть файл с сегодняшней датой в имени и размер у него не нулевой. Если файла нет или он пустой - письмо. Это отловило нас пару раз: один раз закончилось место именно в момент дампа, один раз крякнул mount на NAS и скрипт писал в никуда, считая что всё в порядке.

Ротация бэкапов. Хранить бэкапы бесконечно - значит снова упереться в диск. Держим семь дней ежедневных, четыре недельных (по воскресеньям), один месячный (первое число). Скрипт ротации запускается после создания бэкапа и удаляет лишнее. Логика несложная, но прописать её руками один раз - и голова свободна.

Как устроен crontab

Всё хранится в /etc/cron.d/ отдельными файлами по задачам - не в одном общем crontab, который через полгода никто не понимает. Структура файла стандартная:

# Контроль диска - каждые 2 часа
0 */2 * * * root /usr/local/sbin/check-disk.sh

# Чистка tmp и старых логов - воскресенье 03:00
0 3 * * 0 root /usr/local/sbin/cleanup-old-files.sh

# Проверка бэкапов - каждый день в 08:00
0 8 * * * root /usr/local/sbin/check-backups.sh

Запуск от root нужен не везде - где можно, запускаем от отдельного пользователя с минимальными правами. Но не будем притворяться: на большинстве серверов всё идёт от рута, потому что так быстрее.

Куда идут уведомления

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

Отдельная проблема - не заваливать себя ложными срабатываниями. Если скрипт пишет письмо при каждом запуске «на всякий случай» - письма перестают читать через три дня. Письмо должно приходить только когда что-то не так, и формулировка должна сразу говорить что именно и где.

Что не автоматизируем

Реагирование на проблему - руками. Скрипт может найти переполненный диск и сообщить, но что с ним делать дальше - решает человек. Автоматическое удаление файлов «чтобы освободить место» - это путь к тому, что однажды скрипт удалит что-то важное. Не делаем.

Сейчас набор скриптов у нас стабилизировался примерно на восьми штуках. Берём их с собой на каждый новый сервер - адаптируем пути и пороги, разворачиваем. Первые пару часов после появления нового сервера он уже сам за собой следит.

Контакт

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

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