System stoi na mirrorze rpool utworzonym przez instalator. Maszyny wirtualne dostaną osobną pulę tank — dzięki temu reinstalacja Proxmoxa nie dotyka danych, a pulę można w razie potrzeby przenieść na inny serwer jednym poleceniem zpool import.
Większość parametrów ZFS ustawia się raz, przy tworzeniu puli lub datasetu. Część z nich (ashift, układ vdevów) nie da się zmienić później bez przeniesienia danych. Dlatego najpierw projekt, potem komendy.
ZFS czy LVM w Proxmoxie?
Instalator Proxmoxa domyślnie proponuje ext4 na LVM, a maszyny wirtualne trafiają wtedy na LVM-thin. To lżejsze rozwiązanie — mniej RAM-u i brak narzutu na sumy kontrolne. ZFS daje w zamian:
- sumy kontrolne wykrywające ciche uszkodzenia danych i samonaprawianie na mirrorze,
- natychmiastowe snapshoty i wbudowaną w Proxmoxa replikację maszyn między węzłami klastra (działa tylko na ZFS),
- kompresję w locie, która zwykle przyspiesza dyski zamiast je spowalniać.
Na serwerze z pamięcią ECC i kilkoma dyskami wybór jest prosty: ZFS. LVM ma sens na maszynie z małą ilością RAM-u albo z jednym dyskiem, gdzie i tak nie ma z czego odtwarzać uszkodzonych danych.
ZFS mirror czy RAIDZ?
Pula ZFS składa się z vdevów (grup dysków), a wydajność losowych operacji rośnie z liczbą vdevów, nie dysków. Dla czterech dysków SSD:
| Układ | Pojemność użyteczna | Losowe IOPS | Odporność | Rozbudowa |
|---|---|---|---|---|
| 2× mirror (RAID10) | 50% | ~2 vdevy | 1 dysk w każdej parze | Dodajesz kolejną parę |
| RAIDZ1 | ~75% | ~1 vdev | 1 dysk | Rozszerzanie RAIDZ (OpenZFS 2.3+), wolne |
| RAIDZ2 | ~50% | ~1 vdev | 2 dowolne dyski | Jak wyżej |
Pod maszyny wirtualne wybierz mirrory. Dysk VM to wolumen (zvol) z małym blokiem, a na RAIDZ małe bloki marnują miejsce na parzystość i wyrównanie (padding). W praktyce RAIDZ1 z blokiem 16K daje niewiele więcej miejsca niż mirror, a wyraźnie mniej IOPS.
RAIDZ2 ma sens dla dużych plików: mediów, backupów, archiwum. Wtedy warto zrobić osobną pulę na dyskach HDD, ale R620 z zatokami 2,5” do tego nie służy.
Tworzenie puli
Zawsze adresuj dyski przez /dev/disk/by-id/. Nazwy sda, sdb mogą zamienić się miejscami po restarcie:
ls -l /dev/disk/by-id/ | grep -v -- -part | grep -E 'ata-|scsi-|nvme-'Utwórz pulę z dwóch mirrorów. Poniższe identyfikatory zamień na te z wyniku polecenia powyżej:
zpool create \ -o ashift=12 \ -o autotrim=on \ -O compression=lz4 \ -O atime=off \ -O xattr=sa \ -O acltype=posixacl \ -O dnodesize=auto \ tank \ mirror /dev/disk/by-id/ata-SAMSUNG_MZ7L3960HCJR-00A07_S6KMNA0T100001 /dev/disk/by-id/ata-SAMSUNG_MZ7L3960HCJR-00A07_S6KMNA0T100002 \ mirror /dev/disk/by-id/ata-SAMSUNG_MZ7L3960HCJR-00A07_S6KMNA0T100003 /dev/disk/by-id/ata-SAMSUNG_MZ7L3960HCJR-00A07_S6KMNA0T100004
zpool status tankCo oznaczają te opcje:
ashift=12— bloki 4 KiB. Dyski często deklarują sektory 512 B, choć fizycznie zapisują 4 KiB. Za małeashiftzmusza dysk do cyklu odczyt–modyfikacja–zapis przy każdym małym zapisie, a tej wartości nie da się zmienić po utworzeniu vdeva.autotrim=on— ZFS na bieżąco informuje SSD o zwolnionych blokach.compression=lz4— kompresja jest praktycznie darmowa dla CPU, a zwykle przyspiesza I/O, bo na dysk trafia mniej danych. Włącz ją zawsze.atime=off— brak zapisu przy każdym odczycie pliku.xattr=sa,acltype=posixacl,dnodesize=auto— wydajne rozszerzone atrybuty. Mają znaczenie dla kontenerów LXC i udziałów Samba.
Datasety i storage w Proxmoxie
Zamiast wrzucać wszystko do korzenia puli, podziel ją na datasety — każdy może mieć własne parametry, limity i harmonogram snapshotów:
# Dyski maszyn wirtualnych i kontenerów LXCzfs create tank/vm
# Kopie zapasowe vzdump — duże, sekwencyjne plikizfs create -o recordsize=1M -o compression=zstd tank/backup
# Obrazy ISO i szablonyzfs create -o recordsize=1M tank/isoDodaj je jako magazyny Proxmoxa:
# Dyski VM (zvol) i rootfs kontenerów — thin provisioning, blok 16Kpvesm add zfspool tank-vm --pool tank/vm --content images,rootdir --sparse 1 --blocksize 16k
# Backupy i ISO jako zwykłe katalogipvesm add dir tank-backup --path /tank/backup --content backup --is_mountpoint yespvesm add dir tank-iso --path /tank/iso --content iso,vztmpl --is_mountpoint yes
pvesm status--blocksize 16k to volblocksize nowo tworzonych dysków VM. 16K to domyślna wartość w nowszych Proxmoxach i rozsądny kompromis dla systemów plików gości. Dla maszyny z bazą danych o stronie 8K (PostgreSQL) możesz utworzyć osobny storage z 8k. Wartość obowiązuje tylko dla nowych dysków.
--is_mountpoint yes chroni przed zapisem do pustego katalogu, gdy pula się nie zaimportuje. Proxmox po prostu oznaczy storage jako niedostępny.
Limit ARC (zfs_arc_max): ile RAM-u dla ZFS
ARC to cache ZFS w pamięci RAM. Im większy, tym więcej odczytów obsłużonych bez dotykania dysków — ale każdy gigabajt ARC to gigabajt mniej dla maszyn wirtualnych. ARC oddaje pamięć pod presją, jednak robi to z opóźnieniem, a maszyny z dużym przydziałem RAM-u mogą w tym czasie nie wystartować.
Praktyczna reguła dla puli SSD: 2 GiB + 1 GiB na każdy TiB danych, z górną granicą na tyle, żeby wszystkie maszyny zmieściły się w pamięci jednocześnie. Dla serwera ze 128 GiB i pulą 2 TiB to np. 8 GiB:
# Wartość w bajtach: 8 × 1024³echo "options zfs zfs_arc_max=$((8 * 1024**3))" > /etc/modprobe.d/zfs.conf
# Root na ZFS — limit musi trafić do initramfsupdate-initramfs -u -k all
# Zastosuj od razu, bez restartuecho $((8 * 1024**3)) > /sys/module/zfs/parameters/zfs_arc_maxSkuteczność cache sprawdzisz poleceniem:
arc_summary -s arc | head -30arcstat 5Kolumna hit% w arcstat stale powyżej 90% oznacza, że ARC jest wystarczający. Jeśli spada poniżej 80% przy normalnej pracy, a masz wolną pamięć — zwiększ limit.
SLOG, L2ARC i special vdev — zwykle nie
To najczęściej polecane „przyspieszacze” ZFS, które w domowym labie rzadko pomagają:
- SLOG przyspiesza tylko zapisy synchroniczne i tylko wtedy, gdy dysk SLOG jest szybszy od dysków puli i ma ochronę zasilania. Przy puli z SSD z PLP zysk jest znikomy.
- L2ARC to cache odczytu na SSD, ale każdy blok w L2ARC zajmuje miejsce w RAM-ie na nagłówek. Najpierw zwiększ ARC.
- Special vdev przechowuje metadane i jest krytyczny — jego utrata oznacza utratę całej puli. Ma sens przy dużych pulach HDD, nie SSD.
Snapshoty automatyczne z Sanoid
Snapshot ZFS powstaje w ułamku sekundy i zajmuje miejsce tylko na zmienione później bloki. Sanoid tworzy je według harmonogramu i sam usuwa stare:
apt install -y sanoid[tank/vm] use_template = vm recursive = yes process_children_only = yes
[tank/backup] use_template = backup
[template_vm] frequently = 0 hourly = 24 daily = 14 weekly = 4 monthly = 3 autosnap = yes autoprune = yes
[template_backup] hourly = 0 daily = 7 monthly = 1 autosnap = yes autoprune = yesPakiet w Debianie instaluje timer systemd, który uruchamia Sanoida co 15 minut. Sprawdź, czy działa:
systemctl status sanoid.timersanoid --cron --verbosezfs list -t snapshot -o name,used,creation -s creation | tailPrzywrócenie dysku maszyny wirtualnej do stanu sprzed godziny (maszyna musi być wyłączona):
# Snapshoty dysku VM 110zfs list -t snapshot tank/vm/vm-110-disk-0
# Cofnięcie — -r usuwa nowsze snapshoty, zastanów się dwa razyzfs rollback -r tank/vm/vm-110-disk-0@autosnap_2026-09-08_10:00:01_hourlyScrub i alerty o awariach
Scrub czyta wszystkie dane i porównuje sumy kontrolne, więc wykrywa ciche uszkodzenia, zanim zabraknie drugiej kopii do naprawy. Pakiet zfsutils-linux w Debianie uruchamia go automatycznie w drugą niedzielę miesiąca (/etc/cron.d/zfsutils-linux). Ręcznie:
zpool scrub tankzpool status tankO zdarzeniach (degradacja puli, błędy odczytu, wynik scrubu) informuje ZED — demon zdarzeń ZFS. W Proxmoxie wystarczy, żeby trafiały do roota:
ZED_EMAIL_ADDR="root"ZED_NOTIFY_VERBOSE=1systemctl restart zfs-zedPoczta do roota przechodzi przez system powiadomień Proxmoxa. Adres e-mail ustawisz w Datacenter → Permissions → Users → root@pam, a cel powiadomień (SMTP, Gotify, webhook) w Datacenter → Notifications. ZED_NOTIFY_VERBOSE=1 wysyła raport także po udanym scrubie — dzięki temu wiesz, że alerty w ogóle działają.
Szybka diagnostyka
zpool status -x # „all pools are healthy” albo lista problemówzpool list -v # zajętość i fragmentacja per vdevzpool iostat -v tank 5 # obciążenie dysków na żywozfs get compressratio tank # ile oszczędza kompresjazfs list -o space -r tank # gdzie znika miejsce (snapshoty!)smartctl -a /dev/disk/by-id/ata-SAMSUNG_MZ7L3960HCJR-00A07_S6KMNA0T100001 | grep -iE 'wear|reallocated|hours'Pula ZFS nie powinna przekraczać ~80% zajętości — powyżej tego progu rośnie fragmentacja i wyraźnie spada wydajność zapisu. Ustaw sobie alert albo rezerwację:
# Rezerwacja 15% pojemności puli „dla nikogo” — zapisy zatrzymają się, zanim będzie za późnozfs create -o refreservation=$(( $(zpool get -Hp -o value size tank) * 15 / 100 )) tank/rezerwaPula jest gotowa. W następnej części postawisz na niej maszynę wirtualną z Dockerem — od szablonu cloud-init do działającego stosu Compose.