ZFS можна запускати всередині віртуальної машини на Proxmox. Люди роблять це щодня. Дехто навіть спокійно спить.
Але «як» має значення: HBA passthrough зазвичай — зрілий вибір, тоді як віртуальні диски — спокуслива скоринка, яка перетворюється на інцидент о 3 ночі, коли ви поєднаєте рівні кешування, порядок записів і «допоміжні» RAID-контролери.
Прийміть рішення спочатку: що ви оптимізуєте
Є лише кілька вагомих причин розміщувати ZFS всередині VM:
- Ви хочете можливості ZFS у гостьовій системі: нативні workflow send/receive, політики на рівні dataset, шифрування, снапшоти, якими керує гість.
- Ви надаєте «зберігання як сервіс» для, наприклад, Kubernetes і хочете відокремити стек зберігання від життєвого циклу гіпервізора.
- Ви мігруєте з bare-metal ZFS і хочете зберегти операційну пам’ять і звички.
- У вас обмеження по обладнанню (спільні хости, обмежена кількість посадкових місць) і ви консолідуєте, не відмовляючись від семантики ZFS.
Є також причини, що здаються легітимними, поки ними не стають:
- «Я просто створю кілька віртуальних дисків і дам ZFS ними керувати.» Це не «неправильно», але додає шари кешування, бар’єри запису та звітування про помилки так, що збої стають важчими для розуміння. Ви платите податок на надійність пізніше.
- «Passthrough лякає.» Це не страшно. Це вибагливо. Це різні речі.
Якщо хочете чітку рекомендацію за замовчуванням:
- Для серйозних даних: пропустіть HBA (або окремі NVMe) у гість і дайте гостю бачити справжні диски.
- Для тимчасових або тестових навантажень: віртуальні диски підходять, але обирайте безпечні режими кешу і приймайте обмеження.
Єдиний дозволений ярлик: якщо дані важливі і ви питаєте «це нормально?», то це не нормально. Використовуйте passthrough.
Цікавинки та коротка історія (згодом знадобиться)
- ZFS створювали, щоб покінчити з мовчазною корупцією даних, і він очікує бачити помилки пристроїв і порядок операцій. Віртуалізоване зберігання часто це розмиває.
- «ZIL» за замовчуванням не окремий журнал. Це intent log на пулі; SLOG — це лише зовнішній пристрій для синхронних записів.
- Диски з 4K секторами змусили всіх піклуватися про вирівнювання. Ось навіщо існує ashift, і чому «бенчмарк гарний» все одно може бути помилкою.
- VT-d/IOMMU passthrough колись був розкішшю. Тепер це звично, але топологія PCIe материнської плати все ще вирішує, чи буде ваш день легким.
- Virtio спроектовано як паравіртуалізований і швидкий, але це все ж абстракція. Абстракції ховають речі, включно з болем.
- Кеші запису на RAID-контролерах спричинили десятиліття несподіваних втрат даних. Деякі з тих контролерів ще в серверах, посміхаються ввічливо.
- Контрольні суми ZFS покривають дані й метадані, але він не може перевірити те, що ніколи не отримав. Якщо гіпервізор бреше — ZFS не може сперечатися.
- Потреба NVMe для передбачуваності з’явилася після швидкості. Сплески затримки важливіші для VM, ніж загальний показник пропускної здатності.
Дві моделі: HBA passthrough проти віртуальних дисків
Модель A: HBA passthrough (або passthrough пристрою)
Це модель «ZFS бачить справжні диски». Ви пробрасываєте HBA (класично LSI/Broadcom в IT mode) або цілком NVMe-пристрої, і гість володіє стеком зберігання від контролера до пулу.
Що ви отримуєте:
- Реальне звітування помилок (SMART де підтримується, реальні коди стану, реальні таймаути).
- Передбачуваний порядок записів: менше ситуацій «гість думав, що запис стійкий».
- Чистіше тюнінгування продуктивності: ви тюнінгуєте ZFS, а не ZFS плюс QEMU плюс хост-файлова система плюс бекенд зберігання.
- Scrub і resilver ведуть себе як справжній ZFS, а не як «ZFS поверх чийогось файлу».
Що ви платите:
- IOMMU групи можуть змусити вас пробросити більше пристроїв, ніж хочете (або взагалі заблокувати).
- Жива міграція стає складною або неможливою, якщо не переносити фізичний пристрій (що неможливо).
- Видимість з боку хоста зменшується. Хост не може легко робити резервні копії «всередині» пулу без співпраці гостя.
- Операційне управління: тепер ви підтримуєте ZFS у гостьовій системі. Це нормально — просто визнайте це.
Модель B: Віртуальні диски (qcow2/raw на ZFS, LVM-thin, Ceph тощо)
Це модель «ZFS у гості, але диски гостьової системи — віртуальні». Гість бачить /dev/vda або /dev/sdX віртуальні пристрої. Ці пристрої підкріплені чимось на хості: zvol ZFS, файл на ZFS, логічний том LVM або розподілений бекенд як Ceph.
Що ви отримуєте:
- Проста життєва робота: снапшоти, бекапи, клонування на рівні гіпервізора.
- Можлива жива міграція (залежить від бекенду).
- Незалежність від обладнання: без драм з IOMMU.
- Централізований моніторинг зі сторони хоста.
Що ви платите:
- Ви накладаєте файлові системи/стеки зберігання одне на одне. Коли воно ламається — ви дебагаєте всю «лазанью».
- Вибір режиму кешу має значення. Один неправильно встановлений біт — і «надійний запис» стає «оптимістичною вигадкою».
- Поводження TRIM/discard може дивувати, особливо зі снапшотами.
- SMART та детальна телеметрія дисків зазвичай зникають (або стають «краще, ніж нічого»).
Правило з позицією: Якщо ви плануєте запускати ZFS у гості, не використовуйте qcow2 як бекенд, якщо лише ви свідомо не обираєте компроміс між коректністю та зручністю. Якщо наполягаєте на віртуальних дисках — використовуйте raw або блочні пристрої.
Жарт #1: Стек зберігання з трьома шарами кешу — як корпоративна організаційна діаграма: усі претендують на власність, ніхто не бере відповідальності.
IOMMU реалії: групи, ACS і чому ваш NIC пересунувся
Passthrough — це не «перемкнути тумблер». Це «переконати платформу ізолювати PCIe-пристрій так, щоб гіпервізор міг передати його гостю, не перетворивши DMA на кошмар». Саме це робить IOMMU: забезпечує ремапінг і ізоляцію для DMA пристроїв.
Що зазвичай йде не так
- Ваш HBA ділить IOMMU групу з чимось, що вам потрібне (NIC, USB-контролер, іноді весь PCIe root port). Якщо ви передаєте його, ви втрачаєте інший пристрій на хості.
- ACS відсутній або обмежений. Деякі споживчі плати зроблені для ігрових GPU, а не для суворої ізоляції пристроїв.
- Проблеми скидання (reset quirks): деякі HBA не скидаються чисто між стартами VM, що призводить до синдрому «працює після перезавантаження хоста».
- Обробка переривань і прив’язка CPU: це не про IOMMU прямо, але саме там з’являється латентність після «успішного» passthrough.
Що насправді означає «ACS override»
Linux іноді може розділити IOMMU групи за допомогою параметра ядра ACS override. Це хак. Іноді це прийнятний хак, іноді — такий, що закінчується нараданням у конференції з комплаєнсу. Якщо платформа не може забезпечити ізоляцію, ви просите програмне забезпечення вдавати, що воно може.
Для домашніх лабораторій ACS override часто «підходить». Для продакшну з реальними ризиками — купуйте обладнання з правильною PCIe ізоляцією. Ваш майбутній я надішле вам кошик фруктів. Або, принаймні, не розбудить о третій ночі.
Продуктивність і коректність: де ховаються проблеми
Порядок записів: тихий вбивця
ZFS дбає про порядок записів, бо він транзакційний. Він очікує, що якщо ОС каже «це на стійкому сховищі», пристрій (або стек під ним) погодиться. Віртуалізація може ламати це тонко:
- Режим кешу хоста «writeback» може підтверджувати записи раніше, ніж вони стануть стійкими.
- Бекенд зберігання може змінювати порядок записів, якщо бар’єри/флаші не виконуються end-to-end.
- Хости без UPS із агресивними кешами перетворюють відключення живлення на майстер-клас з цілісності даних.
Практичний висновок: якщо ви використовуєте віртуальні диски, обирайте режими кешу й бекенди, які зберігають семантику довговічності. Якщо passthrough — перевірте, чи контролер не робить RAID або не бреше про flush.
Подвійний ZFS: так, люди так роблять; ні, не варто за замовчуванням
Запуск ZFS на хості і ZFS всередині гостя (гостьові диски на zvol або файлі) поширений. Це також чудовий спосіб створити заплутані домени відмов:
- Гість ZFS думає, що керує дисками; фактично він керує «шматком пулу».
- Таймінги scrub і IO-патерни можуть конфліктувати: host scrub плюс guest scrub = «чому все повільне?»
- Стиснення і вибір recordsize можуть давати сумарний негативний ефект.
- Write amplification збільшується, особливо для дрібних випадкових записів.
Якщо вам потрібні функції ZFS, оберіть шар, який ними володіє. Host ZFS з zvol для VM-дисків підходить. Guest ZFS з passthrough підходить. ZFS-on-ZFS — це спеціальний випадок, а не стандартна практика.
SLOG і синхронні записи всередині VM
Якщо ваше навантаження багато синхронних операцій (NFS, бази даних з fsync, образи VM у гості), ZFS торкається шляху ZIL. Усередині VM це ускладнюється:
- Швидкий SLOG допомагає лише якщо семантика синхронності справді реалізована end-to-end.
- Якщо хост бреше про flush, ваш «швидкий sync» — просто швидшеюча корупція.
- Якщо ви пробросили NVMe як SLOG, переконайтеся, що воно має захист від втрати живлення, якщо вас цікавлять підтверджені синхронні записи.
TRIM/discard і тонке провізіювання: простір бреше в обидва боки
З віртуальними дисками тонке провізіювання зручне, поки ви не виявите, що гість не може ефективно повернути простір, або снапшоти хоста перешкоджають звільненню. При passthrough TRIM ближчий до реальності (але залежить від підтримки диска/контролера). Операційна різниця велика: одна модель фейлить «загадковим заповненням пулів», інша — «загадковим зношенням SSD». Оберіть пригоду, а потім моніторьте відповідно.
Парафразована ідея (приписують): Уернер Вогельс має відомий операційний маніфест: «Все ламається, завжди». Проєктуйте так, ніби це правда.
Практичні завдання: команди, виводи та що означає результат (і що робити далі)
Зберігання не дебагується на інтуїції. Його дебагують за доказами. Нижче конкретні перевірки, які працюють на реальних Proxmox-хостах і реальних ZFS-гостях.
Завдання 1: Підтвердіть, що IOMMU реально увімкнений на Proxmox-хості
cr0x@server:~$ dmesg | egrep -i 'DMAR|IOMMU|AMD-Vi' | head -n 20
[ 0.823456] DMAR: IOMMU enabled
[ 0.823789] DMAR: Host address width 39
[ 0.824001] DMAR: DRHD base: 0x000000fed90000 flags: 0x0
Що це означає: У вас увімкнено Intel VT-d/DMAR і ядро його використовує.
Рішення: Якщо ви не бачите «IOMMU enabled», виправте налаштування BIOS і параметри завантаження ядра перед налаштуванням passthrough.
Завдання 2: Перевірте параметри завантаження ядра для IOMMU і дружності до passthrough
cr0x@server:~$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.8.12-4-pve root=/dev/mapper/pve-root ro quiet intel_iommu=on iommu=pt
Що це означає: intel_iommu=on увімкнює IOMMU; iommu=pt зменшує накладні витрати для непрошаємих пристроїв, використовуючи passthrough mappings.
Рішення: Якщо ви не бачите прапорів IOMMU, додайте їх і перезавантажтеся. Для AMD шукайте amd_iommu=on.
Завдання 3: Ідентифікуйте HBA і його PCI-адресу
cr0x@server:~$ lspci -nn | egrep -i 'sas|sata|lsi|megaraid'
03:00.0 Serial Attached SCSI controller [0107]: Broadcom / LSI SAS2008 PCI-Express Fusion-MPT SAS-2 [1000:0072] (rev 03)
Що це означає: Контролер на 03:00.0 і це пристрій класу LSI SAS2008.
Рішення: Використайте PCI-адресу в конфігурації passthrough. Також підтвердіть, що він в IT mode, якщо хочете, щоб ZFS бачив індивідуальні диски.
Завдання 4: Подивіться IOMMU групу для цього пристрою
cr0x@server:~$ readlink -f /sys/bus/pci/devices/0000:03:00.0/iommu_group
/sys/kernel/iommu_groups/18
cr0x@server:~$ ls -l /sys/kernel/iommu_groups/18/devices
total 0
lrwxrwxrwx 1 root root 0 Feb 4 10:12 0000:03:00.0 -> ../../../../bus/pci/devices/0000:03:00.0
Що це означає: HBA сам у своїй групі. Це хороший сценарій.
Рішення: Якщо інші критичні пристрої ділять групу, перемістіть у інший слот PCIe, змініть налаштування плати або відмовтеся від passthrough на цьому обладнанні.
Завдання 5: Перевірте, який драйвер зараз володіє HBA (на хості)
cr0x@server:~$ lspci -k -s 03:00.0
03:00.0 Serial Attached SCSI controller: Broadcom / LSI SAS2008 PCI-Express Fusion-MPT SAS-2 (rev 03)
Subsystem: Broadcom / LSI SAS2008 PCI-Express Fusion-MPT SAS-2
Kernel driver in use: mpt3sas
Kernel modules: mpt3sas
Що це означає: Хост використовує mpt3sas. Для passthrough ви хочете, щоб vfio-pci володів пристроєм.
Рішення: Прив’яжіть його до vfio-pci; якщо хост використовує його для власного зберігання, зупиніться і перегляньте архітектуру.
Завдання 6: Прив’яжіть HBA до vfio-pci (і перевірте)
cr0x@server:~$ echo "options vfio-pci ids=1000:0072" | sudo tee /etc/modprobe.d/vfio.conf
options vfio-pci ids=1000:0072
cr0x@server:~$ sudo update-initramfs -u
update-initramfs: Generating /boot/initrd.img-6.8.12-4-pve
cr0x@server:~$ sudo reboot
Connection to server closed by remote host.
cr0x@server:~$ lspci -k -s 03:00.0
03:00.0 Serial Attached SCSI controller: Broadcom / LSI SAS2008 PCI-Express Fusion-MPT SAS-2 (rev 03)
Kernel driver in use: vfio-pci
Kernel modules: mpt3sas
Що це означає: vfio-pci володіє пристроєм; хост більше не торкається його дисків.
Рішення: Тепер безпечно додавати його до VM. Якщо він все ще прив’язаний до mpt3sas, ви пропустили initramfs або маєте конфліктні налаштування.
Завдання 7: Прикріпіть HBA до Proxmox VM і підтвердіть, що QEMU бачить його
cr0x@server:~$ sudo qm set 120 -hostpci0 03:00.0,pcie=1
update VM 120: -hostpci0 03:00.0,pcie=1
cr0x@server:~$ sudo qm config 120 | egrep -i 'hostpci|machine|bios'
bios: ovmf
hostpci0: 03:00.0,pcie=1
machine: q35
Що це означає: Ви використовуєте q35 і OVMF, добрі для сучасного PCIe passthrough.
Рішення: Якщо у вас legacy i440fx, перейдіть на q35, якщо немає вагомої причини цього не робити.
Завдання 8: Всередині гостя підтвердіть, що диски видимі, і ідентифікуйте їх безпечно
cr0x@zfs-vm:~$ lsblk -o NAME,SIZE,MODEL,SERIAL,TYPE
NAME SIZE MODEL SERIAL TYPE
sda 14.6T ST16000NM001G ZR123ABC disk
sdb 14.6T ST16000NM001G ZR124DEF disk
sdc 14.6T ST16000NM001G ZR125GHI disk
sdd 14.6T ST16000NM001G ZR126JKL disk
Що це означає: Гість бачить справжні диски з моделлю/серійним. Саме це потрібно для ідентичності пристроїв у ZFS.
Рішення: Використовуйте стійкі ідентифікатори (/dev/disk/by-id) при створенні пулів. Якщо диски показують як «QEMU HARDDISK», ви не використовуєте справжній passthrough пристрою.
Завдання 9: Створіть пул зі стійкими шляхами пристроїв і правильним ashift
cr0x@zfs-vm:~$ ls -l /dev/disk/by-id | egrep 'ZR123ABC|ZR124DEF|ZR125GHI|ZR126JKL'
lrwxrwxrwx 1 root root 9 Feb 4 10:20 ata-ST16000NM001G_ZR123ABC -> ../../sda
lrwxrwxrwx 1 root root 9 Feb 4 10:20 ata-ST16000NM001G_ZR124DEF -> ../../sdb
lrwxrwxrwx 1 root root 9 Feb 4 10:20 ata-ST16000NM001G_ZR125GHI -> ../../sdc
lrwxrwxrwx 1 root root 9 Feb 4 10:20 ata-ST16000NM001G_ZR126JKL -> ../../sdd
cr0x@zfs-vm:~$ sudo zpool create -o ashift=12 tank raidz1 \
/dev/disk/by-id/ata-ST16000NM001G_ZR123ABC \
/dev/disk/by-id/ata-ST16000NM001G_ZR124DEF \
/dev/disk/by-id/ata-ST16000NM001G_ZR125GHI \
/dev/disk/by-id/ata-ST16000NM001G_ZR126JKL
cr0x@zfs-vm:~$ zpool status tank
pool: tank
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz1-0 ONLINE 0 0 0
ata-ST16000NM001G_ZR123ABC ONLINE 0 0 0
ata-ST16000NM001G_ZR124DEF ONLINE 0 0 0
ata-ST16000NM001G_ZR125GHI ONLINE 0 0 0
ata-ST16000NM001G_ZR126JKL ONLINE 0 0 0
Що це означає: Пул онлайн і використовує стабільні ідентифікатори. ashift=12 загалом правильний для 4K-секторних дисків (і безпечний для більшості сучасних дисків).
Рішення: Якщо ви помилитеся з ashift, ви не «поправите» це пізніше. Потрібно перебудовувати. Вирішіть зараз, а не після зберігання 40 ТБ.
Завдання 10: Перевірте поведінку sync і сигнали затримки від ZFS
cr0x@zfs-vm:~$ sudo zfs set sync=standard tank
cr0x@zfs-vm:~$ zpool iostat -v tank 1 3
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 1.20T 42.5T 0 210 0 52.0M
raidz1-0 1.20T 42.5T 0 210 0 52.0M
sda - - 0 52 0 13.1M
sdb - - 0 52 0 13.0M
sdc - - 0 53 0 13.0M
sdd - - 0 53 0 12.9M
Що це означає: Розподіл IO виглядає адекватно. Якщо один диск постійно повільніший — це проблема диска/контролера/кабелю, а не «ZFS такий-то».
Рішення: Якщо бачите дуже нерівномірні записи — перевірте конкретний шлях пристрою, кабелі або порт HBA.
Завдання 11: На Proxmox-хості перевірте бекенд диска VM і режим кешу (сценарій віртуальних дисків)
cr0x@server:~$ qm config 130 | egrep -i 'scsi|virtio|cache|discard'
scsi0: local-zfs:vm-130-disk-0,cache=none,discard=on,iothread=1,size=200G
scsihw: virtio-scsi-single
Що це означає: Ця VM використовує ZFS zvol на хості (local-zfs), з cache=none (безпечніше для довговічності), discard увімкнено і є IO-потік.
Рішення: Якщо ви бачите cache=writeback на хості без BBU чи UPS — змініть. Ви покладаєтесь на вдачу і сподівання, що електрика поводитиметься ввічливо.
Завдання 12: Виміряйте реальну затримку з боку гостя
cr0x@zfs-vm:~$ iostat -x 1 3
Linux 6.5.0 (zfs-vm) 02/04/2026 _x86_64_ (8 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
2.13 0.00 3.45 8.20 0.10 86.12
Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %util await svctm
sda 0.00 55.00 0.00 14080.0 0.00 1.00 62.00 11.20 0.35
sdb 0.00 54.00 0.00 13824.0 0.00 0.00 61.50 11.10 0.34
sdc 0.00 56.00 0.00 14336.0 0.00 0.00 62.30 11.30 0.35
sdd 0.00 55.00 0.00 14080.0 0.00 0.00 62.10 11.25 0.35
Що це означає: await ≈ 11ms для записів — правдоподібно для HDD під помірним навантаженням. Якщо await стрибає до сотень мс — у вас черги або зупинки бекенду.
Рішення: Якщо %steal високий — у вас contention по vCPU; тюнінг зберігання не вирішить. Якщо await високий при низькому util — підозрійте віртуалізаційні накладні або зупинки на хості.
Завдання 13: Підтвердіть, що ZFS не страждає від нестачі пам’яті (ARC-thrash виглядає як «повільні диски»)
cr0x@zfs-vm:~$ cat /proc/meminfo | egrep 'MemTotal|MemFree|Cached'
MemTotal: 33554432 kB
MemFree: 1823400 kB
Cached: 16200480 kB
cr0x@zfs-vm:~$ sudo arcstat 1 3
time read miss miss% dmis dm% pmis pm% mmis mm% arcsz c
10:33:01 812 142 17 60 42 82 58 0 0 12.0G 12.0G
10:33:02 790 150 19 65 43 85 57 0 0 12.0G 12.0G
10:33:03 805 155 19 70 45 85 55 0 0 12.0G 12.0G
Що це означає: ARC стабільний на 12G і miss rate помірний. Якщо ARC малий або постійно зменшується — продуктивність почуватиметься як «рандомні IO прокляті».
Рішення: Якщо VM не має достатньо RAM для ARC — дайте їй RAM, перемістіть ZFS на хост або прийміть профіль продуктивності.
Завдання 14: Переконайтеся, що ви випадково не запускаєте ZFS поверх RAID-тома
cr0x@zfs-vm:~$ sudo smartctl -a /dev/sda | egrep 'Vendor|Product|Rotation|SMART support'
Vendor: SEAGATE
Product: ST16000NM001G
Rotation Rate: 7200 rpm
SMART support is: Available - device has SMART capability.
Що це означає: Гість може опитувати SMART, що вказує на відносно прямий шлях до диска. Якщо ви бачите апаратний RAID-том натомість — часто отримаєте загальні рядки виробника і відсутність SMART.
Рішення: Якщо ви на апаратному RAID — зупиніться і перепрошити контролер в IT/HBA режим або замініть його. ZFS хоче диски, а не театральні представлення.
Завдання 15: На Proxmox-хості перевірте IO wait і насиченість підлягаючих пристроїв
cr0x@server:~$ pveperf
CPU BOGOMIPS: 76800.00
REGEX/SECOND: 1975679
HD SIZE: 98.23 GB (rbd)
FSYNCS/SECOND: 2321.41
DNS EXT: 37.82 ms
DNS INT: 0.86 ms
Що це означає: FSYNCS/SECOND дає грубу уяву про синхронну продуктивність root/storage бекенду Proxmox. Це не бенчмарк, але ловить очевидні «вузли хворі» проблеми.
Рішення: Якщо FSYNCS/SECOND жахливий на вузлі, що має бути здоровим, розслідуйте зберігання хоста першим. Тюнінг гостя не переможе зламаний бекенд.
Швидкий план діагностики (що перевіряти першим/другим/третім)
Це план для випадків «повільно» і «ZFS сердиться». Не імпровізуйте. Дійте по ланцюжку.
Перший крок: вирішіть, де зберігається істина про зберігання
- HBA/пристрій passthrough: поводьтеся з гостем як з bare metal. Починайте в гості при перевірці здоров’я дисків і сигналів ZFS.
- Віртуальні диски: починайте на хості. Гість може звітувати лише те, що він бачить, і це може бути «ввічливою брехнею».
Другий крок: визначте, це затримка, пропускна здатність чи планування CPU
- У гості:
iostat -x 1і дивітьсяawaitта%steal. - На хості:
iostat -x 1іtop(абоhtop) для IO wait.
Якщо %steal підвищений — можливо проблема планування vCPU. Якщо await дуже велике при низькій util — підозрюйте черги на гіпервізорі, flush-стали або хворий контролер.
Третій крок: перевірте сам ZFS, що він робить
zpool status -xv: помилки, degraded vdev, проблеми з контрольними сумами.zpool iostat -v 1: дисбаланс по vdev.zfs get compressratio,recordsize,atime,syncдля відповідного dataset.
Четвертий крок: підтвердіть, що ви не створили часову бомбу кеша запису
- Віртуальні диски: підтвердіть, що режим кешу Proxmox —
noneабо свідомо обраний безпечний варіант. - Passthrough: переконайтеся, що контролер в IT mode і не робить writeback без захисту.
П’ятий крок: шукати специфічні для віртуалізації «підводні камені»
- Увімкнені IO-потоки для virtio-scsi коли потрібно.
- Налаштування multiqueue, pinning vCPU і вирівнювання NUMA для важких IO навантажень.
- Відключений ballooning для ZFS-гостей (пам’ять під тиском + ARC = сум).
Три корпоративні історії з тилів зберігання
Інцидент: невірне припущення («гипервізор збереже»)
Середня компанія використовувала Proxmox для внутрішніх сервісів. Команда захотіла можливості ZFS всередині VM через реплікаційний workflow на базі zfs send/receive. Розумно. Створили VM, приєднали qcow2-диски на хостовому зберіганні і побудували raidz пул всередині гостя. Бенчмарки виглядали добре. Усі були задоволені.
Місяці потому сталася подія з живленням. Нічого драматичного. Коротке відключення, UPS зробив, що міг, але кілька вузлів впали жорстко. Коли кластер піднявся, пул однієї VM імпортувався з помилками контрольних сум. Інший не імпортувався без форсу. Схоже на часткові записи.
Корінь проблеми не був одною помилкою. Це стек припущень: режим кешу хоста підтверджував записи раніше, ніж вони були стійкі, а підлягаючий бекенд мав власну поведінку кешу. Гостьовий ZFS вірив, що отримує коректні flush semantics. Насправді — ні. Пул вистояв настільки, щоб бути лякаючим: не чиста втрата, не очевидна. Наступив довгий і дорогий тиждень.
Виправлення було нудним і структурним: вони перебудували дизайн. Для ZFS-in-VM робочих навантажень, що мали значення, перейшли на HBA passthrough і валідували довговічність. Для тих, хто потребував живої міграції і снапшотів хоста — перестали запускати ZFS в гості і використовували host ZFS. Те саме обладнання. Інший контракт.
Оптимізація, що повернулася проти: «Давайте використаємо швидший режим кешу»
Інша організація мала застосунок з великою кількістю fsync. Хтось помітив високу затримку і низьку пропускну здатність на віртуальних дисках. Вони змінили режим кешу Proxmox на writeback, бо це покращило графіки. І справді — затримка впала, пропускна здатність зросла, всі повернулися до ігнорування питання зберігання.
Потім настало технічне обслуговування під час шумного періоду. Аплікація перезапустилась, але база даних повідомила про корупцію. Не катастрофа — більше «знайшов речі, які не можу узгодити». Бекапи були, але відновлення означало втрату між снапшотами плюс болісне вікно відновлення.
Postmortem виявив очевидне: writeback кеш покращив показники, підтверджуючи записи раніше. Менш очевидно: ніхто не визначив, що означає «стійкий запис» в їхньому середовищі. Вони оптимізували метрику без чіткого визначення вимог надійності.
Вони відкотилися до безпечніших налаштувань кешу, додали захист від втрати живлення там, де потрібно, і прогнали тести з симуляціями падінь. Продуктивність впала, але стала чесною. Це той тип, з яким можна працювати.
Нудна, але правильна практика, що врятувала день: «Ми тестуємо resilver та scrub як функцію»
Третя команда запускала ZFS у VM з HBA passthrough. Не було гламурно; це обрали за передбачувану поведінку при відмовах і чисту телеметрію. Команда мала звичку, яка виглядала надмірною: вони планували регулярні scrubs і раз на квартал навмисно відключали диск у вікні техобслуговування, щоб відпрацювати процедури заміни і resilver.
Одного дня диск почав кидати періодичні помилки. Нічого драматичного: кілька read error, що спочатку автокоригувалися. Scrub позначив це, і оскільки команда вже бачив це раніше, діяли без дебатів. Замінити диск, resilver і продовжити.
Через два тижні інший диск тієї ж партії почав те саме. Знову: заміна, resilver, рух вперед. Ніякої паніки, ніяких «чому пул деградований» у Slack.
Справжній виграш прийшов пізніше: виробник визнав проблему з певною партією. Багато компаній дізналися про це з втратою vdev під час resilver. Ця — дізналася завдяки тремору на графіку scrub. Практика була нудною. Результат — ні.
Жарт #2: Єдина річ більш настирлива за bit rot — це таблиця, що стверджує, що ваше зберігання «зелене».
Типові помилки: симптом → корінь проблеми → виправлення
1) ZFS-пул гостьової системи пошкоджений після збою хоста
Симптоми: Пул імпортується з помилками, з’являються помилки контрольних сум, dataset поводяться дивно після некоректного вимкнення.
Корінь проблеми: Режим кешу віртуального диска і бекенд не дотримувалися flush semantics end-to-end; гостьовий ZFS довіряв довговічності, якої не було.
Виправлення: Використовуйте безпечні режими кешу (cache=none для багатьох налаштувань), уникайте qcow2 для ZFS-in-guest якщо важлива цілісність, або перейдіть на HBA/device passthrough.
2) «Passthrough не працює», хоча IOMMU увімкнений
Симптоми: VM не стартує, Proxmox повідомляє помилки VFIO, пристрій зникає або спричиняє нестабільність хоста.
Корінь проблеми: Пристрій ділить IOMMU групу з критичним обладнанням хоста, або пристрій має проблеми зі скиданням.
Виправлення: Перевірте членство в групі; перемістіть слот PCIe; оберіть іншу материнську плату/CPU платформу; іноді оновлення BIOS/прошивки допомагає. Уникайте ACS override для продакшну з ризиками.
3) Гостьовий ZFS повільний, але диски в порядку
Симптоми: Висока затримка, низька продуктивність, без очевидних SMART-помилок, ZFS не показує помилок.
Корінь проблеми: Конкуренція за vCPU і високий %steal, або ballooning пам’яті викликає ARC-thrash.
Виправлення: Прив’яжіть vCPU для важких IO навантажень, вимкніть ballooning для ZFS-гостей, виділіть достатньо RAM і уникайте оверхеду CPU на storage VM.
4) Пул постійно «таємничо заповнюється» з тонкопровізованими віртуальними дисками
Симптоми: Зберігання хоста заповнюється, хоча гість показує вільний простір; discard не звільняє простір як очікувалося.
Корінь проблеми: Discard/TRIM не увімкнені end-to-end, снапшоти перешкоджають звільненню, або бекенд не ефективно «пробиває дірки».
Виправлення: Увімкніть discard на Proxmox-дисках, переконайтеся, що гість виконує TRIM, керуйте снапшотами свідомо і моніторьте фактичний розмір розподіленого простору на хості.
5) Scrub надто повільні всередині VM
Симптоми: Scrub займає дуже довго; продуктивне навантаження страждає під час вікон scrub.
Корінь проблеми: Scrub IO конкурує з IO VM; при віртуальних дисках може бути складна подвійна конкуренція (хост плюс гість). При passthrough часто просто «диски зайняті», але може бути й питання глибини черги.
Виправлення: Плануйте scrubs, встановіть пріоритети scrub/resilver, уникайте одночасного запуску scrub на хості й у гості, і перевірте налаштування черг HBA якщо потрібно.
6) «ZFS не бачить SMART» після passthrough
Симптоми: smartctl повертає обмежену інформацію або помилки; диски показують загальні ідентифікатори.
Корінь проблеми: Ви пробросили RAID-контролер, що все ще робить RAID, або стоїте за експандером/контролером, який потребує специфічних параметрів smartctl.
Виправлення: Переведіть контролер у IT/HBA режим; використайте коректні ключі smartctl для SAS; підтвердіть, що гість бачить реальні пристрої, а не логічні томи.
Контрольні списки / поетапний план
План A: Ви хочете ZFS у VM для реальних даних (рекомендований шлях)
- Купіть/оберіть обладнання, що підтримує чисту IOMMU ізоляцію. Серверні плати ведуть себе краще; топологія PCIe має значення.
- Увімкніть VT-d/AMD-Vi в BIOS, завантажте з прапорами IOMMU, перевірте через
dmesg. - Ідентифікуйте HBA, підтвердіть IT mode, і що він сам у своїй IOMMU групі.
- Прив’яжіть HBA до vfio-pci, перезавантажтеся, підтвердіть володіння драйвером.
- Створіть виділену storage VM: q35 + OVMF, без ballooning, достатньо RAM, розумна кількість vCPU, розгляньте pinning CPU при чутливості до затримки.
- Пропрутніть HBA, а потім всередині гостя створіть пул, використовуючи
/dev/disk/by-idшляхи. - Встановіть властивості ZFS свідомо для кожного dataset (recordsize, compression, atime).
- Моніторте і тестуйте поведінку при відмовах: scrubs, процедура заміни диска, перезавантаження, і планована симуляція втрати живлення, якщо ви готові.
План B: Ви наполягаєте на віртуальних дисках, але хочете зменшити радіус ураження
- Надавайте перевагу raw або zvol-backed дискам перед qcow2 для ZFS-in-guest.
- Використовуйте virtio-scsi з
iothread=1для важких IO-патернів. - Свідомо встановлюйте режим кешу: за замовчуванням
cache=none, якщо не можете довести іншу гарантію довговічності. - Увімкніть discard end-to-end, якщо тонке провізіювання важливе.
- Не запускайте host ZFS scrub одночасно з guest ZFS scrub, якщо можна уникнути. Рознесіть техобслуговування.
- Протестуйте відновлення: симулюйте некоректне вимкнення VM і перевірте імпорт пулу та цілісність застосунків.
План C: Вам насправді не потрібен ZFS у гості
- Запускайте ZFS на Proxmox-хості і використовуйте zvol для VM-дисків.
- Використовуйте снапшоти і бекапи Proxmox на рівні гіпервізора.
- Експонуйте зберігання гостям через virtio і тримайте логіку зберігання в одному місці.
Питання та відповіді
1) Чи passthrough HBA завжди швидший?
Ні. Частіше він більш передбачуваний. Віртуальні диски можуть бути швидкими на хороших бекендах, але passthrough зменшує шари, що додають стрибки затримки і семантичні невідповідності.
2) Чи можна жити-мігрувати VM з HBA passthrough?
Ні в практичному сенсі. Диски фізично приєднані до одного хоста. Можна мігрувати обчислення, але не кабелі.
3) Чи нормально запускати ZFS на qcow2?
Для тестування і некритичних даних — так. Для важливих даних — це привабливий шлях до фрагментації і складності, що ускладнює аналіз відмов.
4) Якщо я використовую Proxmox host ZFS, чи варто також використовувати guest ZFS?
Відповідь за замовчуванням: ні. Оберіть один шар, який відповідальний за ZFS. ZFS-on-ZFS — нішевий дизайн, не краща практика.
5) Який режим кешу слід використовувати для віртуальних дисків?
Почніть з cache=none. Це не найшвидший варіант, але чесний. Якщо змінюєте — робіть це з чіткою історією довговічності (захист живлення, гарантії бекенду, тести падінь).
6) Чи допомагає SLOG ZFS у VM?
Іноді. Він допомагає латентності синхронних записів, коли навантаження змушує sync. Але він допоможе лише якщо flush/durability семантика реальна end-to-end.
7) Чому мій HBA ділить IOMMU групу з NIC?
Тому що топологія PCIe і підтримка ACS визначається дизайном материнської плати і CPU. Linux не може вигадати ізоляцію, якої не надало обладнання.
8) Чи варто вмикати ballooning на ZFS VM?
Ні, якщо ви цінуєте стабільність продуктивності. ZFS використовує пам’ять для ARC; ballooning робить кешування сюрпризним евиктом.
9) Чи потрібен саме IT mode?
Якщо ви хочете, щоб ZFS коректно керував окремими дисками — так. RAID mode ховає диски за логічними томами і часто заважатиме видимості помилок і відновленню.
10) Яка найпростіша «безпечна» архітектура для Proxmox + зберігання?
Host ZFS + zvol VM-диски + Proxmox бекапи — найпростіша безпечна конфігурація для багатьох середовищ. Додавайте passthrough лише коли потрібно, щоб гість володів ZFS.
Практичні наступні кроки
Оберіть дизайн залежно від того, що ви хочете гарантувати:
- Якщо пріоритет — цілісність даних і чіткі моделі відмов: створіть storage VM з HBA/device passthrough і поводьтеся з нею як зі сховищним сервером.
- Якщо пріоритет — зручність операцій і мобільність: не запускайте ZFS у гості; запускайте його на Proxmox-хості і тримайте VM-диски простими.
- Якщо вам потрібно ZFS-in-guest на віртуальних дисках: використовуйте raw/zvol-backed пристрої,
cache=none, свідомо увімкніть discard і протестуйте краш-сценарії перед продакшном.
А потім зробіть нудну частину: виконайте наведені команди вище, збережіть виводи і вирішіть на підставі доказів. Зберігання — одне з небагатьох місць, де реальність завжди перемагає. Просто не завжди вона перемагає швидко.