Автоматические снапшоты ZFS с помощью Sanoid на Fedora Server 44 #
Это продолжение предыдущей статьи про создание собственного NAS на базе Fedora Server 44. В прошлый раз мы установили Fedora Server, подключили ZFS, создали первый датасет и расшарили его по сети с помощью Samba.
Сегодня продолжаем допиливать наш NAS. На этот раз займемся одной из самых крутых фишек ZFS — снапшотами. А чтобы не делать все вручную, сразу автоматизируем этот процесс с помощью утилиты Sanoid.
Зачем вообще нужны снапшоты? #
ZFS — очень мощная и невероятно надежная файловая система. Конечно, без недостатков тоже не обошлось, но преимуществ у нее гораздо больше.
Одна из главных фишек ZFS — это снапшоты. По сути, это снимок состояния файловой системы в определенный момент времени. Если что-то пошло не так — случайно удалили файлы, неудачно обновили систему или словили программу-вымогатель — можно просто откатиться к предыдущему состоянию, как будто ничего и не произошло.
Конечно, совсем бесплатно это не работает. Снапшоты занимают место на диске, но только под измененные данные. Пока файлы не меняются, снапшот практически ничего не весит. Поэтому платить приходится только за изменения, а не за полную копию данных.
В TrueNAS работа со снапшотами вынесена в удобный WebUI. В Fedora Server такого удобства нет — Cockpit пока не умеет полноценно работать с ZFS.
Но ничего страшного, мы и тут не пропадем.
Работа со снапшотами вручную #
Для начала давайте посмотрим, как вообще работают снапшоты вручную.
# Создать снапшот
sudo zfs snapshot data/media@before-upgrade
# Откатиться к снапшоту
sudo zfs rollback data/media@before-upgrade
# Проверить целостность пула (желательно выполнять примерно раз в месяц)
sudo zpool scrub dataДля локальной работы можно включить отображение каталога .zfs:
sudo zfs set snapdir=visible data/mediaОднако Samba не отображает этот служебный каталог SMB-клиентам. Если вы хотите пользоваться снапшотами прямо из Проводника Windows через меню «Предыдущие версии», потребуется настроить модуль
shadow_copy2. Именно так эта возможность реализована в TrueNAS После этого в каталоге появится скрытая папка.zfs, внутри которой можно просматривать содержимое всех снапшотов. Иногда это оказывается очень удобно, если нужно быстро достать случайно удаленный файл без полного отката файловой системы.
Однако, несмотря на то что ручной труд облагораживает человека, как и любой другой труд, память у нас штука ненадежная. ИИ-агентами лично я пользоваться не хочу, да и давать им доступ к своим данным — идея довольно смелая. Смелая, но глупая
Поэтому давайте автоматизируем весь этот процесс с помощью широко известного в узких кругах набора утилит Sanoid.
Sanoid умеет автоматически создавать снапшоты по расписанию, удалять устаревшие и поддерживать заданную политику хранения без какого-либо участия пользователя.
Установка Sanoid #
Шаг 1. Устанавливаем необходимые зависимости #
Для начала установим Git и все библиотеки, которые необходимы для работы Sanoid.
sudo dnf install -y \
git \
perl-Config-IniFiles \
perl-Data-Dumper \
perl-Capture-Tiny \
perl-Getopt-Long \
lzop \
mbuffer \
mhash \
pvНа Fedora все необходимые Perl-модули уже находятся в официальных репозиториях, поэтому дополнительно подключать EPEL или устанавливать пакеты через CPAN не потребуется.
Шаг 2. Загружаем Sanoid #
Переходим во временную директорию и клонируем официальный репозиторий проекта.
cd /tmp
sudo git clone https://github.com/jimsalterjrs/sanoid.git
cd sanoidПереключимся на последнюю стабильную версию.
sudo bash -c 'cd /tmp/sanoid && git checkout "$(git tag | grep "^v" | tail -n 1)"'Конечно, можно оставить и ветку master, но лично я предпочитаю использовать стабильные релизы. Домашний NAS — это не то место, где хочется неожиданно словить баг после очередного обновления.
Шаг 3. Устанавливаем программу #
Теперь установим сам Sanoid.
Копируем исполняемые файлы:
sudo cp sanoid syncoid findoid sleepymutex /usr/local/sbinСоздаем каталог для конфигурационных файлов:
sudo mkdir -p /etc/sanoidКопируем настройки по умолчанию:
sudo cp sanoid.defaults.conf /etc/sanoid/Создаем основной файл конфигурации:
sudo touch /etc/sanoid/sanoid.confИ на всякий случай сохраним пример конфигурации. Он пригодится, если захотите настроить более сложные сценарии.
sudo cp sanoid.conf /etc/sanoid/sanoid.example.confНа этом установка Sanoid завершена. Осталось научить систему запускать его автоматически.
Настраиваем автоматический запуск #
Поскольку Fedora использует systemd, логично доверить запуск Sanoid именно ему.
Создадим два небольших сервиса: один будет отвечать за создание снапшотов, а второй — за удаление устаревших.
Создаем сервис создания снапшотов #
Создаем файл:
sudo nano /etc/systemd/system/sanoid.serviceВставляем следующее содержимое:
[Unit]
Description=Create ZFS Snapshots
Requires=zfs.target
After=zfs.target
Wants=sanoid-prune.service
Before=sanoid-prune.service
ConditionFileNotEmpty=/etc/sanoid/sanoid.conf
[Service]
Type=oneshot
Environment=TZ=UTC
ExecStart=/usr/local/sbin/sanoid --take-snapshots --verboseЗдесь нет ничего сложного. Этот сервис просто запускает Sanoid, который создает снапшоты в соответствии с нашей будущей конфигурацией.
Обратите внимание на строку:
ConditionFileNotEmpty=/etc/sanoid/sanoid.confОна запрещает запуск сервиса до тех пор, пока мы не создадим файл конфигурации. Очень полезная мелочь, которая избавляет от лишних ошибок при первой настройке.
Создаем сервис очистки снапшотов #
Теперь создадим второй сервис.
sudo nano /etc/systemd/system/sanoid-prune.serviceИ вставляем:
[Unit]
Description=Prune ZFS Snapshots
Requires=zfs.target
After=zfs.target sanoid.service
ConditionFileNotEmpty=/etc/sanoid/sanoid.conf
[Service]
Type=oneshot
Environment=TZ=UTC
ExecStart=/usr/local/sbin/sanoid --prune-snapshots --verbose
[Install]
WantedBy=sanoid.serviceЭтот сервис занимается уборкой: удаляет снапшоты, срок хранения которых уже закончился согласно нашей политике.
Таким образом нам вообще не придется думать о том, когда чистить старые снимки — Sanoid сделает все сам.
Создаем таймер #
Осталось научить systemd запускать Sanoid по расписанию.
Создаем таймер:
sudo nano /etc/systemd/system/sanoid.timerИ вставляем:
[Unit]
Description=Run Sanoid every 15 minutes
Requires=sanoid.service
[Timer]
OnCalendar=*:0/15
Persistent=true
[Install]
WantedBy=timers.targetВ моем случае Sanoid запускается каждые 15 минут.
Для домашнего NAS этого более чем достаточно. Если ваши данные меняются редко, интервал можно спокойно увеличить, например до одного часа.
Активируем сервисы #
После того как все сервисы созданы, осталось сообщить о них systemd и включить автоматический запуск.
Для начала перечитаем конфигурацию:
sudo systemctl daemon-reloadРазрешим запуск сервиса очистки снапшотов:
sudo systemctl enable sanoid-prune.serviceИ включим таймер:
sudo systemctl enable --now sanoid.timerПроверить, что таймер успешно запустился, можно командой:
systemctl list-timers sanoid.timerОжидаемый результат будет примерно таким:
NEXT LEFT LAST
Fri 2026-07-17 10:15:00 12 min Fri 2026-07-17 10:00:00На этом установка полностью завершена.
Проверяем установку #
Для собственного спокойствия можно убедиться, что Sanoid действительно установлен.
Например, посмотреть его версию:
sanoid --versionИли открыть встроенную справку:
sanoid --helpЕсли команды выполняются без ошибок — все прошло успешно.
Настраиваем расписание снапшотов #
На данный момент есть один небольшой нюанс.
Sanoid уже установлен.
Таймер уже работает.
Systemd уже каждые 15 минут пытается запускать Sanoid.
Но… делать он пока ничего не будет.
Все потому, что мы еще не рассказали ему, какие датасеты нужно обслуживать и сколько снапшотов необходимо хранить.
Поэтому открываем основной файл конфигурации:
sudo nano /etc/sanoid/sanoid.confПо умолчанию Sanoid поставляется с большим количеством готовых шаблонов. Если интересно посмотреть все возможности утилиты, рекомендую заглянуть в официальный пример конфигурации:
https://github.com/jimsalterjrs/sanoid/blob/master/sanoid.conf
Но для домашнего NAS настолько сложная конфигурация обычно не нужна.
Предположим, что наш пул называется data, а все пользовательские данные находятся в датасете data/media.
Тогда файл sanoid.conf будет выглядеть следующим образом:
[data/media]
use_template = production
[template_production]
frequently = 0
hourly = 36
daily = 30
weekly = 4
monthly = 3
yearly = 0
autosnap = yes
autoprune = yesРазберемся, что означают эти параметры.
В данной конфигурации Sanoid будет автоматически:
- хранить 36 почасовых снапшотов;
- хранить 30 ежедневных;
- хранить 4 еженедельных;
- хранить 3 ежемесячных;
- не создавать “частые” (
frequently) и годовые (yearly) снапшоты.
Параметр
autosnap = yesвключает автоматическое создание снапшотов.
А параметр
autoprune = yesавтоматически удаляет старые снапшоты, срок хранения которых уже закончился.
Важно. Вместо
data/mediaукажите имя своего ZFS-датасета. Узнать его можно командой:zfs list
Если нужно защищать сразу весь пул #
Если в вашем пуле несколько датасетов (media, documents, backups, nextcloud и так далее), гораздо удобнее использовать рекурсивную обработку.
В этом случае достаточно написать:
[data]
use_template = production
recursive = yes
[template_production]
frequently = 0
hourly = 36
daily = 30
weekly = 4
monthly = 3
yearly = 0
autosnap = yes
autoprune = yesТеперь Sanoid будет автоматически обслуживать все дочерние датасеты внутри пула data.
На мой взгляд, именно такой вариант является наиболее удобным для домашнего NAS. Не придется каждый раз добавлять новые датасеты в конфигурацию вручную — они сразу попадут под действие политики хранения. Это особенно удобно, если вы часто экспериментируете и создаете новые датасеты.
Проверяем, что все работает #
Давайте еще раз посмотрим, что мы уже сделали.
- ✅ Установили Sanoid.
- ✅ Создали сервис создания снапшотов.
- ✅ Создали сервис очистки старых снапшотов.
- ✅ Настроили таймер systemd.
- ✅ Описали политику хранения снапшотов.
Теперь каждые 15 минут systemd будет пытаться запускать Sanoid.
Посмотреть список всех активных таймеров можно командой:
sudo systemctl list-timersИ здесь есть один важный момент.
Пока файл /etc/sanoid/sanoid.conf пустой, ничего происходить не будет. Именно для этого мы ранее добавили строку:
ConditionFileNotEmpty=/etc/sanoid/sanoid.confКак только вы сохраните конфигурацию хотя бы с одним датасетом, следующий запуск таймера автоматически начнет создавать снапшоты.
Никаких дополнительных действий выполнять не нужно. Не нужно перезапускать таймер, перезагружать сервер или заново включать сервисы — systemd сам подхватит новую конфигурацию.
Если не хочется ждать ближайшие 15 минут, можно проверить работу вручную.
Создать снапшоты:
sudo sanoid --take-snapshots --verboseИли запустить сервис, который обычно вызывается таймером:
sudo systemctl start sanoid.serviceПосле этого можно убедиться, что снапшот действительно появился:
zfs list -t snapshotЕсли вы увидели новый снапшот — поздравляю, все работает именно так, как и должно.
А как же резервное копирование? #
Здесь очень важно понимать один момент.
Снапшоты — это не резервные копии.
Да, они отлично защищают от случайного удаления файлов, неудачных обновлений или действий программ-вымогателей. Но если выйдет из строя сам диск, контроллер или сгорит весь сервер, вместе с ним пропадут и все снапшоты.
Поэтому снапшоты — это первая линия защиты данных, а не полноценный бэкап.
Syncoid — следующий шаг #
К счастью, разработчики Sanoid подумали и об этом.
Вместе с Sanoid устанавливается еще одна замечательная утилита — Syncoid. Она умеет реплицировать ZFS-датасеты на другой пул, другой сервер или даже в другую географическую точку через SSH.
Самый простой пример выглядит так:
sudo syncoid -r data backupгде:
data— пул или датасет, который мы реплицируем;backup— пул или датасет, куда будут отправляться данные.
На первый взгляд команда выглядит очень простой, но под капотом Syncoid делает довольно серьезную работу. Утилита сама определяет, какие данные изменились после предыдущей синхронизации, передает только разницу между снапшотами и автоматически возобновляет передачу, если соединение неожиданно оборвалось.
Именно поэтому связка Sanoid + Syncoid считается одним из лучших решений для организации резервного копирования на базе ZFS.
Заключение #
На этом настройку автоматических снапшотов можно считать завершенной.
Теперь ваш NAS умеет самостоятельно:
- создавать снапшоты по расписанию;
- автоматически удалять устаревшие снимки;
- поддерживать заданную политику хранения без какого-либо участия пользователя.
В следующей статье мы подробно разберем Syncoid и настроим полноценную репликацию данных между двумя ZFS-пулами. После этого наш NAS сможет пережить уже не только случайное удаление файлов, но и выход из строя целого сервера.