Копії віртуальних машин¶
BombVault копіює віртуальні машини KVM/libvirt без монтування будь-якого шляху libvirt. Він запускає virsh на хості через SSH (qemu+ssh://), читає й пише диски віртуальних машин через монтування Host Data (/mnt на хості — це /host/user у контейнері) і копіює UEFI NVRAM через SSH. Оскільки ніщо, що належить libvirt, не монтується, BombVault ніколи не може завадити VM Manager в Unraid.
Цей посібник охоплює налаштування, методи копіювання, віртуальні машини зі знімками Unraid і TrueNAS SCALE. Копіям контейнерів нічого з цього не потрібно.
Копії наборів даних ZFS використовують те саме SSH-з'єднання, з тим самим ключем, хостом і користувачем. Щойно копії віртуальних машин підключаються, підключаються й записи наборів даних ZFS. Див. Набори даних ZFS.
Що ви налаштовуєте¶
| Налаштування | Де | Типово | Значення |
|---|---|---|---|
Host SSH: Address (LIBVIRT_HOST) |
змінна шаблону | host.docker.internal |
Хост Unraid, до якого звертаються через SSH |
Host SSH: Port (LIBVIRT_SSH_PORT) |
змінна шаблону | 22 |
Порт SSH в Unraid |
Host SSH: User (LIBVIRT_SSH_USER) |
змінна шаблону | root |
Користувач SSH на хості |
| Відкритий ключ | Налаштування, Інтеграції, SSH хоста | створюється під час першого запуску | Авторизуйте його на хості |
BombVault створює свою пару ключів SSH під час першого запуску в /config/ssh/id_ed25519, вона зберігається в appdata. Ключ хоста закріплюється в /config/ssh/known_hosts під час першого підключення.
Шаблон заповнює Host SSH: Address заглушкою 192.168.x.x. BombVault вважає її незаданою і пробує host.docker.internal, що працює в мережі bridge за замовчуванням. У користувацькій мережі замініть її на IP хоста в локальній мережі (крок 3 Б).
Крок 1: увімкніть SSH на хості Unraid¶
- В Unraid відкрийте Settings, Management Access і задайте Use SSH значення Yes.
- Якщо ви змінювали порт SSH, запам'ятайте його. Host SSH: Port має збігатися.
Крок 2: авторизуйте відкритий ключ BombVault¶
/root в Unraid живе в пам'яті й очищується під час кожного завантаження, тому ключ має лежати ще й на флешці. Виконайте це в терміналі Unraid:
K=$(docker exec BombVault cat /config/ssh/id_ed25519.pub)
mkdir -p /root/.ssh /boot/config/ssh && chmod 700 /root/.ssh
grep -qxF "$K" /root/.ssh/authorized_keys 2>/dev/null || echo "$K" >> /root/.ssh/authorized_keys
grep -qxF "$K" /boot/config/ssh/root.pubkeys 2>/dev/null || echo "$K" >> /boot/config/ssh/root.pubkeys
chmod 600 /root/.ssh/authorized_keys
Unraid 6.9 і новіші під час кожного завантаження копіюють /boot/config/ssh/root.pubkeys в authorized_keys користувача root, тож це переживає перезавантаження. Це діє для будь-якого входу root, які б ім'я хоста чи порт не використовував BombVault.
Крок 3: мережа¶
BombVault має відкрити TCP-з'єднання від контейнера до порту SSH хоста. Виберіть випадок, який підходить вашому налаштуванню.
А. BombVault у мережі bridge за замовчуванням¶
- Залиште Host SSH: Address рівним
host.docker.internalабо заглушці шаблону. Шаблон додає--add-host=host.docker.internal:host-gateway, що вказує на шлюз docker0, тобто на хост. - Задайте Host SSH: Port рівним вашому порту SSH.
Б. BombVault у користувацькій мережі¶
Контейнер у br0.x, macvlan чи ipvlan не може сягнути хоста через host.docker.internal, бо 172.17.0.1 — це docker0, недоступний з br0.x. Натомість:
- В Unraid задайте Settings, Docker, Host access to custom networks значення Enabled.
- Задайте Host SSH: Address рівним IP хоста Unraid у локальній мережі, тобто адресі, за якою ви відкриваєте вебінтерфейс.
- Якщо мережа контейнера й хост перебувають у різних VLAN, дозвольте маршрут на роутері чи файрволі: з VLAN контейнера до IP хоста на порт SSH за TCP.
- Якщо IP хоста в локальній мережі все одно недоступний, використайте IP-шим хоста в підмережі контейнера. Знайдіть його на хості командою
ip -4 addr show | grep -B2 <container-subnet>.
Перевірте, що хост відповідає¶
Виконайте це в терміналі Unraid з вашим IP та портом:
docker exec BombVault timeout 6 bash -c 'echo > /dev/tcp/192.168.1.10/22' && echo OPEN || echo UNREACHABLE
OPEN означає, що шлях працює. UNREACHABLE означає, що мережу з кроку 3 потрібно полагодити, перш ніж робити щось інше.
Крок 4: задайте змінні й перевірте¶
- В Unraid відкрийте Docker, натисніть BombVault, виберіть Edit, задайте Host SSH: Address (і Host SSH: Port, якщо він не 22) і натисніть Apply. Якщо змінних немає, імпортуйте шаблон заново, бо Unraid зберігає збережену конфігурацію наявного контейнера.
- У BombVault відкрийте Налаштування, Інтеграції, SSH хоста і натисніть Перевірити з'єднання. Воно має стати зеленим.
Той самий виклик із терміналу перелічує ваші віртуальні машини:
docker exec BombVault virsh -c "qemu+ssh://root@192.168.1.10:22/system?keyfile=/config/ssh/id_ed25519&known_hosts=/config/ssh/known_hosts&known_hosts_verify=auto" list --all
Крок 5: метод для кожної віртуальної машини¶
У кожної віртуальної машини є Метод у картці ВМ на її вкладці «Налаштування» (відкрийте віртуальну машину в розділі Резервні копії):
- Graceful (вимкнення) використовується за замовчуванням. Він вимикає віртуальну машину, копіює диски й запускає її знову, тож копія завжди узгоджена. Він чекає до десяти хвилин, поки гість вимкнеться, і ніколи не вимикає його примусово. Гість, який після цього все ще працює, лишається як є, а копія завершується помилкою з причиною. Якщо гість вимкнеться протягом наступної години, BombVault запустить його знову. Якщо цей запуск не вдасться, невдалий запуск копії про це повідомить.
- Живий знімок копіює працюючу віртуальну машину через зовнішній знімок і
blockcommit. Потрібен диск на/mnt/cacheабо/mnt/diskX, а не на/mnt/user. З гостьовим агентом qemu у віртуальній машині знімок узгоджений (quiesced), а без нього він узгоджений лише на рівні збою (crash-consistent). У вимкненої віртуальної машини живий режим сам перемикається на Graceful. Коли знімок зробити не вдається, ця копія завершується помилкою, а віртуальна машина продовжує працювати, бо віртуальну машину, яку ви вирішили копіювати наживо, заради цього ніколи не вимикають.
Чого копія не містить¶
Копія може пройти успішно й усе ж містити не всю віртуальну машину. Тоді запуск має примітку з попередженням, яка називає, чого бракує:
- Диски, які BombVault не читає. Диск лише для читання,
lun, а також дискnetworkчиvolumeпропускаються, і примітка називає кожен із них із цільовим пристроєм і типом. Визначення в копії їх і далі перелічує. Cdrom і флопі-дисковод не називаються. Звичайний блоковий пристрій, який не є zvol ZFS, натомість призводить до помилки копії. - Стан емульованого TPM. Він не має шляху в XML домену. Unraid VM Manager налаштовує такий TPM для віртуальної машини з BIOS OVMF TPM, тому примітка з'являється й в Unraid. Гість, який зберігає секрет у своєму TPM, як це робить BitLocker, може після відновлення без цього стану запитати свій ключ відновлення, тож тримайте цей ключ під рукою.
Тонкі диски¶
Відновлення зберігає тонкий диск тонким, чи замінює воно диск, чи пише новий: restic записує послідовності нулів як дірки в новому файлі, а BombVault після запису повертає нульові блоки заміненого файла через fallocate --dig-holes. Поки restic замінює файл, цей файл займає повний розмір, якщо на пулі вистачає місця. На файловій системі без пробивання дірок диск лишається повного розміру, і журнал про це повідомляє. Перевірка вільного місця й далі рахує новий диск за повним розміром.
Невдале відновлення¶
Відновлення на місці вимикає віртуальну машину, записує диски, а визначення та NVRAM замінює лише після того, як диски записано. Невдале відновлення лишає віртуальну машину визначеною разом з її NVRAM. Якщо її диски не змінилися і вона працювала, вона запускається знову. Якщо вони могли змінитися, вона лишається вимкненою, бо завантаження з наполовину записаного диска писало б поверх нього, і запуск про це повідомляє. Повторне відновлення тієї самої копії доводить справу до кінця.
Знімки, зареєстровані в libvirt (Unraid VM Manager робить знімки інакше), зупиняють відновлення на місці до того, як віртуальну машину буде зачеплено, бо libvirt не може видалити віртуальну машину, яка їх має. Спершу видаліть їх.
Лише змінені блоки¶
Віртуальну машину з дисками qcow2 можна копіювати, читаючи лише змінене. Увімкніть Лише змінені блоки в тій самій картці, і BombVault використовує API копіювання libvirt замість методу вище:
- Він запускає завдання копіювання в режимі pull (
virsh backup-begin), яке в той самий момент створює контрольну точку з іменемbombvault-<time>, і читає диски через SSH-з'єднання через прокинутий сокет Unix. Коли гостьовий агент відповідає, файлові системи гостя заморожуються лише на час запуску завдання. Розморожування, яке не вдалося, пробується знову близько п'ятнадцяти секунд, а якщо гість усе одно не розморожується, BombVault надсилає сповіщення. - Перший запуск читає всі виділені блоки. Наступні читають лише блоки, які бітова карта контрольної точки позначає як записані після попередньої копії.
- Кожен диск зберігається як тека сегментів фіксованого розміру з тим, що бачить гість. Незмінені сегменти беруться з попереднього знімка без читання, тож кожен знімок повний і відновлюється сам по собі.
- Відновлення збирає диск з його сегментів і перетворює назад у qcow2 через
qemu-img. Диск має той самий вміст, що й у момент копіювання, але файл новий, qcow2, а ланцюжок базових образів повертається сплюснутим. - Перевірка перед таким відновленням перелічує кожен диск, який вона перебудовує, і рахує його в повному розмірі гостя, двічі для qcow2, оскільки сирий образ і його перетворена копія лежать поруч, поки старий файл не замінено. Це максимум, який може зайняти диск, тож нестача за цим підрахунком робить рядок місця сірим, а не блокує. Перевірка відновлення після першої копії та Перевірити відновлення також переконуються, що знімок містить кожен сегмент кожного диска потрібного розміру.
- Між запусками у віртуальної машини в libvirt немає записаної контрольної точки. BombVault зберігає визначення найновішої контрольної точки
bombvault-в/config/vm-checkpointsі видаляє лише запис libvirt про неї (virsh checkpoint-delete --metadata). Її бітова карта лишається у файлі qcow2 і продовжує рахувати записи, а наступний запуск повертає контрольну точку на місце (virsh checkpoint-create --redefine) перед початком. libvirt відмовляється видаляти визначення віртуальної машини з контрольними точками, і саме це дозволяє Remove VM в Unraid і відновленню працювати як звичайно. - Завдання копіювання, яке BombVault залишив працюючим, бо зупинився посеред копіювання, завершується, коли BombVault запускається знову, разом із контрольними точками, які цей запуск залишив записаними.
- Вимкнення перемикача, виключення віртуальної машини з розкладу чи видалення її копій теж завершує таке завдання і, поки віртуальна машина працює, видаляє й бітову карту. На вимкненій віртуальній машині libvirt не може її видалити, і вона лишається в образі невикористаною.
- Контрольні точки інших інструментів лишаються недоторканими. Віртуальну машину, в якої вони є, не можна відновити, поки їх не видалять, і відновлення зупиняється, не зачепивши віртуальну машину.
Перемикач сам відступає. Відсутня чи зламана контрольна точка, диск, що змінив розмір, або найновіший знімок, що не належить до змінених блоків, означає, що весь диск читається ще раз. Вимкнена віртуальна машина, сирий диск чи zvol, відсутність SSH-з'єднання з хостом, libvirt без API копіювання чи замало вільного місця в /config означають звичайну копію методом вище. Картка каже, що з цього використав останній запуск і чому.
Вимоги: libvirt з API копіювання (перевірено з libvirt 12.2 і QEMU 10.2 в Unraid 7.3), sshd з AllowStreamLocalForwarding yes (типово, в Unraid теж, де вимкнено переспрямування TCP) і диски qcow2. libvirt відмовляється створювати контрольні точки на сирих дисках, а Unraid типово створює сирі vdisk. Віртуальна машина продовжує працювати під час копіювання, як і за живого режиму, а сегменти, що чекають restic, займають до 4 ГіБ у /config.
Віртуальні машини зі знімками Unraid¶
Знімок, який робить VM Manager в Unraid, перетворює диск qcow2 на ланцюжок: вихідний образ унизу, а поверх нього по одному файлу на знімок, у кожному лише те, що змінилося після того, що лежить під ним. Віртуальна машина пише в найновіший файл. Диск із двома знімками — це три файли.
BombVault копіює таку віртуальну машину повністю:
- Кожен файл ланцюжка. Він іде по ланцюжку базових образів кожного диска до кінця й копіює кожен файл у ньому разом зі списком знімків Unraid (
/etc/libvirt/qemu/snapshotdb/<vm>/snapshots.db, читається через SSH). Ланцюжок, який не можна пройти до кінця, наприклад тому що файл посередині зник, провалює копію й називає файл. - Жива копія зберігає знімки. Живий знімок кладе зверху тимчасовий шар, поки читає диск, а потім зливає його назад, лише в образ просто під ним. Після копії ланцюжок такий самий, як до неї. Віртуальна машина без знімків поводиться як завжди.
- Відновлення повертає ланцюжок. Відновлення на місці записує кожен файл туди, де він був, і повертає список знімків Unraid, тож VM Manager знову перелічує знімки. Відновлення поруч з оригіналом записує файли в теку копії й спрямовує відновлені диски на відновлені файли, тож копія ніколи не читає з образів оригіналу. Список знімків Unraid повертається лише за відновлення на місці, бо він називає файли там, де вони були скопійовані. Без нього копія завантажується так само, а VM Manager просто не перелічує для неї знімків.
- Лише змінені блоки читає те, що бачить гість, тому його відновлення повертається одним сплюснутим файлом qcow2 без знімків.
- Відновлення повертає диск вибраної вами копії. Знімки, зроблені чи злиті після цієї копії, цього не змінюють. Копія, зроблена до знімка, визначає віртуальну машину на файлі, який у ній є, а копія, зроблена до злиття, повертає свій шар і працює на ньому. Новіші файли лишаються на місці, невикористані й незмінені. Копія, у якій є шар, але немає файла під ним, відхиляється до того, як віртуальну машину буде зачеплено. Після відновлення визначення віртуальної машини не перелічує ланцюжок, тож libvirt читає його з відновлених файлів.
Приклад: віртуальна машина з двома знімками¶
У віртуальної машини homeassistant один диск, vdisk1.qcow2, і два знімки, які ви зробили у VM Manager перед двома оновленнями. Тепер її диск — ланцюжок із трьох файлів. Вона працює весь час, тому використовує Живий знімок.
- Відкрийте Резервні копії, потім
homeassistant, потім її вкладку Налаштування. У картці ВМ перевірте, що Метод дорівнює Живий знімок, а Лише змінені блоки вимкнено. - Натисніть Створити резервну копію в шапці сторінки.
- Коли запуск завершено, його рядок у Останні запуски на вкладці Перевірка зелений. Віртуальна машина весь час продовжувала працювати, а копія містить усі три файли диска та список знімків Unraid.
- У VM Manager обидва знімки досі на місці, а диск досі читається через ті самі три файли.
Через місяць оновлення йде не так, і ви хочете повернути вчорашній стан поруч зі зламаним, щоб порівняти:
- Відкрийте Відновлення, виберіть Віртуальні машини й клацніть
homeassistant. - Залиште рекомендовану копію минулої ночі та виберіть Поруч з оригіналом у Куди.
- Натисніть Відновити. Три файли лягають у теку з іменем віртуальної машини та
-restored, а відновлений диск вказує на відновлені файли. Працююча віртуальна машина не змінюється.
Щоб відкотити всю віртуальну машину, виберіть Замінити оригінал з ввімкненим Спершу зробити копію поточного стану. BombVault скопіює зламаний стан, вимкне віртуальну машину, запише назад три файли та список знімків Unraid і запустить її знову.
TrueNAS SCALE¶
Кроки вище написано для Unraid, але те саме з'єднання qemu+ssh:// працює з будь-яким libvirtd, до якого може сягнути контейнер, зокрема TrueNAS SCALE, де віртуальні машини знову працюють на libvirt, починаючи з 25.04.2. У TrueNAS рядок підключення потрібно перевизначити, а ключ додається користувачу root у власних налаштуваннях користувачів TrueNAS. Ще три речі змінюють те, що містить копія: диски на zvol, стан vTPM та імена, які TrueNAS дає своїм віртуальним машинам.
1. Сокет libvirt¶
libvirtd у TrueNAS слухає не там, де очікує рядок підключення, побудований із полів SSH хоста. Задайте натомість LIBVIRT_URI з додатковим параметром ?socket=:
BombVault використовує LIBVIRT_URI достеменно як записано, і LIBVIRT_HOST, LIBVIRT_SSH_USER та LIBVIRT_SSH_PORT не потрібні. Для кожної з них, яка не задана, BombVault бере хост, користувача й порт з URI і для власних команд SSH, тож копіювання NVRAM і копії наборів даних ZFS сягають тієї самої машини, що й virsh. Змінна, яку ви задали самі, завжди важливіша, а журнал завантаження називає ціль, яку взято з URI. У TrueNAS користувачу, відмінному від root, для копій наборів даних ZFS потрібен ще zfs allow <user> snapshot,destroy,mount <dataset>, див. Набори даних ZFS.
Впишіть в URI адресу TrueNAS у локальній мережі. Якщо не задано ні LIBVIRT_URI, ні LIBVIRT_HOST, BombVault бере шлюз застосунку за замовчуванням як хост, бо host.docker.internal у застосунку TrueNAS не розв'язується, а журнал завантаження називає вибрану адресу. Для копій наборів даних ZFS цього достатньо. Для копій віртуальних машин усе ще потрібен URI для сокета.
Для копій віртуальних машин застосунку потрібна можливість SETPCAP разом із CHOWN, DAC_OVERRIDE, FOWNER, SETGID і SETUID. Без неї libvirt зупиняється з помилкою «cannot apply process capabilities». YAML у розділі TrueNAS SCALE задає їх усі разом із SYS_CHROOT, який потрібен для знімка замість зупинки.
У TrueNAS SCALE 25.10.0 шлях до сокета перевірено на справжньому обладнанні: стандартний qemu:///system завершується помилкою Failed to connect socket to '/var/run/libvirt/libvirt-sock': No such file or directory, а той самий виклик з ?socket=/run/truenas_libvirt/libvirt-sock перелічує домени.
2. Ключ BombVault у TrueNAS¶
Крок 2 вище пише на флешку Unraid і тут не застосовний. У TrueNAS:
- Увімкніть службу SSH в System, Services.
- У Credentials, Users змініть root і вставте відкритий ключ BombVault із Налаштування, Інтеграції, SSH хоста як його відкритий ключ SSH. TrueNAS зберігає його між перезавантаженнями й оновленнями.
Свіжі установки TrueNAS 24.10 і новіші не дають root пароля, а для входу за ключем він не потрібен. Якщо ви надаєте перевагу не використовувати root, авторизуйте ключ для облікового запису адміністратора з sudo і впишіть її ім'я замість root в LIBVIRT_URI. Тоді копіям наборів даних ZFS потрібен zfs allow, як описано вище.
Репліка на другий сервер входить із власним ключем, який показує вікно репліки. Ключ SSH хоста не авторизує репліку, а ключ репліки не авторизує копії віртуальних машин.
TrueNAS не бачить змін, зроблених через virsh
Передбачається, що middleware TrueNAS, шар за його екранами віртуальних машин, — єдиний спосіб змінювати його віртуальні машини. Команда virsh через це SSH-з'єднання, тобто те, що запускають копіювання та відновлення віртуальних машин BombVault, іде в обхід нього, і TrueNAS може пізніше узгодити чи перезаписати стан, якого не створював. Це випливає з документованої поведінки TrueNAS і на справжньому сервері не спостерігалося. Це ризик того самого роду, що й узгодження VM Manager в Unraid змін, зроблених поза ним, тільки гостріший у TrueNAS.
3. Диски на zvol¶
Диски віртуальних машин TrueNAS часто є zvol, блочними пристроями ZFS у /dev/zvol/<pool>/<dataset>, а не файлами qcow2. restic не може копіювати блочний пристрій за його шляхом так, як копіює файл, тому BombVault впізнає диск zvol у XML домену (<source dev="..."> замість <source file="...">) і працює з ним за тим самим SSH-з'єднанням. Контейнеру BombVault інструменти ZFS не потрібні.
Копія zvol:
zfs snapshot <dataset>@bombvault-vm-<time>фіксує момент часу, зокрема й поки віртуальна машина працює.zfs clone -o volmode=dev -o readonly=onробить цей знімок читабельним як пристрій.volmode=devне дає хосту сканувати розділи гостя.ddчитає пристрій, і сирий образ потрапляє в restic одним файлом,/vm-disks/<dataset>.img, з тегомvm:<name>:zvol:<dev>. restic ріже його на шматки за вмістом, тож блоки, які не змінилися з минулої копії, не зберігаються заново.- Клон і знімок потім знищуються, чи вдалася копія, чи ні. Якщо BombVault зупинився посеред копіювання, наступна копія цього zvol спершу видаляє знімок
bombvault-vm-<time>і його клон<dataset>-bombvault-vm-<time>. Усі інші знімки він не чіпає і зберігає той, з якого щось ще клонували. Журнал називає, що видалено або збережено.
BombVault не використовує для цього zfs send. Кожен запис потоку send несе GUID знімка й поточну контрольну суму, тож restic не знайшов би нічого від минулої копії для повторного використання і щоразу зберігав би весь диск заново. Виміряно на TrueNAS SCALE 25.10 із zvol на 512 МіБ, що містить 200 МіБ даних: перша копія додала 211 МБ, друга без змін 52 КБ, а після зміни 1 МіБ 3,6 МБ. Той самий zvol через zfs send додавав 214 МБ під час кожного запуску.
Кожен запуск також записує маленький знімок із тегом vm:<name> з XML домену, коли всі диски вже всередині. У віртуальної машини, всі диски якої — zvol, файлового знімка немає, і саме цей знімок показує запуск під віртуальною машиною та робить її відновлюваною.
Відновлення записує кожен zvol назад на місці, так само як файловий диск записується у свій файл, тож відновлена віртуальна машина завантажує відновлені дані:
- Перш ніж щось зачеплено, BombVault перевіряє, що запуск містить образ кожного диска zvol. Запуск, де його немає, відхиляється, а віртуальна машина лишається як є.
- Наявний zvol спершу отримує знімок
<dataset>@bombvault-before-restore-<time>з часом у UTC, як і кожне ім'я знімка BombVault, тож воно може відрізнятися від місцевого годинника на кілька годин. Журнал називає його, аzfs rollbackдо нього скасовує відновлення, поки він найновіший знімок zvol. Коли з'являється новіший, наприклад від наступного відновлення, це робитьzfs rollback -r, знищуючи новіші знімки. Він лишається, поки ви не видалите його черезzfs destroy, коли відновлена віртуальна машина запрацює. - Zvol, якого більше немає, створюється з розміром, який він мав під час копіювання, а наявний іншого розміру повертається до цього розміру.
ddзаписує образ на/dev/zvol/<dataset>. За ввімкненого стиснення, як типово в TrueNAS, порожні частини образу повертаються як діри й не займають місця.
Для відновлення на інший екземпляр потрібен пул призначення. Воно переносить файлові диски в теку призначення, але тека не називає пулу ZFS, тому без нього BombVault відхиляє відновлення до його початку. Передайте пул параметром zvolPool у POST /api/foreign/restore: кожен zvol зберігає свій шлях нижче пулу (tank/vms/win10/disk0 на flashpool стає flashpool/vms/win10/disk0), і XML домену вказує на нього. У вікні Зі старої папки резервних копій на сторінці «Відновлення» поля для цього немає, тому воно доступне лише прямим викликом API. Відновлення на тому самому екземплярі записує кожен zvol назад у нього самого.
Експорт файлами пропускає zvol. Віртуальна машина, всі диски якої — zvol, відхиляється з цією причиною, тож відновіть її з копії. Для віртуальної машини з ще й файловими дисками експорт містить файлові диски та примітку, що називає пропущені zvol.
Це випробувано на TrueNAS SCALE 25.10 із ZFS 2.3.4: три копії пробного zvol, відновлення на місці після того, як zvol було перезаписано й він виріс, і відновлення на zvol, який видалили. Кожне відновлення читалося назад із тим самим SHA-256, що й у джерела, zvol знову мав старий розмір, а ні знімка, ні клона не лишилося. Ціла віртуальна машина, єдиний диск якої — zvol, була скопійована працюючою, із Graceful і з живим режимом, і вимкненою, і там само пройшло відновлення цілої віртуальної машини (видалити визначення, записати zvol, визначити, завантажити): zvol прочитався з контрольною сумою джерела, і віртуальна машина запустилася.
Файлові диски, як їх використовує Unraid, нічого з цього не зачіпає.
4. Стан vTPM¶
У віртуальної машини може бути віртуальний TPM, який потрібен гостям із Secure Boot і Windows 11. Його стан лежить поза диском і NVRAM, тож копія лише цих двох повернула б гостя з новим порожнім TPM.
- Passthrough TPM, справжня мікросхема, передана гостю, називає свій шлях у XML домену. BombVault зберігає його стан поруч з NVRAM через SSH і записує назад перед
virsh define, за можливості, як і NVRAM: невдале читання чи запис пишеться в журнал і не провалює копію чи відновлення. - Емульований vTPM, який TrueNAS налаштовує для гостей Windows 11 і Secure Boot, не публікує в XML домену шляху до стану, тому його стан не копіюється. BombVault не вгадує шлях, і копія завершується приміткою, що стану TPM цієї віртуальної машини в ній немає. Тримайте ключ відновлення такого гостя, наприклад ключ BitLocker, під рукою, перш ніж його відновлювати.
- Підключити TPM до віртуальної машини TrueNAS самостійно не можна. API пристроїв віртуальних машин у TrueNAS SCALE 25.10 приймає лише
CDROM,DISPLAY,NIC,PCI,RAW,DISKіUSBта відхиляєTPMяк невідомий тип.
Обробка TPM перевірена лише модульними тестами й на справжньому гості TrueNAS із vTPM не запускалася. Віртуальна машина без TPM копіюється й відновлюється точно так, як раніше.
NVRAM зберігається як звичайно. TrueNAS зберігає його для кожної віртуальної машини в /var/db/system/vm/nvram/<id>_<name>_VARS.fd, і XML домену називає цей шлях.
5. Імена віртуальних машин у TrueNAS¶
В Unraid ім'я віртуальної машини в libvirt — те, яке ви вибрали. TrueNAS вигадує ім'я в libvirt сам і змінював спосіб двічі:
| Версія TrueNAS | Ім'я в libvirt | Де живе ваше ім'я |
|---|---|---|
| 25.10 «Goldeye» | {id}_{name}, наприклад 1_debian |
в імені libvirt, після {id}_ |
| 26 | UUID віртуальної машини, наприклад 550e8400-e29b-41d4-a716-446655440000 |
лише в <title> XML домену |
На хості, який BombVault визначає як TrueNAS або який називає PLATFORM=truenas, список «Резервні копії» показує ваше ім'я: debian замість 1_debian у 25.10 і <title> замість UUID у 26 або UUID, якщо назви немає. Це лише те, що показує список. Кожен виклик virsh і налаштування окремої віртуальної машини, як і раніше, використовують ім'я libvirt, тож копіювання й відновлення завжди діють на потрібну віртуальну машину. У TrueNAS 26 це означає, що віртуальна машина, яку TrueNAS створює заново з новим UUID, з'являється як новий запис без своїх налаштувань, хоча її ім'я виглядає тим самим. В Unraid нічого не змінюється, зокрема й для віртуальної машини, названої 10_Windows.
Схему 25.10 спостерігали на справжньому сервері TrueNAS SCALE 25.10. Схема TrueNAS 26 узята з документації TrueNAS і перевірена лише модульними тестами.
Усунення несправностей¶
| Ознака | Причина та виправлення |
|---|---|
| Перевірити з'єднання зависає, потім завершується помилкою | До хоста не достукатися. Перевірте крок 3 (мережа, VLAN, файрвол), а також Host SSH: Address і Port. |
Permission denied (publickey), хоча ключ у authorized_keys |
StrictModes у sshd відхиляє файл ключа, бо в батьківської теки хибний власник чи режим. Це часто трапляється, коли /root/.ssh — посилання на флешку FAT (/boot/config/ssh/...), доступну для запису всім. Журнал хоста показує Authentication refused: bad ownership or modes for directory .... Додайте StrictModes no до конфігурації sshd хоста в глобальний розділ, до будь-якого блоку Match, потім виконайте /etc/rc.d/rc.sshd restart. Unraid під час кожного завантаження пише /etc/ssh/sshd_config заново, тож збережіть це, як описано нижче. |
Permission denied (publickey) і ключа справді немає |
Повторіть крок 2 і перевірте, що SSH увімкнено. |
Host key verification failed |
Виконайте docker exec BombVault rm -f /config/ssh/known_hosts і перевірте знову. |
Перевірка з кроку 3 пише UNREACHABLE |
Контейнер не сягає порту SSH хоста. Див. крок 3: доступ хоста до користувацьких мереж, маршрутизація VLAN або IP-шим чи IP у локальній мережі. |
| У Edit немає змінних | Імпортуйте шаблон заново. Наявний контейнер зберігає свою стару збережену конфігурацію. |
| Віртуальна машина зі знімками Unraid не копіюється й називає файл | Ланцюжок базових образів диска не можна пройти до кінця. Перевірте у VM Manager, що кожен знімок цього диска ще на місці й що названий файл існує всередині /mnt. |
Інші ознаки неполадок із віртуальними машинами описано в розділі Усунення несправностей.
Як пережити перезавантаження¶
Unraid під час кожного завантаження пише /etc/ssh/sshd_config заново, тому зміни на боці хоста доводиться робити заново під час завантаження:
- Порт SSH зберігається в
/boot/config/ident.cfg, задається через вебінтерфейс Unraid. StrictModes no, якщо він знадобився вище, не зберігається. Застосовуйте його під час завантаження з/boot/config/go:
# /boot/config/go: keep SSH key auth working with flash-based authorized_keys
( for i in $(seq 1 30); do [ -f /etc/ssh/sshd_config ] && break; sleep 2; done
grep -q '^StrictModes no' /etc/ssh/sshd_config || \
sed -i '0,/^Match /s/^Match /StrictModes no\n&/' /etc/ssh/sshd_config
# SIGHUP reloads sshd's config in place: it keeps the listener + open sessions
# and avoids the "killing listener process / Restarting SSH server daemon"
# warning that `rc.sshd restart` prints at boot. Only reload if sshd is already
# up; if it starts after this runs, it reads the edited config on its own.
pidof sshd >/dev/null && killall -HUP sshd ) &
- Власний ключ SSH BombVault і
~/.ssh/configлежать у/config(appdata) і створюються заново під час кожного запуску, тож переживають перезапуски контейнера та хоста.
Безпека¶
Авторизований ключ дає root на хості, той самий рівень довіри, що й сокет Docker, який BombVault уже використовує. Тримайте BombVault у довіреній мережі. Ключ ed25519 зберігається з режимом 0600 в appdata, а ключ хоста закріплений. Кожна команда хоста передається окремими аргументами, ніколи через віддалену оболонку, а SSH-з'єднання використовує BatchMode і тайм-аут підключення.