19 KiB
Executable File
Kraken → TrueNAS — автобэкап стека
Создано: 2026-09-20 Обновлено: 2026-09-20 (✅ ВСЕ 7 ШАГОВ ВЫПОЛНЕНЫ И ПРОВЕРЕНЫ) Статус: ✅ РАБОТАЕТ END-TO-END. Архив 165 МБ / 36985 файлов лёг на TrueNAS (
nas:nas), jellyfin иbackup.logисключены. Крон0 4 * * *установлен. Старый бэкап Kraken→Mail.ru отключён. Задача: бэкап стека Kraken складывать на TrueNAS в/mnt/RED_2TB/backup/kraken/, откуда он автоматически уезжает в Mail.ru Cloud существующим rclone-скриптом TrueNAS (скрипт не трогаем).
✅ СТАТУС РЕАЛИЗАЦИИ (2026-09-20)
| # | Шаг | Статус | Факт |
|---|---|---|---|
| 1 | SSH-ключ kraken-backup-push + pub на TrueNAS |
✅ | Ключ на Kraken ~/.ssh/kraken-backup-push (ed25519, fp SHA256:hpatuPO7Yyf+/OryR1dokDmmUXAY7Ei4dWvL1pfsvLQ). Pub записан в sshpubkey юзера nas (id=72) через midclt call user.update 72. Проверено живьём: ssh -i kraken-backup-push nas@mallexxx.duckdns.org → CONNECTED_AS=nas. |
| 2 | Датасет /mnt/RED_2TB/backup/kraken |
✅ | Создан через midclt call pool.dataset.create (NFSV4/PASSTHROUGH). Права 1000:1000 (nas) 770 — выставлены через midclt call filesystem.setperm (обычный chown от truenas_admin → Operation not permitted). Проверено: Kraken пишет туда (WRITE_OK/CLEANUP_OK). |
| 3 | Скрипт на Kraken | ✅ | /home/kraken/kraken-backup-to-truenas.sh (755, bash -n OK). Лог ~/kraken-backup.log, err ~/kraken-backup.err. Рабочая копия на Mac: /Users/admin/kraken-recovery/kraken-backup-to-truenas.sh. Запускается под sudo (см. ниже), rsync с --chown=nas:nas. |
| 4 | Ротация 14 архивов | ✅ | Реализована: ls -1t kraken-docker-*.tar.gz | tail -n +15 | rm на стороне TrueNAS. В прогоне отработала (архив один → удалять нечего, шаг прошёл без ошибок). |
| 5 | Крон 0 4 * * * |
✅ | Поставлен: /etc/cron.d/kraken-backup (root:root 644), строка 0 4 * * * root /home/kraken/kraken-backup-to-truenas.sh. cron активен. Не конфликтует с root-crontab (sd-backup.sh 03:00 вс, timemachine). |
| 6 | Живой прогон | ✅ | Проверено end-to-end: tar 603M → 165 МБ, rsync 52 с, размер совпал (165704366 == 165704366), лог === KRAKEN BACKUP DONE ===. На TrueNAS: /mnt/RED_2TB/backup/kraken/kraken-docker-20260920-115925.tar.gz, 36985 файлов, владелец nas:nas. |
| 7 | Выключить старый Kraken→Mail.ru | ✅ | СДЕЛАНО. Строка 0 3 * * 0 в /config/rclone/crontab закомментирована, применено (crontab /config/rclone/crontab). Проверено: активных задач в контейнере нет (crontab -l | grep -v '^#' пусто), crond жив, контейнер Up. Бэкап для отката: /home/kraken/backups/rclone-disable-20260920-120606/. |
✅ РЕШЕНИЕ БЛОКЕРА ПРАВ: вариант C — весь скрипт под sudo
Симптом (первый прогон): tar: docker/portainer/certs: Cannot open: Permission denied → Exiting with failure status → ветка exit 2, архив удалён.
Факт (владельцы подпапок /srv/...6194539b.../docker/):
| Владелец | Каталоги |
|---|---|
| root (0:0) | cloudflared, hermes-build, hermes, homeassistant, jellyfin, portainer, rclone, scripts, watchtower |
| 1000:1000 (kraken) | media-pipeline, prowlarr, radarr, sonarr, transmission |
tar от kraken покрывал только половину — критичные hermes, portainer, rclone/config (root-owned) недоступны.
Решение (Alex: «ну конечно sudo cron должен быть») — вариант C:
- Скрипт запускается целиком под sudo (
sudo -nработает без пароля, NOPASSWD есть). - В скрипте:
rsync -a --no-o --no-g --chown=nas:nas— владелец архива на TrueNAS принудительноnas:nas, несмотря на root на отправляющей стороне. - Крон-строка в
/etc/cron.d/kraken-backupуже идёт отroot→ sudo внутри скрипта не нужен, tar и так root.
⚠️ Питфолл: при root-сборке архива ОБЯЗАТЕЛЬНО
rsync --chown=nas:nas, иначе архив на TrueNAS окажетсяroot:root, и ротация (rmотnas) его не удалит.
⚠️ Питфолл скрипта (мелкий, не критичный):
$ERR-файл (~/kraken-backup.err) не обнуляется в начале прогона — при чтении лога видны старыеPermission deniedиз прошлого падения. Фильтровать по времени, либо добавить: > "$ERR"в старт.
📦 Факты для реализации (собраны 2026-09-20)
- Размер стека:
/srv/.../docker= 2.2G, без jellyfin и*.log= 603M (сжимается). /tmpна Kraken = tmpfs 2.0G → места под архив хватает.- rsync/tar на Kraken есть:
/usr/bin/rsync,/usr/bin/tar. - Внешний IP Kraken =
92.62.70.9(⚠️ динамический — в доке фигурировал.41). Следствие:from=вauthorized_keysдля push-ключа не ставить — IP сменится и бэкап умрёт. Ограничить толькоno-pty,no-port-forwarding,no-agent-forwarding,no-X11-forwarding. (Через APIuser.updateограничения всё равно не выставить — ключ пишется «голым»; если нужны ограничения, править~nas/.ssh/authorized_keysпод root.) - Бэкап-скрипт на Mac (рабочая копия):
/Users/admin/kraken-recovery/kraken-backup-to-truenas.sh. - Дампы перед изменениями (TrueNAS):
/home/truenas_admin/kraken-backup-setup-20260919-223211/—nas-user-before.json,cronjobs-before.json,smb-before.json. ⚠️/mnt/RED_2TB/backup/—root:root,truenas_adminне может создавать там папки (бэкапы держать в~).
Питфоллы TrueNAS, подтверждённые в этой сессии
chown/chmodотtruenas_adminна root-owned датасете →Operation not permitted. Рабочий путь:midclt call filesystem.setperm '{"path":...,"mode":"770","uid":1000,"gid":1000}'(возвращает job id, применяется асинхронно — подождать 3-5 с и проверитьls -ldn). Это не требует root-шелла, в отличие отchown.midclt call pool.dataset.createсaclmode=PASSTHROUGH+acltype=NFSV4— сработало (обход питфолла №3 из family/plans/t610-backup-to-truenas про DISCARD).- Ключ юзера
nasкласть черезmidclt call user.update 72 '{"sshpubkey":"..."}'— TrueNAS сам создаёт~nas/.ssh/authorized_keysс правильными правами, обходя питфолл №9 (непроходимые родители~nas).
Почему появилась задача
2026-09-20 при разборе падения vless reverse proxy и cloudflared ssh tunnel выяснилось:
- Бэкап Kraken был — контейнер
rcloneна Kraken, вс 03:00,/data/docker→mailru-crypt:kraken/docker. - Но последний успешный прогон — до 13.09.2026. 13-го прогон упал с 292 ошибками: сначала
507 Insufficient Storage(место на Mail.ru кончилось), затем400 Bad Request. - Прогон 20.09 не состоялся вообще — контейнер
rcloneне был запущен (docker-гонка: dockerd стартовал раньше монтирования USB-диска, см. personal/tech/docker-data-root-mount-race). Crontab пропущенное окно не догоняет. rclone syncпри ошибках не удаляет → в облаке застряло неполное состояние.
Решение Alex (2026-09-20): перенастроить так, чтобы бэкап Kraken шёл на TrueNAS в общую папку backup/, рядом с t610, и уезжал в Mail.ru существующим скриптом. Часть «TrueNAS → Mail.ru» не трогать.
Схема (принята 2026-09-20)
Kraken: /srv/dev-disk-by-uuid-6194539b-.../docker (весь стек конфигов)
│ tar czf - (собирается НА Kraken, локально)
│ rsync/scp ──────────► mallexxx.duckdns.org:22 (порт открыт, ping ~102ms)
▼
TrueNAS: /mnt/RED_2TB/backup/kraken/kraken-docker-<ts>.tar.gz
│ ротация N архивов
▼
rclone backup.sh (вс 03:00, контейнер rclone) ← ⛔ НЕ ТРОГАЕМ
│ run_sync "backup" /data/backup "mailru-crypt:"
▼
Mail.ru Cloud (зашифровано)
Ключевой принцип: /mnt/RED_2TB/backup/* уже целиком уходит в mailru-crypt: строкой run_sync "backup" /data/backup "mailru-crypt:". Значит всё, положенное в backup/kraken/, уезжает в облако автоматически — правок в backup.sh не требуется. Тот же приём, что у family/plans/t610-backup-to-truenas.
Решения и обоснование
-
Вариант A — PUSH с Kraken (выбрал Alex 2026-09-20). Почему не PULL (как у t610): Kraken за NAT, белого IP нет → TrueNAS не может к нему подключиться. PULL потребовал бы SSH-туннель. PUSH работает через уже открытый порт
mallexxx.duckdns.org:22. Минус PULL-схемы t610 здесь непреодолим: у t610 адрес в локалке TrueNAS (192.168.2.176), у Kraken — другая сеть (192.168.1.x) + NAT. -
Что бэкапим: весь
/srv/dev-disk-by-uuid-6194539b-.../docker(2.2G), кроме:docker/jellyfin/(1.5G) — метаданные/картинки, перекачиваемы. Alex: «метаданные не надо».docker/rclone/config/backup.log(65 МБ) — растущий лог самого бэкапа, бессмысленно таскать в архив. Итого к бэкапу ≈ 700 МБ минус логи. Состав, который уезжает:hermes(249M — данные Hermes-агента: sessions, .env, auth.json, cron),radarr119M,media-pipeline90M,sonarr82M,rclone/config63M (минус лог),prowlarr56M,transmission12M,homeassistant6.6M,portainer,scripts,hermes-build,cloudflared,watchtower,compose.sh.
-
Целевой датасет:
/mnt/RED_2TB/backup/kraken— внутриbackup, уезжает в Mail.ru автоматически. ⚠️ Создавать как t610: parent/mnt/RED_2TB/backup, ACL Mode =Passthrough(не DISCARD!), ACL Type = NFSv4, праваnas:nas 770. -
Расписание: крон на Kraken, ежедневно, время после t610 (03:30) — предлагается 04:00. Ротация 14 архивов. ⚠️ Питфолл: crontab не догоняет пропущенное окно. Если Kraken лежал — бэкап за тот день потерян. Вариант улучшения:
@reboot+ проверка «архив за сегодня есть?» (обсуждаемо). -
Транспорт:
rsyncc SSH-ключом. Отдельный pull/push-ключ (ограничитьfrom=+no-ptyна стороне TrueNAS). Ключ хранить в/mnt/RED_2TB/backup/kraken/.ssh/(владелецnas, как t610 — питфолл №9:~nas/.sshнедоступен). ⚠️ Kraken пишет как юзер вauthorized_keysTrueNAS. Нужен юзер с правом записи вbackup/kraken(илиnas). -
Скрипт: на Kraken (
/home/kraken/backup-to-truenas.sh), tar + rsync. Лог рядом.
⚠️ Проблемы, которые надо решить при реализации
| # | Проблема | Решение |
|---|---|---|
| 1 | nas (uid 1000 на TrueNAS) vs юзер на Kraken — разные uid |
Ключ с from= + запись в backup/kraken от нужного владельца; либо chown nas:nas |
| 2 | У Kraken нет ключа для TrueNAS (в ~/.ssh только id_ed25519 от другого) |
Сгенерировать отдельный ключ kraken-backup-push, pub → authorized_keys TrueNAS |
| 3 | Mail.ru переполнен | Не блокирует доставку на TrueNAS. Разбираться отдельно (вне этой задачи) |
| 4 | Ротация на стороне Kraken vs TrueNAS | Делать ротацию на TrueNAS (там архивы), rm старых |
| 5 | backup.log 65 МБ растёт |
Исключить из tar (--exclude) + рассмотреть ротацию самого лога |
✅ ШАГ 7 — ВЫПОЛНЕН (2026-09-20)
Сделано: строка 0 3 * * 0 /config/rclone/backup.sh ... в /config/rclone/crontab контейнера rclone закомментирована (#0 3 * * 0 ...), применено через crontab /config/rclone/crontab.
Проверено:
docker exec rclone crontab -l→ строка с#crontab -l | grep -v '^#' | grep -v '^$'→ пусто (активных задач нет)- Контейнер
rclone—Up,crond -f -l 8жив backup.shне тронут (только расписание отключено) — при необходимости легко вернуть
Откат: снять # + sudo docker exec rclone crontab /config/rclone/crontab. Бэкап: /home/kraken/backups/rclone-disable-20260920-120606/.
Причина отключения: устранение дублирования и переполнения Mail.ru (507). Теперь Kraken идёт в облако только через TrueNAS.
🔁 Проверка reboot-безопасности (2026-09-20, после фикса гонки)
Alex выключил Kraken (sudo shutdown -h now). Фикс mount-race подтверждён живым reboot'ом: после включения все контейнеры поднялись сами — docker ps не пуст (12 Up, включая cloudflared, xray-reverse-bridge, rclone, jellyfin). Ручных docker start не потребовалось.
Что проверять после каждого reboot:
ssh kraken 'docker ps -q | wc -l' # ожидаем ~12, не 0
Если 0 — гонка вернулась, смотреть systemctl show docker -p RequiresMountsFor (должно быть непусто).
⚠️ Крон не догоняет пропущенное окно. Пока Kraken лежал, прогон 04:00 пропускается без компенсации. Если это критично — добавить
@reboot-строку с проверкой «есть ли архив за сегодня».
Шаги реализации (все 7 выполнены)
- ✅ Ключ
kraken-backup-push(ed25519) на Kraken → pub на TrueNAS черезmidclt call user.update 72. - ✅ Датасет
/mnt/RED_2TB/backup/kraken(Passthrough, NFSv4,nas:nas 770). - ✅ Скрипт на Kraken (
/home/kraken/kraken-backup-to-truenas.sh): tar (exclude jellyfin, *.log) →rsyncна TrueNAS. - ✅ Ротация 14 архивов (на TrueNAS).
- ✅ Крон на Kraken:
/etc/cron.d/kraken-backup,0 4 * * * root. - ✅ Живой прогон (165 МБ, 36985 файлов, размер совпал).
- ✅ Старый бэкап Kraken → Mail.ru отключён.
Примечание про
from=в authorized_keys: изначально планировалось ограничить ключ по IP, но внешний IP Kraken динамический (92.62.70.9, в доке был.41) →from=не ставить, иначе бэкап умрёт при смене IP. Ограничения через APIuser.updateвсё равно не выставляются — ключ пишется «голым».
Проверка результата
# 1) архив появился на TrueNAS
ssh truenas_admin@mallexxx.duckdns.org 'ls -la /mnt/RED_2TB/backup/kraken/'
# 2) лог прогона (на Kraken)
ssh kraken 'sudo tail -20 /home/kraken/kraken-backup.log'
# 3) уезжает в облако (после вс 03:00)
ssh truenas_admin@mallexxx.duckdns.org 'docker exec rclone tail -30 /config/rclone/backup.log'
Открытые вопросы (не блокируют бэкап)
- Mail.ru переполнен (
507 Insufficient Storageс 13.09).backup/krakenдоедет до облака только после освобождения места. TrueNAS-часть работает независимо от этого. - Лог
backup.logконтейнераrclone= 65 МБ и растёт — исключён из архива, но стоит рассмотреть ротацию самого лога.
Связанные заметки
- family/plans/t610-backup-to-truenas — образец схемы (PULL), питфоллы датасетов/SMB/ключей
- family/how-to/truenas-rclone-backup — rclone-бэкап TrueNAS → Mail.ru (куда попадает
backup/kraken) - family/how-to/kraken-access — доступ к Kraken, контейнеры
- personal/tech/docker-data-root-mount-race — гонка docker↔монтирование (причина, почему прогон 20.09 не состоялся)
- personal/tech/jellyfin-db-schema-mismatch — jellyfin после reboot: сервер старше БД
- personal/tech/xray-reverse-tunnel-kraken-truenas — разбор того же инцидента
- family/how-to/openmediavault-rpi5 — Kraken OMV