Storage là điểm yếu thầm lặng của Proxmox mà ít người để ý
Mình chạy homelab với Proxmox VE quản lý 12 VM và container — đây là playground để test mọi thứ trước khi đưa lên production. Thời gian đầu, mình dùng LVM-thin mặc định mà Proxmox installer tạo sẵn. Ổn thôi, cho đến khi một ổ NVMe xuất hiện bad sector và mình không hề hay biết — dữ liệu bị silent corruption, VM boot lên nhưng database bên trong báo lỗi lạ mà không tìm được nguyên nhân. Đó là lúc mình bắt đầu nghiêm túc xem xét ZFS.
So sánh các approach storage cho Proxmox VE
Proxmox hỗ trợ khá nhiều backend storage. Trước khi chọn, cần hiểu rõ trade-off của từng loại:
LVM / LVM-Thin (mặc định)
Proxmox installer tự tạo LVM-Thin mà không hỏi — boot lên là xài ngay. LVM-Thin có thin provisioning và snapshot, nhưng không checksum, không self-healing. Sector bị hỏng thì bạn sẽ không biết cho đến khi VM crash hoặc data đã bị corrupted từ lúc nào không hay.
- Ưu: Đơn giản, overhead thấp, được hỗ trợ tốt out-of-the-box
- Nhược: Không có data integrity checking, snapshot chậm khi volume lớn
Directory (ext4/xfs)
Lưu VM disk dưới dạng file raw hoặc qcow2 trên filesystem thông thường. Backup dễ bằng rsync, không cần setup gì thêm. Nhưng snapshot qua qcow2 chậm và dễ fragmentation theo thời gian, ảnh hưởng I/O performance.
ZFS (zvol + dataset)
Filesystem tích hợp volume manager, checksumming, snapshot, compression, và scrub ngay ở tầng storage. ZFS không cần RAID controller phần cứng — nó tự quản lý redundancy và data integrity.
- Ưu: Checksum mọi block, snapshot atomic tức thì, compression native (lz4), scrub phát hiện lỗi sớm
- Nhược: RAM usage cao (1GB RAM/1TB storage là khuyến nghị tối thiểu), không thể shrink pool sau khi tạo
Ceph (cho cluster nhiều node)
Distributed storage, sinh ra cho cluster từ 3 node trở lên. Setup Ceph trên single server thì công sức bỏ ra không xứng với lợi ích — bỏ qua option này nếu bạn không có ít nhất 3 máy.
Phân tích: ZFS mạnh ở đâu, yếu ở đâu?
ZFS không giải quyết hết mọi vấn đề storage. Nhưng khi chạy Proxmox với dữ liệu quan trọng, có 2 thứ nó làm tốt hơn bất kỳ option nào khác:
- Silent corruption detection: Mỗi block được checksum (SHA-256 hoặc blake3). Khi đọc, ZFS verify checksum — nếu không khớp, nó biết block bị lỗi và với mirror/RAIDZ sẽ tự sửa từ bản copy còn lành.
- Atomic snapshot: Snapshot ZFS tạo trong mili-giây bất kể volume 100GB hay 2TB. Không cần freeze VM lâu, không ảnh hưởng I/O đáng kể.
Với LVM-thin, mình chỉ biết có vấn đề khi VM crash hoặc database báo lỗi lạ. ZFS scrub chạy hàng tuần và báo thẳng vào log — biết được trước khi thiệt hại xảy ra, không phải sau.
Khi nào nên chọn ZFS cho Proxmox?
Chọn ZFS nếu thỏa mãn các điều kiện sau:
- Server có từ 16GB RAM trở lên (ZFS ARC cache ngốn RAM nhưng rất đáng)
- Cần snapshot nhanh phục vụ backup workflow hoặc testing
- Dữ liệu quan trọng và muốn phát hiện lỗi phần cứng trước khi quá muộn
- Muốn compression để tiết kiệm dung lượng mà không sacrifice performance
RAM dưới 8GB thì ZFS sẽ bào mòn performance thay vì cải thiện. Hay cần shrink pool thì cũng tránh — một khi tạo pool xong, không có cách thu nhỏ lại.
Hướng dẫn triển khai ZFS trên Proxmox VE
Proxmox VE 7+ có sẵn ZFS kernel module. Nếu cài Proxmox lên ext4 root (không chọn ZFS lúc install), cần thêm package sau:
Bước 1: Kiểm tra và cài ZFS module
# Kiểm tra ZFS đã có chưa
zfs version
# Nếu chưa có, cài đặt
apt update && apt install zfsutils-linux
# Load kernel module
modprobe zfs
# Xác nhận module đã load
lsmod | grep zfs
Bước 2: Xác định ổ đĩa để tạo pool
# Xem danh sách ổ đĩa
lsblk -o NAME,SIZE,TYPE,MOUNTPOINT
# Xem disk ID ổn định hơn /dev/sdX
ls -l /dev/disk/by-id/ | grep -v part
Luôn dùng disk by-id thay vì /dev/sdX — thứ tự ổ có thể thay đổi sau reboot và làm hỏng pool.
Bước 3: Tạo ZFS pool
Giả sử có 2 ổ 1TB, mình tạo mirror pool (tương đương RAID-1) để vừa có redundancy vừa có read performance tốt hơn:
# Tạo mirror pool bằng disk ID (an toàn nhất)
zpool create -f rpool_vm mirror \
/dev/disk/by-id/ata-WDC_WD10EZEX-xxxxxxxx \
/dev/disk/by-id/ata-WDC_WD10EZEX-yyyyyyyy
# Nếu có 3 ổ, dùng RAIDZ1 (tương đương RAID-5 nhưng không có write hole)
# zpool create -f rpool_vm raidz1 /dev/disk/by-id/... /dev/disk/by-id/... /dev/disk/by-id/...
# Xác nhận pool đã tạo
zpool status rpool_vm
zpool list
Bước 4: Cấu hình properties tối ưu cho VM workload
# Bật compression lz4 (nhanh, tiết kiệm ~20-40% dung lượng)
zfs set compression=lz4 rpool_vm
# Tắt atime (giảm write overhead không cần thiết)
zfs set atime=off rpool_vm
# Xác nhận properties đã áp dụng
zfs get compression,atime rpool_vm
Bước 5: Thêm ZFS pool vào Proxmox VE
Vào Proxmox web UI → Datacenter → Storage → Add → ZFS, điền:
- ID: tên storage trong Proxmox (ví dụ:
zfs-vm) - ZFS Pool:
rpool_vm - Content: Disk image, Container
- Block Size: 8K (phù hợp hầu hết VM workload)
Hoặc thêm nhanh qua CLI:
pvesm add zfspool zfs-vm --pool rpool_vm --content images,rootdir
Tận dụng snapshot ZFS cho VM
Mỗi VM disk trong Proxmox trên ZFS được lưu dưới dạng zvol. Snapshot ZFS hoạt động ở tầng block nên cực kỳ nhanh:
Tạo và rollback snapshot thủ công
# Xem danh sách zvol của các VM
zfs list | grep vm-
# Tạo snapshot VM 100 trước khi update hệ thống
zfs snapshot rpool_vm/vm-100-disk-0@before-update-2024-01
# Xem tất cả snapshot
zfs list -t snapshot
# Rollback khi có sự cố (VM phải tắt trước)
qm stop 100
zfs rollback rpool_vm/vm-100-disk-0@before-update-2024-01
qm start 100
Tự động snapshot hàng ngày
#!/bin/bash
# /usr/local/bin/zfs-auto-snapshot.sh
# Chạy hàng ngày, giữ 7 snapshot gần nhất
POOL="rpool_vm"
DATE=$(date +%Y%m%d-%H%M)
KEEP=7
# Tạo snapshot cho tất cả zvol trong pool
for zvol in $(zfs list -H -o name -t volume | grep "^${POOL}/vm-"); do
zfs snapshot "${zvol}@auto-${DATE}"
echo "Snapshot: ${zvol}@auto-${DATE}"
done
# Xóa snapshot cũ, giữ $KEEP cái gần nhất mỗi zvol
for zvol in $(zfs list -H -o name -t volume | grep "^${POOL}/vm-"); do
snapshots=$(zfs list -H -o name -t snapshot | grep "^${zvol}@auto-" | sort)
count=$(echo "$snapshots" | wc -l)
if [ "$count" -gt "$KEEP" ]; then
echo "$snapshots" | head -n $((count - KEEP)) | xargs -I{} zfs destroy {}
fi
done
# Thêm vào crontab: chạy lúc 2h sáng mỗi ngày
crontab -e
# Thêm dòng:
0 2 * * * /usr/local/bin/zfs-auto-snapshot.sh >> /var/log/zfs-snapshot.log 2>&1
Checksum và scrub — Lớp bảo vệ data integrity
ZFS tự động verify checksum mỗi khi đọc block. Nhưng với data ít được đọc (cold data), scrub định kỳ mới quét được toàn bộ pool:
# Chạy scrub kiểm tra toàn bộ pool
zpool scrub rpool_vm
# Theo dõi tiến trình
zpool status rpool_vm
# Output mẫu khi scrub hoàn thành
# scan: scrub repaired 0B in 00:04:21 with 0 errors on Sun Mar 15 03:00:02 2026
0 errors có nghĩa pool đang clean. Phát hiện lỗi thì ZFS với mirror hoặc RAIDZ tự sửa từ bản copy còn lành rồi log lại — bạn chỉ cần đọc log, không phải debug crash. Với LVM-thin, kịch bản đó kết thúc bằng VM không boot được.
# Tự động scrub mỗi Chủ nhật lúc 3h sáng
# Thêm vào crontab:
0 3 * * 0 zpool scrub rpool_vm
# Kiểm tra compression ratio thực tế
zfs get compressratio rpool_vm
# Monitor I/O real-time
zpool iostat rpool_vm 2
Kết quả thực tế sau khi chuyển sang ZFS
Sau khi migrate homelab từ LVM-thin sang ZFS mirror với lz4 compression, compression ratio đạt khoảng 1.4x–1.8x tùy VM — VM chạy nhiều text/log được hưởng lợi nhiều nhất. Snapshot tạo tức thì thay vì mất vài phút. Điều mình đánh giá cao nhất: scrub hàng tuần report 0 errors, storage tự giám sát data integrity — không còn phải tin vào may mắn như hồi dùng LVM-thin nữa.
Server đủ RAM, dữ liệu quan trọng — đây là upgrade mình không thể không làm. Không tốn thêm tiền phần cứng, chỉ cần bỏ thời gian setup đúng cách một lần.

