Task Scheduler (Планировщик задач) в VyOS

Task Scheduler в VyOS - это встроенная система для планирования и автоматического выполнения команд и скриптов в определенное время или через регулярные интервалы. Функционал построен на основе системного планировщика cron, но предоставляет удобный интерфейс конфигурации через CLI.

Обзор

Task Scheduler позволяет:

  • Автоматизировать повторяющиеся задачи администрирования
  • Выполнять резервное копирование конфигурации по расписанию
  • Запускать скрипты мониторинга и диагностики
  • Периодически очищать логи и временные файлы
  • Выполнять операции обслуживания в нерабочие часы
  • Интегрироваться с внешними системами через API-вызовы

Возможности

  • Гибкое расписание: минуты, часы, дни недели, дни месяца, месяцы
  • Cron-совместимый синтаксис
  • Выполнение как операционных команд VyOS, так и shell-команд
  • Интеграция с системой логирования (syslog)
  • Поддержка скриптов (bash, python)

Синтаксис расписания

Task Scheduler использует стандартный cron-синтаксис с пятью полями:

* * * * *
│ │ │ │ │
│ │ │ │ └─── День недели (0-7, где 0 и 7 = воскресенье)
│ │ │ └───── Месяц (1-12)
│ │ └─────── День месяца (1-31)
│ └───────── Час (0-23)
└─────────── Минута (0-59)

Специальные символы

СимволОписаниеПример
*Любое значение* * * * * - каждую минуту
,Список значений0,15,30,45 * * * * - 0, 15, 30, 45 минут каждого часа
-Диапазон значений0 9-17 * * * - каждый час с 9:00 до 17:00
/Шаг (интервал)*/5 * * * * - каждые 5 минут
*/nКаждые n единиц0 */2 * * * - каждые 2 часа

Примеры расписаний

# Каждую минуту
* * * * *

# Каждые 5 минут
*/5 * * * *

# Каждый час в 0 минут
0 * * * *

# Ежедневно в 2:30 AM
30 2 * * *

# Каждый понедельник в 9:00 AM
0 9 * * 1

# Первый день каждого месяца в полночь
0 0 1 * *

# Каждые 15 минут в рабочие часы (9-17) в будние дни
*/15 9-17 * * 1-5

# Каждое воскресенье в 3:00 AM
0 3 * * 0

Базовая конфигурация

Создание задачи

# Общий синтаксис
set system task-scheduler task <task-name> interval <cron-expression>
set system task-scheduler task <task-name> executable path <command/script>

# Пример: ежедневное резервное копирование конфигурации в 2:00 AM
set system task-scheduler task backup-config interval '0 2 * * *'
set system task-scheduler task backup-config executable path '/config/scripts/backup.sh'

commit
save

Выполнение VyOS операционных команд

# Сохранение конфигурации каждый час
set system task-scheduler task save-config interval '0 * * * *'
set system task-scheduler task save-config executable path '/opt/vyatta/sbin/vyatta-save-config.pl'

commit
save

Выполнение shell-команд

# Очистка старых логов раз в день
set system task-scheduler task cleanup-logs interval '0 3 * * *'
set system task-scheduler task cleanup-logs executable path '/usr/bin/find /var/log -name "*.gz" -mtime +30 -delete'

commit
save

Задачи с аргументами

# Скрипт с параметрами
set system task-scheduler task monitor-bandwidth interval '*/10 * * * *'
set system task-scheduler task monitor-bandwidth executable path '/config/scripts/bandwidth-monitor.sh'
set system task-scheduler task monitor-bandwidth executable arguments 'eth0 eth1'

commit
save

Расширенная конфигурация

Резервное копирование конфигурации на удаленный сервер

# Создание скрипта резервного копирования
configure
set system task-scheduler task remote-backup interval '0 2 * * *'
set system task-scheduler task remote-backup executable path '/config/scripts/remote-backup.sh'
commit
save

Содержимое /config/scripts/remote-backup.sh:

#!/bin/bash

# Конфигурация
BACKUP_SERVER="192.168.1.100"
BACKUP_USER="backup"
BACKUP_DIR="/backups/vyos"
HOSTNAME=$(hostname)
DATE=$(date +%Y%m%d-%H%M%S)
BACKUP_FILE="config-${HOSTNAME}-${DATE}.boot"

# Сохранение текущей конфигурации
/opt/vyatta/sbin/vyatta-save-config.pl /tmp/${BACKUP_FILE}

# Копирование на удаленный сервер через SCP
scp -i /config/auth/backup-key /tmp/${BACKUP_FILE} ${BACKUP_USER}@${BACKUP_SERVER}:${BACKUP_DIR}/

# Очистка локального файла
rm -f /tmp/${BACKUP_FILE}

# Логирование
logger -t remote-backup "Configuration backed up to ${BACKUP_SERVER}"

# Удаление старых бэкапов (старше 30 дней) на удаленном сервере
ssh -i /config/auth/backup-key ${BACKUP_USER}@${BACKUP_SERVER} \
  "find ${BACKUP_DIR} -name 'config-${HOSTNAME}-*.boot' -mtime +30 -delete"

Сделать скрипт исполняемым:

sudo chmod +x /config/scripts/remote-backup.sh

Мониторинг и алерты

# Проверка доступности критических сервисов каждые 5 минут
set system task-scheduler task service-monitor interval '*/5 * * * *'
set system task-scheduler task service-monitor executable path '/config/scripts/service-monitor.sh'

commit
save

Содержимое /config/scripts/service-monitor.sh:

#!/bin/bash

# Список сервисов для проверки
SERVICES=("ssh" "dhcpd")

# Email для алертов
ALERT_EMAIL="admin@example.com"

# Проверка каждого сервиса
for service in "${SERVICES[@]}"; do
    if ! systemctl is-active --quiet "$service"; then
        # Сервис не запущен - отправка алерта
        echo "ALERT: Service $service is not running on $(hostname)" | \
          mail -s "VyOS Service Alert" $ALERT_EMAIL

        # Логирование
        logger -t service-monitor -p user.err "Service $service is not running"

        # Попытка перезапуска
        systemctl restart $service

        if systemctl is-active --quiet "$service"; then
            logger -t service-monitor -p user.notice "Service $service restarted successfully"
        fi
    fi
done

Очистка старых логов и временных файлов

# Еженедельная очистка в воскресенье в 4:00 AM
set system task-scheduler task weekly-cleanup interval '0 4 * * 0'
set system task-scheduler task weekly-cleanup executable path '/config/scripts/cleanup.sh'

commit
save

Содержимое /config/scripts/cleanup.sh:

#!/bin/bash

# Удаление старых сжатых логов (старше 60 дней)
find /var/log -name "*.gz" -mtime +60 -delete

# Удаление старых core dumps
find /var/core -type f -mtime +7 -delete

# Очистка temporary files старше 7 дней
find /tmp -type f -mtime +7 -delete

# Очистка старых DHCP leases
# (осторожно: может потребоваться корректировка под вашу среду)
# find /var/lib/dhcp -name "*.leases~" -mtime +30 -delete

# Логирование
logger -t weekly-cleanup "Weekly cleanup completed"

Интеграция с API для внешних систем

# Отправка метрик в систему мониторинга каждые 15 минут
set system task-scheduler task send-metrics interval '*/15 * * * *'
set system task-scheduler task send-metrics executable path '/config/scripts/send-metrics.sh'

commit
save

Содержимое /config/scripts/send-metrics.sh:

#!/bin/bash

# Конфигурация
MONITORING_SERVER="http://monitoring.example.com:8086"
INFLUXDB_TOKEN="your-token-here"
HOSTNAME=$(hostname)

# Сбор метрик
CPU_LOAD=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | tr -d ',')
MEM_USAGE=$(free | awk '/Mem:/ {printf "%.2f", ($3/$2)*100}')
DISK_USAGE=$(df -h / | awk '/\// {print $5}' | tr -d '%')

# Отправка в InfluxDB
curl -X POST "${MONITORING_SERVER}/write?db=network_devices" \
  -H "Authorization: Token ${INFLUXDB_TOKEN}" \
  --data-binary "cpu_load,host=${HOSTNAME} value=${CPU_LOAD}
memory_usage,host=${HOSTNAME} value=${MEM_USAGE}
disk_usage,host=${HOSTNAME} value=${DISK_USAGE}"

# Логирование
logger -t send-metrics "Metrics sent to monitoring server"

Ротация конфигураций с Git

# Ежедневный commit конфигурации в Git репозиторий
set system task-scheduler task git-backup interval '0 1 * * *'
set system task-scheduler task git-backup executable path '/config/scripts/git-backup.sh'

commit
save

Содержимое /config/scripts/git-backup.sh:

#!/bin/bash

# Конфигурация Git
GIT_REPO="/config/git-backup"
CONFIG_FILE="/config/config.boot"
HOSTNAME=$(hostname)

# Инициализация репозитория (если нужно)
if [ ! -d "${GIT_REPO}/.git" ]; then
    mkdir -p ${GIT_REPO}
    cd ${GIT_REPO}
    git init
    git config user.email "vyos@${HOSTNAME}"
    git config user.name "VyOS Task Scheduler"
fi

cd ${GIT_REPO}

# Копирование текущей конфигурации
cp ${CONFIG_FILE} ${GIT_REPO}/config.boot

# Commit изменений
git add config.boot
git commit -m "Automated backup on $(date '+%Y-%m-%d %H:%M:%S')"

# Push в удаленный репозиторий (опционально)
# git push origin main

# Логирование
logger -t git-backup "Configuration committed to Git"

Проверка VPN туннелей

# Проверка IPsec туннелей каждые 10 минут
set system task-scheduler task check-vpn interval '*/10 * * * *'
set system task-scheduler task check-vpn executable path '/config/scripts/check-vpn.sh'

commit
save

Содержимое /config/scripts/check-vpn.sh:

#!/bin/bash

# Список peer'ов для проверки
PEERS=("site-b" "site-c")

# Email для алертов
ALERT_EMAIL="network-ops@example.com"

# Проверка каждого peer
for peer in "${PEERS[@]}"; do
    # Проверка состояния туннеля
    STATUS=$(vtysh -c "show vpn ipsec sa" | grep -c "ESTABLISHED")

    if [ "$STATUS" -eq 0 ]; then
        # Туннель не установлен
        echo "VPN tunnel to ${peer} is DOWN on $(hostname) at $(date)" | \
          mail -s "VPN Alert: ${peer}" $ALERT_EMAIL

        logger -t check-vpn -p user.err "VPN tunnel to ${peer} is DOWN"

        # Попытка перезапуска
        sudo ipsec restart
        sleep 10

        # Повторная проверка
        STATUS_AFTER=$(vtysh -c "show vpn ipsec sa" | grep -c "ESTABLISHED")
        if [ "$STATUS_AFTER" -gt 0 ]; then
            logger -t check-vpn -p user.notice "VPN tunnel to ${peer} restored after restart"
        fi
    fi
done

Примеры конфигураций

Пример 1: Базовое резервное копирование

# Ежедневное резервное копирование конфигурации в 2:00 AM
set system task-scheduler task daily-backup interval '0 2 * * *'
set system task-scheduler task daily-backup executable path '/config/scripts/backup.sh'

commit
save

Скрипт /config/scripts/backup.sh:

#!/bin/bash
DATE=$(date +%Y%m%d)
/opt/vyatta/sbin/vyatta-save-config.pl /config/backups/config-${DATE}.boot
# Удаление старых бэкапов (старше 7 дней)
find /config/backups -name "config-*.boot" -mtime +7 -delete
logger -t daily-backup "Configuration backup completed"

Пример 2: Мониторинг интерфейсов

# Проверка состояния интерфейсов каждые 5 минут
set system task-scheduler task interface-monitor interval '*/5 * * * *'
set system task-scheduler task interface-monitor executable path '/config/scripts/interface-monitor.sh'

commit
save

Скрипт /config/scripts/interface-monitor.sh:

#!/bin/bash

INTERFACES=("eth0" "eth1")
ALERT_EMAIL="admin@example.com"

for iface in "${INTERFACES[@]}"; do
    STATUS=$(ip link show $iface | grep -c "state UP")

    if [ "$STATUS" -eq 0 ]; then
        echo "Interface $iface is DOWN on $(hostname)" | \
          mail -s "Interface Alert" $ALERT_EMAIL
        logger -t interface-monitor -p user.err "Interface $iface is DOWN"
    fi
done

Пример 3: Периодическая очистка DHCP leases

# Еженедельная очистка старых DHCP leases
set system task-scheduler task cleanup-dhcp interval '0 3 * * 0'
set system task-scheduler task cleanup-dhcp executable path '/usr/bin/systemctl restart isc-dhcp-server'

commit
save

Пример 4: Обновление динамического DNS

# Обновление DDNS каждые 30 минут (если нет встроенного DDNS)
set system task-scheduler task update-ddns interval '*/30 * * * *'
set system task-scheduler task update-ddns executable path '/config/scripts/update-ddns.sh'

commit
save

Скрипт /config/scripts/update-ddns.sh:

#!/bin/bash

DDNS_URL="https://dyndns.example.com/update"
DDNS_TOKEN="your-token-here"
HOSTNAME="router.example.com"

# Получение внешнего IP
CURRENT_IP=$(curl -s ifconfig.me)

# Обновление через API
curl -X POST "${DDNS_URL}" \
  -H "Authorization: Bearer ${DDNS_TOKEN}" \
  -d "hostname=${HOSTNAME}&ip=${CURRENT_IP}"

logger -t update-ddns "DDNS updated with IP ${CURRENT_IP}"

Пример 5: Ежемесячная перезагрузка (Maintenance Window)

# Перезагрузка в первое воскресенье месяца в 5:00 AM
set system task-scheduler task monthly-reboot interval '0 5 1-7 * 0'
set system task-scheduler task monthly-reboot executable path '/sbin/reboot'

commit
save

Пример 6: Статистика трафика

# Сбор статистики интерфейсов каждый час
set system task-scheduler task traffic-stats interval '0 * * * *'
set system task-scheduler task traffic-stats executable path '/config/scripts/traffic-stats.sh'

commit
save

Скрипт /config/scripts/traffic-stats.sh:

#!/bin/bash

STATS_FILE="/var/log/traffic-stats.log"
DATE=$(date '+%Y-%m-%d %H:%M:%S')

# Получение статистики для eth0
RX_BYTES=$(cat /sys/class/net/eth0/statistics/rx_bytes)
TX_BYTES=$(cat /sys/class/net/eth0/statistics/tx_bytes)

# Запись в лог
echo "${DATE},eth0,${RX_BYTES},${TX_BYTES}" >> ${STATS_FILE}

# Логирование в syslog
logger -t traffic-stats "Statistics collected: RX=${RX_BYTES}, TX=${TX_BYTES}"

Мониторинг и диагностика

Просмотр настроенных задач

# Показать все задачи
show system task-scheduler

# Показать конфигурацию в формате команд
show configuration commands | match task-scheduler

Проверка cron jobs

# Просмотр активных cron jobs
sudo crontab -l

# Логи выполнения cron
show log | match CRON
grep CRON /var/log/syslog

Мониторинг выполнения задач

# Просмотр syslog для задач планировщика
show log | match task-scheduler

# Последние 50 записей cron
show log tail 50 | match CRON

# Real-time мониторинг
monitor log | match CRON

Тестирование скрипта вручную

# Запуск скрипта напрямую для тестирования
sudo /config/scripts/backup.sh

# Проверка прав на выполнение
ls -l /config/scripts/

# Просмотр вывода скрипта
sudo bash -x /config/scripts/backup.sh

Проверка последнего выполнения

# Просмотр временных меток файлов (для скриптов, создающих файлы)
ls -lt /config/backups/

# Логи последнего выполнения
sudo grep "task-name" /var/log/syslog | tail -20

Устранение неполадок

Проблема: Задача не выполняется

Диагностика:

# 1. Проверка конфигурации задачи
show configuration system task-scheduler task <task-name>

# 2. Проверка cron
sudo crontab -l | grep <task-name>

# 3. Проверка логов cron
grep CRON /var/log/syslog | tail -50

# 4. Проверка прав на скрипт
ls -l /config/scripts/<script-name>

# 5. Ручной запуск скрипта
sudo /config/scripts/<script-name>

Решение:

# Сделать скрипт исполняемым
sudo chmod +x /config/scripts/<script-name>

# Проверить синтаксис cron-выражения (должен быть в кавычках)
set system task-scheduler task <task-name> interval '*/5 * * * *'

# Перезапуск cron (если необходимо)
sudo systemctl restart cron

commit
save

Проблема: Скрипт выполняется, но не работает корректно

Диагностика:

# Запуск с debug-выводом
sudo bash -x /config/scripts/<script-name>

# Перенаправление вывода в файл для анализа
sudo /config/scripts/<script-name> > /tmp/debug.log 2>&1
cat /tmp/debug.log

# Проверка переменных окружения
sudo env | sort

Решение:

Добавить логирование в скрипт:

#!/bin/bash

# Включить debug
set -x

# Логирование начала
logger -t my-script "Script started"

# Ваш код здесь
...

# Логирование завершения
logger -t my-script "Script completed"

# Перенаправление stderr в syslog
exec 2> >(logger -t my-script)

Проблема: Задача выполняется слишком часто или редко

Диагностика:

# Проверка cron-выражения
show configuration system task-scheduler task <task-name> interval

# Тестирование расписания online
# Используйте https://crontab.guru для проверки синтаксиса

Решение:

# Примеры корректировки частоты

# Было: каждую минуту (слишком часто)
# * * * * *

# Изменено: каждые 5 минут
set system task-scheduler task <task-name> interval '*/5 * * * *'

# Было: каждый день в 2:00 AM (слишком редко для критичной задачи)
# 0 2 * * *

# Изменено: каждые 6 часов
set system task-scheduler task <task-name> interval '0 */6 * * *'

commit
save

Проблема: Задача не находит команды или файлы

Причина: Cron выполняется с ограниченным PATH и без полного окружения.

Решение:

# В начале скрипта указать полный PATH
#!/bin/bash

# Установка PATH
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# Явно указывать полные пути к командам
/usr/bin/curl https://example.com
/opt/vyatta/sbin/vyatta-save-config.pl /tmp/config.boot

# Для VyOS operational commands
source /opt/vyatta/etc/functions/script-template

Проблема: Нет вывода/логов от задачи

Решение:

Добавить перенаправление вывода в конфигурацию:

# Изменить скрипт для логирования всего вывода
#!/bin/bash

# Перенаправить stdout и stderr в syslog
exec 1> >(logger -t my-task -p user.info)
exec 2> >(logger -t my-task -p user.err)

# Теперь весь вывод будет в syslog
echo "This will appear in syslog"

Или перенаправить в файл:

set system task-scheduler task <task-name> executable path '/config/scripts/script.sh >> /var/log/task.log 2>&1'

Проблема: Задача конфликтует с другими операциями

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

Решение:

Использовать блокировку (locking) в скрипте:

#!/bin/bash

LOCKFILE="/var/run/my-task.lock"

# Проверка существования lock file
if [ -f "$LOCKFILE" ]; then
    logger -t my-task "Task already running, exiting"
    exit 1
fi

# Создание lock file
touch $LOCKFILE

# Trap для удаления lock file при завершении
trap "rm -f $LOCKFILE" EXIT

# Основная логика скрипта
...

# Lock file будет удален автоматически при exit

Лучшие практики

1. Исполняемые права и shebang

Всегда добавляйте shebang и делайте скрипты исполняемыми:

#!/bin/bash
# Ваш скрипт

# Сделать исполняемым
sudo chmod +x /config/scripts/script.sh

2. Логирование

Всегда логируйте выполнение задач:

#!/bin/bash

logger -t my-task "Task started"

# Ваша логика

logger -t my-task "Task completed successfully"

3. Обработка ошибок

Добавляйте обработку ошибок:

#!/bin/bash

set -e  # Остановка при ошибке

# Или явная проверка
if ! command_that_might_fail; then
    logger -t my-task -p user.err "Command failed"
    exit 1
fi

4. Полные пути

Используйте абсолютные пути для команд и файлов:

# Плохо
cp config.boot /tmp/

# Хорошо
/bin/cp /config/config.boot /tmp/config-backup.boot

5. Тестирование

Тестируйте скрипты вручную перед добавлением в планировщик:

# Запуск вручную
sudo /config/scripts/script.sh

# С debug
sudo bash -x /config/scripts/script.sh

6. Документирование

Комментируйте скрипты и задачи:

# Создание задачи с описательным именем
set system task-scheduler task daily-config-backup interval '0 2 * * *'
set system task-scheduler task daily-config-backup executable path '/config/scripts/backup.sh'

# В скрипте
#!/bin/bash
# Description: Daily configuration backup to remote server
# Author: Network Team
# Last modified: 2025-10-14

7. Мониторинг выполнения

Настройте мониторинг критических задач:

# Отправка статуса в систему мониторинга
curl -X POST https://monitoring.example.com/heartbeat/task-name

8. Очистка временных файлов

Удаляйте временные файлы после использования:

#!/bin/bash

TEMP_FILE="/tmp/temp-$$.txt"

# Trap для очистки
trap "rm -f $TEMP_FILE" EXIT

# Использование temp file
...

9. Безопасность

Не храните пароли в скриптах:

# Плохо
PASSWORD="secret123"

# Хорошо - используйте SSH keys или токены в защищенных файлах
API_KEY=$(cat /config/auth/api-key.txt)

10. Расписание и нагрузка

Распределяйте задачи во времени:

# Избегайте множественных задач в одно время
# Плохо:
# Backup: 0 2 * * *
# Cleanup: 0 2 * * *
# Report: 0 2 * * *

# Хорошо:
# Backup: 0 2 * * *   (2:00 AM)
# Cleanup: 0 3 * * *  (3:00 AM)
# Report: 0 4 * * *   (4:00 AM)

Полезные команды

# Показать все задачи
show system task-scheduler

# Конфигурация в формате commands
show configuration commands | match task-scheduler

# Просмотр crontab
sudo crontab -l

# Логи cron
show log | match CRON
grep CRON /var/log/syslog

# Ручной запуск скрипта
sudo /config/scripts/script.sh

# Проверка прав
ls -l /config/scripts/

# Тестирование с debug
sudo bash -x /config/scripts/script.sh

# Мониторинг выполнения
monitor log | match task-name

# Редактирование скрипта
edit /config/scripts/script.sh

# Проверка синтаксиса bash-скрипта
bash -n /config/scripts/script.sh

# Перезапуск cron (если нужно)
sudo systemctl restart cron

# Статус cron
sudo systemctl status cron

Интеграция с другими функциями VyOS

Интеграция с API

# Периодический вызов VyOS REST API
set system task-scheduler task api-health-check interval '*/10 * * * *'
set system task-scheduler task api-health-check executable path '/config/scripts/api-check.sh'

Скрипт:

#!/bin/bash

API_KEY="your-api-key"
API_URL="https://localhost/retrieve"

RESPONSE=$(curl -k -X POST "${API_URL}" \
  -H "Content-Type: application/json" \
  -H "key: ${API_KEY}" \
  -d '{"op":"showConfig","path":[]}' \
  -w "%{http_code}" -o /dev/null -s)

if [ "$RESPONSE" != "200" ]; then
    logger -t api-check -p user.err "API health check failed: HTTP ${RESPONSE}"
else
    logger -t api-check "API health check OK"
fi

Интеграция с высокой доступностью (VRRP)

# Проверка VRRP статуса
set system task-scheduler task vrrp-monitor interval '*/5 * * * *'
set system task-scheduler task vrrp-monitor executable path '/config/scripts/vrrp-monitor.sh'

Интеграция с мониторингом производительности

# Сбор метрик производительности
set system task-scheduler task perf-monitor interval '*/1 * * * *'
set system task-scheduler task perf-monitor executable path '/config/scripts/perf-monitor.sh'

Заключение

Task Scheduler в VyOS - это мощный инструмент для автоматизации рутинных операций и создания отказоустойчивой инфраструктуры. Правильное использование планировщика задач позволяет:

  • Автоматизировать резервное копирование и восстановление
  • Проактивно мониторить состояние системы и сервисов
  • Выполнять регулярное обслуживание без ручного вмешательства
  • Интегрироваться с внешними системами мониторинга и управления
  • Снизить нагрузку на администраторов

Для production-сред рекомендуется:

  • Настроить ежедневное резервное копирование конфигурации
  • Мониторить критические сервисы и интерфейсы
  • Логировать выполнение всех задач в syslog
  • Тестировать скрипты вручную перед добавлением в планировщик
  • Документировать все автоматизированные задачи