Sürdürülebilir bir şekilde barındırılan, Yönetilen F/OSS Nesne depolama, Redis, Prometheus Hetzner, OVH ve LeaseWeb'de **tl;dr - Hetzner'in tahsis edilmiş donanımında (Ubuntu 20.04 - âÂÂFocalâÂÂ) kullanım için yanıtlayıcı destekli ZFS yükleme betiğimin satır satır açıklaması â  mükemmel/minimal değil, ama benim için çalışıyor Bir süre önce, bağlı HDD'leri ve SSD'leri boğmak için Hetzner'da barındırılan tüm çıplak metal adanmış donanımımda ZFS kullanmaya başladım. Alanda birçok seçenek vardır (standart LVM, mdraid btrfs, vb), ancak özellikleri ve ergonomisi için ZFS'yi seçtim. Nedeniyle kimseyi sıkmayacağım, ancak gezinmem gereken şeylerden biri, ZFS'nin daha yeni sürümlerini Ubuntu 20.04'e (Hetzner'da desteklenen işletim sistemlerinden biri) nasıl kuracağımdı. Sistemlerimde ZFS'yi kurarken bazı sorunlarla (özellikle kurulum sonrası) karşılaştım, bu yüzden bunu nasıl yaptığımı açıklamak istedim. Bu gönderi, ZFS'yi yükleyen Ansible betiklerimin dört dörtlük bir açıklamasıdır. ZFS'nin (veya herhangi bir dosya sisteminin) geçiş yapmaya değip değmeyeceğini bilmeden önce, muhtemelen RTFM'yi isteyeceksiniz. ZFS'nin pek çok püf noktası var ve ben kesinlikle bu konuda uzman değilim, ancak nasıl ve neden, terminoloji ve hatta projenin tarihini bilmek çok önemlidir. Başlamanız için birkaç bağlantı: ZFS ile birlikte (muhtemelen buradaki en bilinmeyen miktardır) muhtemelen Ubuntu'ya ve genel sistem yönetimine aşina olmak istersiniz. Bu, ele alınması gereken büyük bir alan ama işte birkaç bağlantı: Neredeyse söylemeye gerek yok ama bu noktada linux sistem yönetimine pek aşina değilseniz, muhtemelen bunu denememelisiniz. Kişisel olarak disklerimin biraz özel bir yapılandırmada olmasını seçiyorum â Üzerinden RAID1 (yansıtma) kurulumum var mdraid, her diskte yönetmesi için ZFS'ye verebileceğim bölümlerle birlikte. İdeal olarak, ZFS'ye verecek tüm disklere sahip olurdum ama bölümler de çalışır. işletim sistemi kurulumu ( disk kurulumunu içeren installimage) Hetzner'in kurtarma modundan çalıştırılır ve aşağıdaki gibi bir dosyayla yönlendirilebilir: # installimage DRIVE0 tarafından kullanılan sürücü bildirimleri /dev/nvme0n1 DRIVE1 /dev/nvme1n1 # Yazılım RAID'i Etkinleştir (OS diski için) SWRAID 1 SWRAIDLEVEL 1 # Bootloader (genellikle grub) BOTLOADER grub # Makine hostame HOSTNAME machine01 # Partition yapılandırma BÖLÜM takas takası 32G PART /boot ext4 1G PART / ext4 128G # Bu son parittion yapılacak (silinecek)& daha sonra ZFS olarak yeniden oluşturuldu) PART /root-disk-remaining ext4 all # Hetzner'ın kullandığı görüntüleri IMAGE /root/.oldroot/nfs/images/Ubuntu-2004-focal-64-minimal.tar ağ paylaşımlarına erişerek belirleyebilirsiniz. gz Bu açıkça oldukça Hetzner'a özgüdür, ancak ZFS'nin kullanabileceği bölümlere/sürücülere sahip olmak için kendi sistemlerinizde yapmanız gereken her şeyi yapın. zfsutils-linuxand zfs-zed Ansible YAML'da adım şöyle görünür: - ad: zfs ile ilgili tüm yukarı akış paketlerini tutun ansible.builtin.shell: | apt-mark tutma zfsutils-linux apt-mark tutma zfs-zed Bu yazının yazılmasından itibaren versiyonu Ubuntu Focal'daki zfs-linux 0.8.3'tür. Buradaki amacımız daha yeni bir sürümü yüklemek ve kullanmaya devam etmek olduğundan, herhangi bir apt güncellemeleri, kurulu sürümümüzü daha eski bir sürümle değiştirmez. Hazır buradayken paketleri de temizleyelim. - ad: Yüklüyse ZFS yukarı akış (ubuntu) paketlerini temizle ignore_errors: evet ansible.builtin.command: | apt purge ---değiştirilen paketlere izin ver zfsutils-linux zfs-zed Dokümanları şuradan okuyabilirsiniz: ne görmek için uygun temizleme, kaldırmaya benzer, ancak varsa yapılandırma dosyalarını da kaldırır. OpenZFS için bağımlılıkları şu şekilde kurabilirsiniz: - isim: ZFS oluşturmak için gereksinimleri yükleyin ansible.builtin.apt: isim:packagesupdate_cache: evet durum: mevcut değişkenler: paketler: - 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 # Aşağıdaki satır `uname -r` çıktısını çağırır, örneğin "5.16.5-arch1- 1"benim kemer sistemim için # böylece satır "linux-headers-5.16.5-arch1-1"gibi bir şeye çözümlenir (elbette Ubuntu'da geçerli değildir, ancak örnek olarak) - linux-headers uname_r.stdout }} - python3 - python3-dev - python3-setuptools - python3-cffi - libffi-dev - python3-paketleme - git - libcurl4-openssl-dev Kesinlikle gerekli olmayan birkaç bağımlılık olabilir, ancak hemen hemen tümü gerekli olmalıdır. / tercih / zfs İşte ZFS: - ad: /opt/zfs ansible.builtin.file oluşturun: yol: /opt/zfs durum: dizin ZFS'yi indirmek istiyorsanız: - isim: İndir zfs ansible.builtin.get_url: url: "httpsgithub.com/openzfs/zfs/releases/download/zfs _zfs_version zfs _zfs_version tar.gz"sağlama toplamı:_zfs_tarball_sha256_checksummode: 0755 dest: "/opt/zfs/zfs _zfs_version tar .gz"Burada ikame {{ _zfs_version }} ( 2.1.1. Ayrıca indirmeyi kendiniz yapmak ve kullanmak için bir sağlama toplamı toplamak/oluşturmak isteyeceksiniz. Kontrol toplamı olmadan değişmemesi gereken şeyleri asla internetten indirmeyin! {{Ansible kalıplama söz dizimidir) Ve eğer bunu Ansible'ın çalıştığı bilgisayardan kopyalamak istiyorsanız (ben bunu yapıyorum): - ad: zfs paketini kopyala (hız sınırından kaçının) ansible.builtin.copy: src: files/zfs/zfs _zfs_version tar.gz"mod: 0755 dest: "/opt/zfs/zfs _zfs_version tar.gz"Kaynağı nasıl almayı seçerseniz seçin, elbette onu açmanız gerekecek: - name: Zfs kodunu aç ansible.builtin.unarchive: src: "/opt/zfs/zfs _zfs_version tar.gz"dest: "/opt/zfs"remote_src: yes Oluşturma sürecini başlatmak için: - ad: ZFS ansible.builtin.shell Kur ve Oluştur: | ./autogen../configure make clean make -j args: chdir: "/opt/zfs/zfs _zfs_version Kaynaktan bir şeyler oluşturmaya aşinaysanız, çeşitli projeler bu ortak araç setini kullanır (bazı varyantları komut dosyaları oluşturun, otomatik oluşturun ve yapılandırın). Beklediğiniz gibi bu biraz zaman alabilir, bu yüzden biraz zaman tanıyın. ZFS'yi kurduktan sonra - isim: ZFS ansible.builtin.shell'i kurun: | make install args: chdir: "/opt/zfs/zfs _zfs_version Normalde *tam burada* işimizin biteceğini düşünürsünüz, ancak bu gönderi var çünkü bunu yapmak genellikle yeterli değil! İleriye basalım. Öncelikle çalışıyorlarsa, ZFS modül(ler)ini boşaltmaya zorlayın: - ad: ZFS modülünün/modüllerinin zorla kaldırılması ansible.builtin.shell: | ./scripts/zfs.-u args: chdir: "/opt/zfs/zfs _zfs_version Beklediğiniz gibi, bu olurken herhangi bir iş yükünü *çalıştırmamak* ideal olacaktır. Modüller boşken bazı yardımcıları kurabiliriz: - ad: Yükleme Sonrası ZFS Yardımcıları ansible.builtin.shell: | ./scripts/zfs-helpers.-i args: chdir: "/opt/zfs/zfs _zfs_version Yardımcılar yüklendikten sonra, ZFS modülünü yeniden yüklemeye zorlayalım: - isim: ZFS modülünün yeniden yüklenmesini zorla ansible.builtin.shell: | ./scripts/zfs.args: chdir: "/opt/zfs/zfs _zfs_version Şunu buldum: inşa etmek ve kullanmak deb modülü (Debian tarafından paket kurulumu için kullanılan format), kurulumun kalıcı hale gelmesine ve Ubuntu paket varsayılanlarıyla değiştirilmemesine de yardımcı oldu. Önce kaynak koddan ZFS deb paketini oluşturun: - isim: ZFS deb paketini oluşturun ansible.builtin.shell: | hata argümanları oluştur: chdir: "/opt/zfs/zfs _zfs_version Ve sonra kurun - ad: ZFS borç paketlerini kurun ansible.builtin.shell: | evet | dpkg -i --force-overwrite deb apt install -f -y deb args: chdir: "/opt/zfs/zfs _zfs_version Teorik olarak bu adım *gerekli olmamalı* (veya tek başına kullanılmamalı), zaten bir yükleme işlemi yürüttüğümüz için, ancak birini veya diğerini yaparken şunu buldum: Yeniden başlatmaların daha eski bir ZFS sürümünün kullanılmasını gerektireceği durumlar olabilir ( apt purge) â özellikle çekirdek düzeyinde. mod araştırması Hemen kurulan ZFS modülünü etkinleştirmek istiyorsanız, şunu kullanın: mod probu: - isim: Modprobe zfs modülü bloğu: - isim: zfs çekirdek modülünü kurun community.general.modprobe: isim: zfs durumu: mevcut ZFS'yi kurmak, bir çekirdek modülü kurmak anlamına gelir, ancak Dinamik Çekirdek Modülü Desteği aracılığıyla tam olarak geliştirmediğimiz için, yerel olarak kurulu çekirdek modüllerinin kullanılmasını etkinleştirmemiz gerekir: - ad: Ekstranın önde olduğundan emin olun ansible.builtin.lineinfile: yol: /etc/modules-load.d/modules.conf regexp: '^search'line: "ubuntu yerleşik ek güncellemeleri ara"durum: mevcut Bunun yaptığı, çekirdek modülü arama yolunu yöneten dosyanın /etc/modules-load.d/modules.conf içinde bir satır var belirtilen ekstra güncellemeleri arayın. Normalde ile başlayan en az bir satır vardır. arama ve yapmak istediğimiz şey emin olmak ekstra modül konumları sürecin başlarında aranır. DKMS alt sistemi aracılığıyla yüklemek isteyeceğiz: - isim: dkms kurulumu zfs ansible.builtin.shell: | dkms kurulum zfs _zfs_version }} args: chdir: "/opt/zfs/zfs _zfs_version Bu noktada, mevcut etkin ZFS sürümünü kontrol edebilmelisiniz ve size şöyle bir şey göstermelidir: root@machine01 ~ # zfs sürümü zfs-2.1.1-1 zfs-kmod-2.1.1-1 Oluşturulan ancak ZFS'nin kullanması için etkinleştirilmesi gereken birkaç SystemD birimi vardır (her zamanki gibi Digital Ocean'ın bazı harika belgeleri vardır): - name: zfs ile ilgili systemd birimlerinin etkinleştirildiğinden emin olun blok: - ansible.builtin.systemd: name:itemstate: başlatıldı etkin: evet döngü: - zfs-import-cache.service - zfs-import.target - zfs-mount.service - zfs-share.service - zfs-zed.service - zfs-volume-wait.service - zfs.target Döngülenen değişkenler koşmaya benzer 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).