Ручные бекапы и обновления отнимают время? В статье разбираем, как автоматизировать выполнение задач на Ubuntu 24.04, включая резервное копирование VPS, и когда выбрать cron, а когда — systemd-таймеры для надёжного расписания.
Введение
Бекапы баз данных, обновление пакетов, ротация логов и мониторинг ресурсов — неизбежная часть работы с серверами. Их автоматизация высвобождает время для решения стратегических задач и снижает риски человеческих ошибок. В Ubuntu 24.04 доступны два встроенных инструмента для планирования: классический cron и systemd-таймеры, интегрированные в систему инициализации.
Cron — классический планировщик задач
Cron — стандартный инструмент планирования в Unix-системах, доступный в Ubuntu 24.04 «из коробки». Он отлично подходит для периодических задач, не требующих сложных зависимостей.
Синтаксис
Формат записи:
* * * * * /путь/к/команде
│ │ ││└─── день недели (от 0 до 7, где 0 и 7 означают воскресенье)
│ │ │└───── месяц (1-12)
│ │ └─────── день месяца (1-31)
│ └───────── час (0-23)
└─────────── минута (0-59)
* означает любое целое число, также можно задавать диапазон (1-5) и перечислять значения через запятую без пробелов (1,3,8).
Задачи добавляются в специальный файл (кронтаб) с помощью утилиты crontab. Команда crontab -e откроет его в текстовом редакторе по умолчанию.
Вместо классического формата * * * * * можно использовать псевдонимы:
- @daily вместо 0 0 * * * (ежедневно в полночь);
- @hourly — 0 * * * * (в начале каждого часа);
- @reboot — запуск один раз при нормальном старте системы (через systemctl reboot или аналоги); @reboot не сработает, если сервер был перезагружен из-за сбоя — для таких случаев используйте systemd-таймеры.
Вы можете задавать переменные окружения в начале кронтаб, например:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
HOME=/home/admin
SHELL=/bin/bash
После этого не нужно будет указывать полные пути в задачах:
0 5 * * * backup.sh # вместо /usr/local/bin/backup.sh
Обязательно указывайте HOME, без этого скрипты, использующие ~/.config, сломаются.
Примеры. Ежедневный бекап в 3:00:
0 3 * * * /opt/scripts/backup.sh
Запуск скрипта /opt/tasks/app.py каждые 10 минут по понедельникам:
*/10 * * * 1 /usr/bin/python3 /opt/tasks/app.py
обновление индекса и установленного ПО в 3:00 каждое 1-е число месяца (автоматическое выполнение apt upgrade -y не рекомендуется в продакшене!):
0 3 1 * * /usr/bin/apt update && /usr/bin/apt upgrade -y
Сценарии для хостинг-инфраструктуры
Бекап MySQL. Прямой пароль в cron-задаче — угроза безопасности. Чтобы автоматизировать резервное копирование и не навредить системе, сначала создайте файл конфигурации /root/.my.cnf с паролем:
[client]
user = имя_пользователя
password = пароль
Настройте права на него:
chmod 600 /root/.my.cnf
После этого добавьте задачу с указанием на файл с паролем:
0 4 * * * /usr/bin/mysqldump --defaults-file=/root/.my.cnf dbname > /backups/db_$(date +\%F).sql
Если используете % в командах (как в date +%F) экранируйте их:
date +\%F
Ротация логов Nginx. Очистка логов старше 30 дней:
0 0 * * * find /var/log/nginx/ -name "*.log" -mtime +30 -delete
Сжатие текущих логов:
0 1 * * * gzip /var/log/nginx/*.log
Команда для ежедневной проверки дискового пространства и отправки отчёта по корневому разделу /dev/nvme0n1p1 на email в 6:00 утра (для работы команды mail должен быть настроен почтовый сервер):
0 6 * * * df -h | grep -E 'Filesystem|/dev/nvme0n1p1' | mail -s "Disk Usage Report on $(hostname)" admin@example.com
Настройка доступа
Доступ к планировщику cron контролируется двумя файлами:
- /etc/cron.allow — если файл существует, то он содержит белый список пользователей;
- /etc/cron.deny — чёрный список.
Если файла cron.allow нет, то все пользователи, кроме перечисленных в cron.deny имеют доступ. Если оба файла отсутствуют, то доступ к кронтаб будет только у root.
Мониторинг
Просмотр активных задач для текущего пользователя:
crontab -l
Просмотр задач других пользователей (нужны права root):
crontab -u username -l
Ограничения cron
Несмотря на простоту и удобство, cron имеет недостатки, мешающие использовать его в сложных сценариях:
- Нет управления зависимостями — невозможно настроить cron на запуск задачи Y после успешного выполнения X.
- Слабая отладка — логи хранятся в /var/log/syslog вперемешку с другими событиями. Поиск ошибок:
grep CRON /var/log/syslog
- Отсутствие событийных триггеров — задачи запускаются строго по времени, а не по событиям (таким как заполнении диска, перезагрузка сервера, запуск другого процесса).
- Риски безопасности — задачи выполняются с правами создавшего их пользователя, и если в скрипте или файлах, к которым обращается задача, неправильно выставлены права, это может создать уязвимости.
Поэтому для задач, требующих перезапуска при сбое или сложных условий, используйте systemd-таймеры.
Systemd-таймеры
Systemd-таймеры — более гибкий способ автоматизации задач в Ubuntu 24.04. В отличие от cron, они интегрированы в систему инициализации, поддерживают зависимости между задачами, перезапуск при сбоях и событийные триггеры.
Принцип работы systemd-таймеров
Каждое задание состоит из двух файлов:
- Служба (.service) описывает что выполнять (команды, переменные окружения). Может быть двух типов: oneshot для разовых задач (аналог cron) и simple для фоновых процессов.
- Таймер (.timer) определяет когда или при каком условии запускать сервис. Поддерживает два типа триггеров:
- временные — по точному расписанию;
- событийные — при загрузке, изменении файлов, заполнении диска.
Преимущества перед cron:
- Возможен запуск сервиса, только если прошлое выполнение завершилось успешно (с помощью OnSuccess=);
- Автоматический перезапуск при сбое (Restart=on-failure);
- Централизованное логирование через journalctl;
- Интеграция с системными зависимостями (например, запуск только после подключения к сети).
Пример таймера для ежедневного бекапа
- Создаём сервис (например, /etc/systemd/system/backup.service):
[Unit]
Description=MySQL Daily Backup
After=network.target # запуск только после поднятия сети
[Service]
Type=oneshot
User=backup_user # запуск от непривилегированного пользователя
ExecStart=/bin/sh -c '/usr/bin/mysqldump -u admin -p's3cr3t' mydb | gzip > /backups/mydb_$(date +%%F).sql.gz'
ExecStopPost=/bin/sh -c 'echo "[$(date)] Backup completed" >> /var/log/backup.log'
- Создаём таймер (/etc/systemd/system/backup.timer):
[Unit]
Description=Run MySQL backup daily at 3 AM
[Timer]
OnCalendar=*-*-* 03:00:00 # ежедневно в 03:00
Persistent=true # запустить задачу после перезагрузки, если пропущена
AccuracySec=1m # погрешность ±1 минута (для экономии ресурсов)
[Install]
WantedBy=timers.target
- Активируем и проверяем:
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer # запустить таймер
# проверка статуса:
systemctl list-timers --all # все активные таймеры
journalctl -u backup.service # логи выполнения
Сценарии для хостинга
- Мониторинг доступности сайта (каждые 5 минут)
Таймер (/etc/systemd/system/site-monitor.timer):
[Timer]
OnBootSec=5m # первый запуск через 5 мин после загрузки
OnUnitActiveSec=5m # повтор каждые 5 мин после последнего завершения
Unit=site-monitor.service
[Install]
WantedBy=multi-user.target
Служба (/etc/systemd/system/site-monitor.service):
[Service]
Type=oneshot
ExecStart=/usr/bin/curl -Is https://yoursite.com | grep '200 OK' || echo "Site down" | mail -s "ALERT" admin@example.com
- Автообновление ОС с последующей перезагрузкой (воскресенье в 4:00)
Таймер (/etc/systemd/system/auto-update.timer):
[Timer]
OnCalendar=Sun *-*-* 04:00:00
RandomizedDelaySec=1h # случайная задержка от 0 до 60 минут для распределения нагрузки
[Install]
WantedBy=timers.target
Служба (/etc/systemd/system/auto-update.service):
[Service]
Type=oneshot
ExecStart=/bin/sh -c '/usr/bin/apt update && /usr/bin/apt upgrade -y && /sbin/reboot'
- Очистка кеша при заполнении диска (событийный триггер)
Таймер (/etc/systemd/system/clean-cache.timer):
[Timer]
OnFilesystemSpace=80% /var/cache # запуск при заполнении 80 % раздела
Unit=clean-cache.service
[Install]
WantedBy=multi-user.target
Служба (/etc/systemd/system/clean-cache.service):
[Service]
Type=oneshot
ExecStart=/usr/bin/find /var/cache/ -type f -mtime +7 -delete
Отладка и мониторинг работы systemd-таймеров
Просмотр всех таймеров:
systemctl list-timers --all
Тестирование сервиса без таймера (ручной запуск):
sudo systemctl start backup.service
Просмотр логов:
journalctl -u backup.service -f
Для анализа временного выражения используйте команду systemd-analyze calendar. Она проверит синтаксис, выведет дату и время ближайшего срабатывания и время, оставшееся до запуска. Пример:
systemd-analyze calendar '*-*-* 03:00:00'
Systemd-таймер или cron
Когда выбрать systemd вместо cron:
- для задач с зависимостями (например, запуск бекапа только после успешного экспорта БД);
- если требуется перезапуск при сбое;
- для интеграции с другими systemd-сервисами (nginx, docker);
- при использовании событийных триггеров (диск, загрузка ЦП).
Читайте в блоге:
- Основы работы с nftables на Ubuntu 24.04
- Настраиваем nftables для защиты веб-сервера на Ubuntu 24.04
- Как генерировать надёжные пароли на Ubuntu 24.04