Tự động hóa ZFS Snapshot và Backup với Sanoid và Syncoid trong HomeLab

HomeLab tutorial - IT technology blog
HomeLab tutorial - IT technology blog

Vấn đề thực tế: Bài học nhớ đời lúc 2:14 sáng

Chuông cảnh báo reo vang lúc 2:14 sáng. Một script cập nhật tự động gặp lỗi nghiêm trọng trên hypervisor chính, làm xáo trộn toàn bộ phân quyền dataset và làm hỏng cơ sở dữ liệu SQLite 4 GB của Vaultwarden cùng Home Assistant. Đứng trước màn hình terminal, tôi có hai lựa chọn: mất bốn tiếng đồng hồ chắp vá từng file từ bản dump rsync của ngày hôm trước, hoặc rollback về một snapshot block-level hoàn chỉnh được tạo cách đó 14 phút.

Tôi đã chọn snapshot. Chỉ ba mươi giây sau, toàn bộ dịch vụ đã hoạt động bình thường trở lại.

Rất nhiều người dùng HomeLab hiện nay vẫn phụ thuộc vào các shell script thiếu ổn định để chạy lệnh zfs snapshot qua cron. Những giải pháp tự chế này rất dễ phát sinh lỗi: chúng làm sót hàng nghìn snapshot rác gây tiêu tốn metadata của pool, âm thầm gặp lỗi khi bạn đổi tên dataset, và tệ nhất là hiếm khi thiết lập được các tầng lưu trữ chi tiết theo thời gian (hàng giờ, hàng ngày, hàng tuần, hàng tháng).

Việc replicate các snapshot đó bằng rsync cũng không khá hơn. Rsync phải quét toàn bộ cây thư mục và đọc từng byte file thông qua tầng VFS. Điều này làm nghẽn I/O ổ đĩa, quá tải khi xử lý các file disk image ảo 500 GB và dễ thất bại khi gặp các lockfile cơ sở dữ liệu đang mở. Thay vào đó, giải pháp bạn thực sự cần là đồng bộ delta dạng atomic ở cấp độ block.

Khái niệm cốt lõi: Tại sao nên dùng Sanoid và Syncoid?

ZFS hỗ trợ sẵn tính năng snapshot Copy-on-Write (CoW) và stream dữ liệu tuần tự thông qua lệnh zfs send và zfs receive. Tuy nhiên, nó thiếu một công cụ điều phối để lên lịch snapshot, tự động dọn dẹp dữ liệu cũ và quản lý truyền tải qua mạng. Đó chính là lý do bộ công cụ Sanoid của Jim Salter ra đời.

Sanoid: Quản lý vòng đời snapshot theo chính sách

Sanoid tự động hóa việc tạo và duy trì snapshot mà không cần đến các bash script phức tạp. Bạn chỉ cần định nghĩa các chính sách lưu trữ trong một file cấu hình duy nhất (/etc/sanoid/sanoid.conf). Một systemd timer sẽ kích hoạt Sanoid mỗi phút hoặc mỗi giờ. Công cụ sẽ tạo các snapshot kèm mốc thời gian (như autosnap_2026-10-06_02:00:00_hourly) và tự động xóa các bản ghi đã hết hạn theo khung lưu trữ đã định (ví dụ: giữ lại 24 bản hàng giờ, 7 bản hàng ngày, 4 bản hàng tuần và 3 bản hàng tháng).

Syncoid: Replication dữ liệu linh hoạt qua mạng

Syncoid chịu trách nhiệm truyền tải dữ liệu qua mạng bằng cách bọc zfs send và zfs receive trong cơ chế nhận diện thông minh qua SSH.

Khi trỏ tới một máy chủ từ xa, Syncoid sẽ tìm snapshot chung gần nhất giữa dataset nguồn và đích. Sau đó, nó tính toán phần chênh lệch (delta), nén dữ liệu (dùng LZ4 hoặc zstd), đệm luồng truyền bằng mbuffer để ổn định băng thông và áp dụng vào pool đích. Ngay cả qua kết nối Wi-Fi hay đường truyền WAN 1 Gbps chập chờn, Syncoid vẫn có thể chuyển 50 GB block dữ liệu database đã thay đổi mà không làm gián đoạn bất kỳ dịch vụ nào.

Thực hành: Xây dựng pipeline tự động hóa

1. Cài đặt các gói phụ thuộc

Chạy các lệnh sau trên cả node chính (nguồn) và máy chủ lưu trữ backup (đích). Áp dụng cho các hệ điều hành Debian, Ubuntu hoặc Proxmox VE:

sudo apt update
sudo apt install -y sanoid lzop mbuffer pv openssh-client openssh-server

2. Cấu hình chính sách snapshot với Sanoid

Trên máy chủ chính, tạo thư mục và file cấu hình tại /etc/sanoid/sanoid.conf:

sudo mkdir -p /etc/sanoid
sudo nano /etc/sanoid/sanoid.conf

Định nghĩa các template lưu trữ snapshot và gán chúng vào các dataset của bạn:

# Template cho dữ liệu production quan trọng
[template_production]
    frequently = 0
    hourly = 24
    daily = 7
    weekly = 4
    monthly = 3
    yearly = 0
    autosnap = yes
    autoprune = yes

# Template cho vùng lưu trữ tạm thời ngắn hạn
[template_ephemeral]
    frequently = 0
    hourly = 6
    daily = 1
    weekly = 0
    monthly = 0
    yearly = 0
    autosnap = yes
    autoprune = yes

# Gán template cho các dataset
[tank/appdata]
    use_template = template_production
    recursive = yes

[tank/vms]
    use_template = template_production
    recursive = yes

[tank/scratch]
    use_template = template_ephemeral
    recursive = no

3. Kiểm tra và tự động hóa Sanoid qua Systemd

Hãy luôn kiểm tra cấu hình bằng chế độ chạy thử (dry run) trước khi bật tính năng tự động dọn dẹp:

# Kiểm tra cú pháp cấu hình và xem trước các tác vụ dự kiến
sudo sanoid --cron --debug --dry-run

# Kích hoạt và khởi chạy systemd timer tích hợp sẵn
sudo systemctl enable --now sanoid.timer

# Xác nhận timer đang hoạt động và đã được lên lịch
sudo systemctl list-timers | grep sanoid

4. Cấu hình xác thực SSH chuyên dụng cho Syncoid

Syncoid cần quyền truy cập SSH để truyền tải snapshot. Hãy tạo một cặp khóa Ed25519 riêng trên node chính mà không đặt mật khẩu passphrase:

# Tạo cặp SSH key trên node chính
sudo ssh-keygen -t ed25519 -f /root/.ssh/id_syncoid -N "" -C "syncoid-backup"

# Sao chép public key sang máy chủ backup đích (ví dụ: 192.168.10.50)
sudo ssh-copy-id -i /root/.ssh/id_syncoid.pub [email protected]

# Kiểm tra xác thực bằng SSH key
sudo ssh -i /root/.ssh/id_syncoid [email protected] "zfs list"

5. Thực hiện đồng bộ lần đầu

Chạy bản replication gốc thủ công. Syncoid sẽ tự động tạo dataset đích và stream toàn bộ dữ liệu ban đầu:

sudo syncoid --sshkey=/root/.ssh/id_syncoid \
    --no-sync-snap \
    --compress=lz4 \
    --recursive \
    tank/appdata [email protected]:backup-pool/appdata

Cờ --no-sync-snap hướng dẫn Syncoid tái sử dụng các snapshot tự động có sẵn của Sanoid thay vì tạo thêm snapshot đồng bộ tạm thời.

6. Tự động hóa quá trình Replication với Syncoid

Lên lịch replication chạy ngay sau khi Sanoid hoàn tất đợt snapshot hàng giờ. Tạo file /etc/cron.d/syncoid-replication trên máy chủ chính:

sudo nano /etc/cron.d/syncoid-replication

Thêm định nghĩa cron (lùi thời gian sang phút thứ 15 của mỗi giờ):

# Đồng bộ tank/appdata sang node backup vào phút thứ 15 mỗi giờ
15 * * * * root /usr/sbin/syncoid --sshkey=/root/.ssh/id_syncoid --quiet --no-sync-snap --compress=lz4 --recursive tank/appdata [email protected]:backup-pool/appdata >> /var/log/syncoid.log 2>&1

7. Diễn tập khôi phục: Phục hồi dữ liệu

Một bản backup chỉ thực sự có giá trị khi bạn đã kiểm tra khả năng khôi phục. Dưới đây là hai cách xử lý khi sự cố xảy ra:

# Tùy chọn A: Rollback cục bộ tức thì (mất < 2 giây)
sudo zfs rollback tank/appdata@autosnap_2026-10-06_02:00:00_hourly

# Tùy chọn B: Kéo dữ liệu về từ máy chủ backup nếu pool cục bộ bị mất
sudo syncoid --sshkey=/root/.ssh/id_syncoid \
    [email protected]:backup-pool/appdata tank/appdata_recovered

Kết luận: Biến sự cố lưu trữ thành tác vụ xử lý nhẹ nhàng

Sự cố lưu trữ và các script cập nhật lỗi là điều không thể tránh khỏi. Bằng cách kết hợp chính sách lưu trữ theo lịch của Sanoid với khả năng đồng bộ delta nhanh chóng của Syncoid, bạn sẽ loại bỏ hoàn toàn yếu tố sai sót từ con người. Dữ liệu của bạn luôn được bảo vệ an toàn tại chỗ nhờ các bản rollback linh hoạt và được sao lưu từ xa qua các luồng block tối ưu băng thông—mang lại sự tin cậy chuẩn doanh nghiệp cho hệ thống HomeLab của bạn.

Share: