F/OSS được lưu trữ bền vững, được quản lý Lưu trữ đối tượng, Redis, Prometheus trên Hetzner, OVH và LeaseWeb **tl;dr - Giải thích từng dòng về tập lệnh cài đặt ZFS được hỗ trợ ansible của tôi để sử dụng trên phần cứng chuyên dụng của Hetznerà ¢â (Ubuntu 20.04 - ââÂFocalââÂ) â  nó không hoàn hảo/tối thiểu, nhưng nó phù hợp với tôi Một thời gian trước, tôi đã bắt đầu sử dụng ZFS trên tất cả phần cứng chuyên dụng bằng kim loại trần của mình được lưu trữ tại Hetzner để sắp xếp các ổ cứng và SSD đính kèm. Có rất nhiều sự lựa chọn trong không gian (LVM tiêu chuẩn, mdraid btrfs, v.v.), nhưng tôi đã chọn ZFS vì tính năng và công thái học của nó. Tôi sẽ không làm phiền bất kỳ ai với lý do tại sao, nhưng một trong những điều tôi cần điều hướng là cách cài đặt các phiên bản ZFS mới hơn trên Ubuntu 20.04 (một trong những hệ điều hành được hỗ trợ tại Hetzner). Tôi đã gặp phải một số sự cố (đặc biệt là sau khi cài đặt) trong khi thiết lập ZFS trên hệ thống của mình nên tôi muốn hướng dẫn cách thực hiện. Bài đăng này là một lời giải thích theo từng khổ thơ về các tập lệnh Ansible cài đặt ZFS của tôi. Trước khi bạn biết liệu ZFS (hoặc bất kỳ hệ thống tệp nào) có đáng để chuyển sang hay không, có lẽ bạn sẽ muốn RTFM. ZFS có rất nhiều thông tin chi tiết và tôi chắc chắn không phải là chuyên gia về nó, nhưng biết cách thức và lý do, cũng như thuật ngữ và thậm chí cả lịch sử của dự án là rất quan trọng. Một vài liên kết để giúp bạn bắt đầu: Cùng với ZFS (có thể là con số chưa biết nhiều nhất ở đây), bạn có thể muốn làm quen với Ubuntu và quản trị hệ thống nói chung. Đó là một khu vực rộng lớn để đề cập nhưng đây là một vài liên kết: Gần như không cần phải nói nhưng nếu bạn không quen lắm với quản trị hệ thống linux vào thời điểm này, có lẽ bạn không nên thử điều này. Cá nhân tôi chọn để các đĩa của mình có cấu hình hơi tùy chỉnh à ¢  Tôi đã thiết lập RAID1 (phản chiếu) qua mdraid, cùng với các phân vùng trên mỗi đĩa mà tôi có thể cung cấp cho ZFS để quản lý. Lý tưởng nhất là tôi có toàn bộ đĩa để cung cấp cho ZFS nhưng các phân vùng cũng hoạt động. thiết lập hệ điều hành ( installimage) bao gồm thiết lập đĩa được chạy từ chế độ cứu hộ của Hetzner và có thể được hướng dẫn bằng một tệp như sau: # Khai báo ổ đĩa được installimage DRIVE0 sử dụng /dev/nvme0n1 DRIVE1 /dev/nvme1n1 # Kích hoạt RAID phần mềm (đối với đĩa hệ điều hành) SWRAID 1 SWRAIDLEVEL 1 # Bộ nạp khởi động (thường là grub) BOOTLOADER grub # Máy chủ lưu trữ HOSTNAME machine01 # Phân vùng cấu hình PART swap swap 32G PART /boot ext4 1G PART / ext4 128G # Sự phân chia cuối cùng này sẽ được thực hiện (xóa& được tạo lại dưới dạng ZFS sau) PHẦN /root-disk-remaining ext4 all # Bạn có thể chỉ định hình ảnh mà Hetzner sử dụng bằng cách truy cập HÌNH ẢNH chia sẻ mạng của họ /root/.oldroot/nfs/images/Ubuntu-2004-focal-64-minimal.tar. gz Điều này rõ ràng là khá dành riêng cho Hetzner, nhưng hãy làm bất cứ điều gì bạn cần làm trên hệ thống của riêng mình để có sẵn các phân vùng/ổ đĩa cho ZFS sử dụng. zfsutils-linuxand zfs-zed Trong Ansible YAML, bước này trông như thế này: - tên: Giữ tất cả các gói ngược dòng liên quan đến zfs ansible.buildin.shell: | apt-mark giữ zfsutils-linux apt-mark giữ zfs-zed Khi viết bài này, phiên bản của zfs-linux trong Ubuntu Focal là 0.8.3. Vì mục tiêu của chúng tôi ở đây là cài đặt và tiếp tục sử dụng phiên bản mới hơn nên chúng tôi muốn đảm bảo rằng mọi bản cập nhật apt không thay thế phiên bản đã cài đặt của chúng tôi bằng phiên bản cũ hơn. Trong khi chúng tôi ở đây, chúng ta cũng hãy thanh lọc các gói. - tên: Lọc các gói ngược dòng ZFS (ubuntu) nếu được cài đặt ign_errors: yes ansible.buildin.command: | apt purge --allow-change-holding-packages zfsutils-linux zfs-zed Bạn có thể đọc tài liệu trên thích hợp để xem những gì purge thực hiện à ¢ â  ità ¢ â  tương tự như xóa nhưng cũng xóa các tệp cấu hình nếu có. Bạn có thể cài đặt các phụ thuộc cho OpenZFS như sau: - tên: Yêu cầu cài đặt để xây dựng ZFS ansible.buildin.apt: tên: góiupdate_cache: có trạng thái: vars hiện tại: gói: - build-essential - autoconf - automake - libtool - gawk - Alien - fakeroot - dkms - libblkid-dev - uuid -dev - libudev-dev - libssl-dev - zlib1g-dev - libaio-dev - libattr1-dev - libelf-dev # Dòng bên dưới gọi đầu ra của `uname -r`, ví dụ "5.16.5-arch1- 1"cho hệ thống vòm của tôi # để dòng này sẽ phân giải thành thứ gì đó như "linux-headers-5.16.5-arch1-1"(tất nhiên là không hợp lệ trên Ubuntu, nhưng là một ví dụ) - linux-headers uname_r.stdout }} - python3 - python3-dev - python3-setuptools - python3-cffi - libffi-dev - python3-packaging - git - libcurl4-openssl-dev Có thể có một số phụ thuộc không thực sự cần thiết nhưng gần như tất cả chúng đều cần thiết. /opt/zfs Đây là ZFS: - tên: Tạo /opt/zfs ansible.buildin.file: đường dẫn: trạng thái /opt/zfs: thư mục Nếu bạn muốn tải xuống ZFS: - tên: Tải xuống zfs ansible.buildin.get_url: url: "httpsgithub.com/openzfs/zfs/releases/download/zfs _zfs_version zfs _zfs_version tar.gz"checksum:_zfs_tarball_sha256_checksummode: 0755 dest: "/opt/zfs/zfs _zfs_version tar .gz"Đây là sự thay thế {{ _zfs_version }} ( 2.1.1. Bạn cũng sẽ muốn tự tải xuống và thu thập/tạo tổng kiểm tra để sử dụng. Không bao giờ tải xuống những thứ từ internet không được phép thay đổi nếu không có kiểm tra! {{là cú pháp tạo khuôn mẫu Ansible) là Và nếu bạn muốn sao chép nó từ máy tính nơi Ansible đang chạy (đây là việc tôi làm): - tên: Sao chép gói zfs (tránh giới hạn tốc độ) ansible.buildin.copy: src: files/zfs/zfs _zfs_version tar.gz"mode: 0755 dest: "/opt/zfs/zfs _zfs_version tar.gz"Bất kể bạn chọn cách lấy nguồn như thế nào, tất nhiên, bạn sẽ cần giải nén nó: - tên: Giải nén mã zfs ansible.builtin.unarchive: src: "/opt/zfs/zfs _zfs_version tar.gz"dest: "/opt/zfs"remote_src: yes Để bắt đầu quá trình xây dựng: - tên: Thiết lập và Xây dựng ZFS ansible.buildin.shell: | ./autogen../configure make clean make -j args: chdir: "/opt/zfs/zfs _zfs_version Nếu bạn đã quen với việc xây dựng mọi thứ từ nguồn, các dự án khác nhau sẽ sử dụng bộ công cụ chung này (một số biến thể của tạo, tự động tạo và định cấu hình tập lệnh). Như bạn có thể mong đợi, việc này có thể mất một lúc, vì vậy hãy dành chút thời gian. Sau khi xây dựng ZFS - tên: Cài đặt ZFS ansible.buildin.shell: | thực hiện cài đặt đối số: chdir: "/opt/zfs/zfs _zfs_version Thông thường, bạn sẽ nghĩ rằng chúng tôi sẽ hoàn thành * ngay tại đây *, nhưng bài đăng này tồn tại vì làm điều này nói chung là không đủ! Letà ¢ â  nhấn trở đi. Trước tiên, buộc dỡ (các) mô-đun ZFS nếu chúng đang chạy: - tên: Buộc dỡ (các) mô-đun ZFS ansible.buildin.shell: | ./scripts/zfs.-u lập luận: chdir: "/opt/zfs/zfs _zfs_version Sẽ là lý tưởng nếu bạn *không* chạy bất kỳ khối lượng công việc nào khi điều này đang xảy ra, như bạn có thể mong đợi. Trong khi các mô-đun không được tải, chúng tôi có thể cài đặt một số trình trợ giúp: - tên: Trình trợ giúp ZFS sau cài đặt ansible.buildin.shell: | ./scripts/zfs-helpers.-i lập luận: chdir: "/opt/zfs/zfs _zfs_version Sau khi các trình trợ giúp được cài đặt, hãy buộc tải lại mô-đun ZFS: - tên: Buộc tải lại mô-đun ZFS ansible.buildin.shell: | ./scripts/zfs.args: chdir: "/opt/zfs/zfs _zfs_version Tôi đã tìm thấy việc xây dựng và sử dụng deb (định dạng được Debian sử dụng để cài đặt gói) cũng giúp cài đặt ổn định và không bị thay thế bởi mặc định của gói Ubuntu. Đầu tiên xây dựng gói gỡ lỗi ZFS từ mã nguồn: - tên: Xây dựng gói gỡ lỗi ZFS ansible.builtin.shell: | lập luận tranh luận: chdir: "/opt/zfs/zfs _zfs_version Và sau đó cài đặt nó - tên: Cài đặt các gói gỡ lỗi ZFS ansible.buildin.shell: | có | dpkg -i --force-overwrite deb apt install -f -y deb args: chdir: "/opt/zfs/zfs _zfs_version Về mặt lý thuyết, bước này *không nên* là cần thiết (hoặc chỉ nên sử dụng một mình), vì chúng tôi đã chạy một quy trình cài đặt, nhưng tôi nhận thấy rằng khi thực hiện bước này hay bước khác, tôi Âd có các tình huống khởi động lại sẽ nhắc sử dụng phiên bản ZFS cũ hơn (mặc dù apt purge) à ¢ â  đặc biệt ở cấp kernel. modprobe Nếu bạn muốn kích hoạt mô-đun ZFS đã được cài đặt ngay lập tức, hãy sử dụng modprobe: - tên: Khối mô-đun modprobe zfs: - tên: Cài đặt mô-đun hạt nhân zfs Community.General.modprobe: tên: trạng thái zfs: hiện tại Cài đặt ZFS có nghĩa là cài đặt một mô-đun hạt nhân, nhưng vì chúng tôi chưa đưa nó vào thông qua Hỗ trợ mô-đun hạt nhân động, nên chúng tôi cần kích hoạt các mô-đun hạt nhân được cài đặt cục bộ để sử dụng: - tên: Đảm bảo phần bổ sung ở phía trước ansible.buildin.lineinfile: đường dẫn: /etc/modules-load.d/modules.conf regexp: '^search'line: "tìm kiếm các bản cập nhật bổ sung được tích hợp sẵn trên Ubuntu"trạng thái: hiện tại Điều này đảm bảo rằng tệp quản lý đường dẫn tìm kiếm mô-đun hạt nhân /etc/modules-load.d/modules.conf có một dòng trong đó có tìm kiếm các bản cập nhật bổ sung được chỉ định. Thông thường có ít nhất một dòng bắt đầu bằng tìm kiếm và những gì chúng tôi muốn làm là đảm bảo các vị trí mô-đun bổ sung được tìm kiếm sớm trong quy trình. Chúng tôi sẽ muốn cài đặt qua hệ thống con DKMS: - tên: dkms cài đặt zfs ansible.buildin.shell: | dkms cài đặt zfs _zfs_version }} lập luận: chdir: "/opt/zfs/zfs _zfs_version Tại thời điểm này, bạn sẽ có thể kiểm tra phiên bản ZFS đang hoạt động hiện tại và nó sẽ hiển thị cho bạn thông tin như sau: root@machine01 ~ # phiên bản zfs zfs-2.1.1-1 zfs-kmod-2.1.1-1 Có một số đơn vị SystemD (như thường lệ Digital Ocean có một số tài liệu tuyệt vời) được tạo nhưng cần phải được kích hoạt để ZFS sử dụng: - tên: Đảm bảo các đơn vị systemd liên quan đến zfs được kích hoạt khối: - ansible.buildin.systemd: tên: itemstate: đã bắt đầu kích hoạt: có vòng lặp: - zfs-import-cache.service - zfs-import.target - zfs-mount.service - zfs-share.service - zfs-zed.service - zfs-volume-wait.service - zfs.target Các biến được lặp lại giống như đang chạy systemd start and systemd enable . The security-minded reader at home is no doubt cringing into the atmosphere by now, but making sure my kernel upgrades are manual is the only way I’ve found to ensure that the installed version of ZFS was not disabled/unexpectedly altered/broken by kernel upgrades: - name: Hold all kernel upgrades to prevent custom built ZFS from doing fallback ansible.builtin.shell: | apt-mark hold linux-headers-generic apt-mark hold linux-image-generic apt-mark hold {{ uname_r.stdout }} # you'll need that `uname -r` output again here I personally prefer to hold back any kernel upgrades and instead perform them at machine setup rather than during operation. DKMS *should* ensure that with the building of any new kernel the ZFS code is rebuilt but it’s been flaky in the past so I find it hard to trust. Along with all the kernel changes we’ve made so far (good and questionable), one thing we’ll want to do is add the configuration necessary to ensure the kernel module is loaded: - name: Ensure zfs kernel module comes up with next restart tags: [ "zfs:post-install:config" ] block: - name: Add zfs module load file ansible.builtin.template: src: templates/kernel-modules/zfs.conf.j2 dest: /etc/modules-load.d/zfs.conf owner: root group: root mode: 0644 Now that we have ZFS installed (restart once to check I’m going to leave the rest of the cluster setup to you. There are a *lot* of ways to use ZFS and setup zpools (RAID0/1/5/Z Actually using ZFS properly is out of scope (I can only hope I’ve covered *installing* it properly, at least), but please refer to the usual manuals there to set up your ZFS pool and storage requirements. Trying to cover even the basics of how to setup ZFS for your drives once it’s been installed is certainly a lot of reading so we’ll leave it there for today. This is the part where you “draw the rest of the owl” (sorry). txg_timeout While experimenting with some write modes for Postgres on ZFS, I looked into an optimization modes that involved reducing the txg_timeout from it’s default of 5 seconds to 1 second. While I won’t get into the tradeoffs implied by that move (please read my post on Postgres + ZFS), here is the setup that I’ve used for modifying txg_timeout per-machine (some machines might use the optimization some might not): - name: Add systemd unit to support txg timeout customization tags: [ "zfs:post-install:config" ] block: - name: Set current ZFS txg_timeout (to 1) ansible.builtin.shell: | echo 1 > /sys/module/zfs/parameters/zfs_txg_timeout - name: install zfs-config-txg-timeout service ansible.builtin.template: src: templates/zfs-config-txg-timeout.service.j2 dest: /etc/systemd/system/zfs-config-txg-timeout.service owner: root group: root mode: 0644 - name: start & enable zfs-config-txg-timeout service ansible.builtin.systemd: name: zfs-config-txg-timeout.service state: started enabled: yes daemon_reload: yes The template that goes with that looks like this: [Unit] Description=Set ZFS txg_timeout After=zfs.target ConditionPathIsDirectory=/sys/module/zfs [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/bin/bash -c 'echo {{ _zfs_txg_timeout_seconds | default(zfs_txg_timeout_seconds) }} > /sys/module/zfs/parameters/zfs_txg_timeout' # Not needed since we want it to always be whatever the setting is # ExecStop=/usr/bin/bash -c 'echo {{ _zfs_txg_timeout_seconds | default(zfs_txg_timeout_seconds) }} > /sys/module/zfs/parameters/zfs_txg_timeout' [Install] WantedBy=multi-user.target Obviously you’ll want to define {{ _zfs_txg_timeout_seconds }} and the zfs_txg_timeout_seconds. In general, this will make sure that the txg_timeout is set to what you want it to be upon startup after ZFS has started. Wasn’t that easy? If you’re answering no, it wasn’t easy for me to figure out either! I spent a lot of time wondering why DKMS wasn’t working properly (which is why the hack of preventing kernel upgrades is still included) and dealing with other issues. The OpenZFS documentation is pretty great but seems to be missing a guide somewhat like this, so hopefully this post will save people some time going forward when trying to experiment with new ZFS setups on Hetzner. Another thing I’m hoping for with this post is to be corrected – if you see something glaringly wrong in my setup, please reach out. The more people can use low cost infrastructure providers like Hetzner, the more cool software we get and the more interesting/innovative products can be built. To that end I’m working on NimbusWS (I’m behind on this but should launch by end of Q1 2022) – if you’re interested please sign up for the service and kick the tires (free tier usage will be available).