Sustainably hosted, Managed F/OSS Imbakan ng bagay, Redis, Prometheus sa Hetzner, OVH at LeaseWeb **tl;dr - Linya sa linyang paliwanag ng aking ansible-powered ZFS install script para gamitin sa HetznerâÂÂs dedicated hardware (Ubuntu 20.04 - âÂÂFocalâÂÂ) â  itoâÂÂs hindi perpekto/minimal, ngunit ito ay gumagana para sa akin Noong nakaraan, nagsimula akong gumamit ng ZFS sa lahat ng aking bare metal na nakatuong hardware na naka-host sa Hetzner para makipagtalo sa mga naka-attach na HDD at SSD. Mayroong maraming mga pagpipilian sa espasyo (karaniwang LVM, mdraid btrfs, atbp), ngunit pinili ko ang ZFS para sa pag-reset at ergonomya nito. Hindi ako magsasawa sa sinuman kung bakit, ngunit isa sa mga bagay na kailangan kong i-navigate ay kung paano mag-install ng mga mas bagong bersyon ng ZFS sa Ubuntu 20.04 (isa sa mga sinusuportahang operating system sa Hetzner). Nakatagpo ako ng ilang isyu (lalo na pagkatapos ng pag-install) habang nagse-set up ng ZFS sa aking mga system kaya gusto kong magbigay ng walkthrough kung paano ko ito ginawa. Ang post na ito ay isang stanza-by-stanza na paliwanag ng aking mga Ansible na script na nag-i-install ng ZFS. Bago mo malaman kung ang ZFS (o anumang filesystem) ay sulit na lumipat sa, malamang na gusto mong mag-RTFM. Ang ZFS ay may maraming ins at tiyak na hindi ako eksperto dito, ngunit ang pag-alam sa kung paano at bakit, pati na rin ang terminolohiya at maging ang kasaysayan ng proyekto ay napakahalaga. Ilang link para makapagsimula ka: Kasama ng ZFS (na malamang na ang pinaka-kilalang dami dito) malamang na gusto mong maging pamilyar sa Ubuntu at pangkalahatang pangangasiwa ng mga sistema. Iyon ay huminto sa isang malaking lugar upang masakop ngunit narito ang ilang mga link: Ito ay halos walang sinasabi ngunit kung hindi ka masyadong pamilyar sa linux system administration sa puntong ito, malamang na hindi mo ito dapat subukan. Personal kong pinipili na ilagay ang aking mga disk sa isang medyo custom na configuration â Mayroon akong RAID1 (mirroring) setup sa pamamagitan ng mdraid, kasama ang mga partisyon sa bawat disk na maaari kong ibigay sa ZFS upang pamahalaan. Sa isip, mayroon akong buong disk na ibibigay sa ZFS ngunit gumagana rin ang mga partisyon. setup ng OS ( installimage) na may kasamang disk setup ay pinapatakbo mula sa rescue mode ng Hetzner at maaaring gabayan ng isang file tulad ng sumusunod: # Mga deklarasyon ng Drive na ginagamit ng installimage DRIVE0 /dev/nvme0n1 DRIVE1 /dev/nvme1n1 # Paganahin ang Software RAID (para sa OS disk) SWRAID 1 SWRAIDLEVEL 1 # Bootloader (karaniwang grub) BOOTLOADER grub # Machine hostame # Partition HOSTNAME machine01 configuration PART swap swap 32G PART /boot ext4 1G PART / ext4 128G # Gagawin ang huling parittion na ito (mapupunas& muling ginawa bilang ZFS mamaya) BAHAGI /root-disk-remaining ext4 lahat # Maaari mong tukuyin ang mga larawang ginagamit ni Hetzner sa pamamagitan ng pag-access sa kanilang network share na IMAGE /root/.oldroot/nfs/images/Ubuntu-2004-focal-64-minimal.tar. gz Malinaw na ito ay medyo partikular sa Hetzner, ngunit gawin ang anumang kailangan mong gawin sa iyong sariling mga system upang magkaroon ng mga partisyon/drive na magagamit para magamit ng ZFS. zfsutils-linuxand zfs-zed Sa Ansible YAML ang hakbang ay ganito: - pangalan: Hawakan ang lahat ng upstream na package na nauugnay sa zfs ansible.builtin.shell: | apt-mark hold zfsutils-linux apt-mark hold zfs-zed Sa pagsulat ng post na ito ang bersyon ng Ang zfs-linux sa Ubuntu Focal ay 0.8.3. Dahil ang layunin namin dito ay mag-install at patuloy na gumamit ng mas bagong bersyon, gusto naming tiyakin na mayroon hindi pinapalitan ng mga apt update ang aming naka-install na bersyon ng mas lumang bersyon. Habang narito tayo, i-purge na rin natin ang mga pakete. - pangalan: Purge ZFS upstream (ubuntu) packages kung naka-install na ignore_errors: yes ansible.builtin.command: | apt purge --allow-change-held-packages zfsutils-linux zfs-zed Maaari mong basahin ang mga doc sa apt upang makita kung ano Ang purge ay â itoâ ay katulad ng pag-alis ngunit inaalis din ang mga configuration file kung mayroon. Maaari mong i-install ang mga dependency para sa OpenZFS tulad nito: - pangalan: Mga kinakailangan sa pag-install para sa pagbuo ng ZFS ansible.builtin.apt: name:packagesupdate_cache: yes state: present vars: packages: - 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 # Ang linya sa ibaba ay tumatawag para sa output ng `uname -r`, halimbawa "5.16.5-arch1- 1"para sa aking arch system # upang ang linya ay lutasin sa isang bagay tulad ng "linux-headers-5.16.5-arch1-1"(hindi wasto sa Ubuntu siyempre, ngunit bilang isang halimbawa) - linux-headers uname_r.stdout }} - python3 - python3-dev - python3-setuptools - python3-cffi - libffi-dev - python3-packaging - git - libcurl4-openssl-dev Maaaring may ilang mga dependency na hindi mahigpit na kinakailangan ngunit halos lahat ng mga ito ay dapat na kailanganin. /opt/zfs Narito ang ZFS: - pangalan: Lumikha ng /opt/zfs ansible.builtin.file: path: /opt/zfs state: directory Kung gusto mong i-download ang ZFS: - pangalan: I-download ang zfs ansible.builtin.get_url: url: "httpsgithub.com/openzfs/zfs/releases/download/zfs _zfs_version zfs _zfs_version tar.gz"checksum:_zfs_tarball_sha256_checksummode: 0755 dest_zfs/zfstar: "/opt .gz"Narito ang pagpapalit {{ _zfs_version }} ( 2.1.1. Gusto mo ring ikaw mismo ang mag-download at mangolekta/bumuo ng checksum na gagamitin. Huwag kailanman mag-download ng mga bagay mula sa internet na hindi dapat magbago nang walang checsum! {{ay ang Ansible templating syntax) ay At kung gusto mong kopyahin ito mula sa computer kung saan tumatakbo ang Ansible (ito ang ginagawa ko): - pangalan: Kopyahin ang zfs package (iwasan ang limitasyon sa rate) ansible.builtin.copy: src: files/zfs/zfs _zfs_version tar.gz"mode: 0755 dest: "/opt/zfs/zfs _zfs_version tar.gz"Anuman ang pipiliin mong makuha ang pinagmulan, siyempre, kakailanganin mong i-unzip ito: - pangalan: I-unzip ang zfs code ansible.builtin.unarchive: src: "/opt/zfs/zfs _zfs_version tar.gz"dest: "/opt/zfs"remote_src: yes Upang simulan ang proseso ng pagbuo: - pangalan: Setup at Build ZFS ansible.builtin.shell: | ./autogen../configure make clean make -j args: chdir: "/opt/zfs/zfs _zfs_version Kung pamilyar ka sa pagbuo ng mga bagay mula sa pinagmulan, ginagamit ng iba't ibang proyekto ang karaniwang toolset na ito (ilang variant ng gumawa, mag-autogen at mag-configure ng mga script). Gaya ng maaari mong asahan na ito ay maaaring magtagal kaya bigyan ito ng ilang oras. Pagkatapos magtayo ng ZFS - pangalan: I-install ang ZFS ansible.builtin.shell: | gumawa ng pag-install args: chdir: "/opt/zfs/zfs _zfs_version Karaniwang iniisip mong tapos na kami *dito*, ngunit umiiral ang post na ito dahil karaniwang hindi sapat ang paggawa nito! Pindutin pa tayo. Pilitin munang i-unload ang (mga) ZFS module kung tumatakbo ang mga ito: - pangalan: Force unload ng ZFS module(ss) ansible.builtin.shell: | ./scripts/zfs.-u args: chdir: "/opt/zfs/zfs _zfs_version Mainam na *hindi* magpatakbo ng anumang mga workload kapag ito ay nangyayari, gaya ng maaari mong asahan. Habang dini-load ang mga module, maaari tayong mag-install ng ilang katulong: - pangalan: Post-Install ZFS Helpers ansible.builtin.shell: | ./scripts/zfs-helpers.-i args: chdir: "/opt/zfs/zfs _zfs_version Pagkatapos ma-install ang mga helper, pilitin nating i-reload ang ZFS module: - pangalan: Force reload ng ZFS module ansible.builtin.shell: | ./scripts/zfs.args: chdir: "/opt/zfs/zfs _zfs_version Natagpuan ko ang gusaling iyon at gamit ang deb module (ang format na ginamit ng Debian para sa pag-install ng package) ay nakatulong din sa pagkuha ng pag-install upang manatili at hindi mapalitan ng mga default ng Ubuntu package. Buuin muna ang ZFS deb package mula sa source code: - pangalan: Bumuo ng ZFS deb package ansible.builtin.shell: | gumawa ng deb args: chdir: "/opt/zfs/zfs _zfs_version At pagkatapos ay i-install ito - pangalan: I-install ang ZFS deb packages ansible.builtin.shell: | oo | dpkg -i --force-overwrite deb apt install -f -y deb args: chdir: "/opt/zfs/zfs _zfs_version Sa teoryang ang hakbang na ito *ay hindi dapat* kailangan (o dapat gamitin nang mag-isa), dahil nagpatakbo na kami ng proseso ng pag-install, ngunit nalaman ko na kapag ginagawa ko ang isa o ang isa pa. Âd may mga sitwasyon kung saan ang mga pag-restart ay mag-uudyok ng mas lumang bersyon ng ZFS na gamitin (sa kabila ng apt purge) â partikular sa antas ng kernel. modprobe Kung gusto mong paganahin ang ZFS module na na-install kaagad, gamitin modprobe: - pangalan: Modprobe zfs module block: - pangalan: I-install ang zfs kernel module community.general.modprobe: pangalan: zfs state: kasalukuyan Ang pag-install ng ZFS ay nangangahulugan ng pag-install ng kernel module, ngunit dahil hindi pa namin ito lubos na nai-bake sa pamamagitan ng Dynamic Kernel Module Support, kailangan naming paganahin ang mga lokal na naka-install na kernel module upang magamit: - pangalan: Tiyaking nasa harap ang extra ansible.builtin.lineinfile: path: /etc/modules-load.d/modules.conf regexp: '^search'line: "search extra updates ubuntu built-in"state: present Ang ginagawa nito ay tinitiyak na ang file na namamahala sa landas ng paghahanap ng kernel module Ang /etc/modules-load.d/modules.conf ay may linya sa loob nito na mayroon maghanap ng mga karagdagang update na tinukoy. Karaniwan mayroong kahit isang linya na nagsisimula sa maghanap, at ang gusto naming gawin ay siguraduhin Ang mga karagdagang lokasyon ng module ay hinanap nang maaga sa proseso. Gusto naming i-install sa pamamagitan ng DKMS subsystem: - pangalan: dkms install zfs ansible.builtin.shell: | dkms install zfs _zfs_version }} args: chdir: "/opt/zfs/zfs _zfs_version Sa puntong ito, dapat mong suriin ang kasalukuyang aktibong bersyon ng ZFS, at dapat itong magpakita sa iyo ng ganito: root@machine01 ~ # zfs na bersyon zfs-2.1.1-1 zfs-kmod-2.1.1-1 Mayroong ilang mga unit ng SystemD (gaya ng nakasanayan na ang Digital Ocean ay may ilang magagandang doc) na nilikha ngunit kailangang paganahin para magamit ng ZFS: - pangalan: Tiyaking pinagana ang mga unit ng systemd na nauugnay sa zfs: - ansible.builtin.systemd: name:itemstate: sinimulang pinagana: yes loop: - zfs-import-cache.service - zfs-import.target - zfs-mount.service - zfs-share.service - zfs-zed.service - zfs-volume-wait.service - zfs.target Ang mga variable na ini-loop ay katulad ng pagtakbo 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).