지속 가능한 호스팅, 관리형 F/OSS 개체 저장소, Redis, Prometheus Hetzner, OVH 및 LeaseWeb에서 **tl;dr - Hetzner의 전용 하드웨어(Ubuntu 20.04 - âââFocalÃââ)에서 사용하기 위한 Ansible 기반 ZFS 설치 스크립트에 대한 줄별 설명입니다. â itÃâ완벽하거나 최소는 아니지만 나에게 적합합니다. 얼마 전 Hetzner에서 호스팅되는 모든 베어 메탈 전용 하드웨어에서 ZFS를 사용하여 연결된 HDD 및 SSD를 랭글링하기 시작했습니다. 공간에는 많은 선택 사항이 있습니다(표준 LVM, mdraid btrfs 등), 하지만 저는 ZFS의 기능과 인체 공학 때문에 ZFS를 선택했습니다. 그 이유에 대해 아무도 지루하게 생각하지 않겠지만 탐색해야 하는 것 중 하나는 Ubuntu 20.04(Hetzner에서 지원되는 운영 체제 중 하나)에 최신 버전의 ZFS를 설치하는 방법이었습니다. 시스템에서 ZFS를 설정하는 동안 몇 가지 문제(특히 사후 설치)가 발생하여 어떻게 했는지에 대한 연습을 제공하고 싶었습니다. 이 게시물은 ZFS를 설치하는 내 Ansible 스크립트에 대한 스탠자별 설명입니다. ZFS(또는 모든 파일 시스템)가 전환할 가치가 있는지 알기 전에 아마도 RTFM을 원할 것입니다. ZFS에는 많은 기능이 있으며 저는 확실히 전문가는 아니지만 프로젝트의 용어와 역사뿐만 아니라 방법과 이유를 아는 것이 매우 중요합니다. 시작할 수 있는 몇 가지 링크: ZFS(여기서 가장 알려지지 않은 수량일 가능성이 높음)와 함께 Ubuntu 및 일반 시스템 관리에 익숙해지기를 원할 것입니다. 그것은 다루어야 할 큰 영역을 종료하지만 다음은 몇 가지 링크입니다. 거의 말할 필요도 없지만 이 시점에서 Linux 시스템 관리에 익숙하지 않은 경우 이 작업을 시도해서는 안 됩니다. 저는 개인적으로 약간의 사용자 지정 구성으로 디스크를 선택합니다. Ãâ를 통해 RAID1(미러링) 설정이 있습니다 mdraid, 관리를 위해 ZFS에 제공할 수 있는 각 디스크의 파티션. 이상적으로는 ZFS에 제공할 전체 디스크가 있지만 파티션도 작동합니다. OS 설정( 디스크 설정을 포함하는 installimage)는 HetznerÃâ의 복구 모드에서 실행되며 다음과 같은 파일로 안내할 수 있습니다. # installimage DRIVE0 /dev/nvme0n1 DRIVE1 /dev/nvme1n1에 의해 사용되는 드라이브 선언 # 소프트웨어 RAID 활성화(OS 디스크용) SWRAID 1 SWRAIDLEVEL 1 # 부트로더(일반적으로 grub) BOOTLOADER grub # Machine hostame HOSTNAME machine01 # 파티션 configuration PART swap swap 32G PART /boot ext4 1G PART / ext4 128G # 이 마지막 부분이 만들어질 것입니다.& 나중에 ZFS로 다시 생성됨) PART /root-disk-remaining ext4 all # 네트워크 공유 IMAGE /root/.oldroot/nfs/images/Ubuntu-2004-focal-64-minimal.tar에 액세스하여 Hetzner가 사용하는 이미지를 지정할 수 있습니다. gz 이것은 분명히 Hetzner에 따라 다르지만 ZFS가 활용할 수 있는 파티션/드라이브를 갖기 위해 자신의 시스템에서 필요한 모든 작업을 수행하십시오. zfsutils-linuxand zfs-zed Ansible YAML에서 단계는 다음과 같습니다. - 이름: 모든 zfs 관련 업스트림 패키지 보유 ansible.builtin.shell: | apt-mark 보류 zfsutils-linux apt-mark 보류 zfs-zed 이 게시물을 작성하는 시점에서 Ubuntu Focal의 zfs-linux는 0.8.3입니다. 여기에서 우리의 목표는 최신 버전을 설치하고 계속 사용하는 것이므로 apt 업데이트는 설치된 버전을 이전 버전으로 교체하지 않습니다. 여기 있는 동안 패키지도 제거하겠습니다. - 이름: 설치된 경우 ZFS 업스트림(ubuntu) 패키지 제거 ignore_errors: yes ansible.builtin.command: | 적절한 퍼지 --allow-change-held-packages zfsutils-linux zfs-zed 에서 문서를 읽을 수 있습니다. 무엇을 보기 쉽다 purge는 제거와 비슷하지만 구성 파일이 있는 경우 제거합니다. 다음과 같이 OpenZFS에 대한 종속성을 설치할 수 있습니다. - name: 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 # 아래 줄은 `uname -r`의 출력을 호출합니다(예: "5.16.5-arch1- 내 아치 시스템의 경우 1"# 그래서 줄은 "linux-headers-5.16.5-arch1-1"(물론 우분투에서는 유효하지 않지만 예로서) - linux-headers uname_r.stdout }} - python3 - python3-dev - python3-setuptools - python3-cffi - libffi-dev - python3-packaging - git - libcurl4-openssl-dev 꼭 필요한 것은 아니지만 거의 모든 종속 항목이 필수여야 하는 몇 가지 종속 항목이 있을 수 있습니다. /opt/zfs 다음은 ZFS입니다. - 이름: Create /opt/zfs ansible.builtin.file: 경로: /opt/zfs 상태: 디렉토리 ZFS를 다운로드하려면 다음을 수행하십시오. - 이름: zfs ansible.builtin.get_url 다운로드: url: "httpsgithub.com/openzfs/zfs/releases/download/zfs _zfs_version zfs _zfs_version tar.gz"체크섬:_zfs_tarball_sha256_checksummode: 0755 대상: "/opt/zfs/zfs _zfs_version tar .gz"여기서 대체 {{ _zfs_version }} ( 2.1.1. 또한 다운로드를 직접 수행하고 사용할 체크섬을 수집/생성하고 싶을 것입니다. 체크섬 없이는 변경할 수 없는 항목을 인터넷에서 다운로드하지 마십시오! {{Ansible 템플릿 구문입니다)는 그리고 Ansible이 실행 중인 컴퓨터에서 복사하려는 경우(제가 하는 일입니다): - 이름: zfs 패키지 복사(속도 제한 방지) ansible.builtin.copy: src: files/zfs/zfs _zfs_version tar.gz"mode: 0755 dest: "/opt/zfs/zfs _zfs_version tar.gz"소스를 가져오기 위해 선택한 방법에 관계없이 물론 압축을 풀어야 합니다. - 이름: zfs 코드 압축 해제 ansible.builtin.unarchive: src: "/opt/zfs/zfs _zfs_version tar.gz"대상: "/opt/zfs"remote_src: 예 빌드 프로세스를 시작하려면: - 이름: ZFS 설정 및 빌드 ansible.builtin.shell: | ./autogen../configure make clean make -j args: chdir: "/opt/zfs/zfs _zfs_version 소스에서 빌드하는 데 익숙하다면 다양한 프로젝트에서 이 공통 도구 세트(일부 변형 스크립트 만들기, 자동 생성 및 구성). 예상할 수 있듯이 시간이 좀 걸릴 수 있으므로 시간을 좀 주세요. ZFS 구축 후 - 이름: ZFS ansible.builtin.shell 설치: | 설치 인수 확인: chdir: "/opt/zfs/zfs _zfs_version 일반적으로 *바로* 여기에서* 완료될 것이라고 생각하겠지만 일반적으로 이렇게 하는 것만으로는 충분하지 않기 때문에 이 게시물이 존재합니다! 앞으로 나아가자. 실행 중인 경우 먼저 ZFS 모듈을 강제로 언로드합니다. - 이름: ZFS 모듈(ss) ansible.builtin.shell의 강제 언로드: | ./scripts/zfs.-u 인수: chdir: "/opt/zfs/zfs _zfs_version 예상할 수 있듯이 이런 일이 발생하면 워크로드를 실행하지 *않는* 것이 이상적입니다. 모듈이 언로드되는 동안 몇 가지 도우미를 설치할 수 있습니다. - 이름: 설치 후 ZFS 도우미 ansible.builtin.shell: | ./scripts/zfs-helpers.-i 인수: chdir: "/opt/zfs/zfs _zfs_version 도우미가 설치된 후 ZFS 모듈을 강제로 다시 로드합니다. - 이름: ZFS 모듈 ansible.builtin.shell의 강제 재로드: | ./scripts/zfs.args: chdir: "/opt/zfs/zfs _zfs_version 나는 그 건물을 발견하고 deb 모듈(데비안에서 패키지 설치에 사용하는 형식)은 설치를 고정하고 우분투 패키지 기본값으로 대체하지 않는 데 도움이 되었습니다. 먼저 소스 코드에서 ZFS deb 패키지를 빌드합니다. - 이름: ZFS deb 패키지 ansible.builtin.shell 빌드: | deb 인수 만들기: chdir: "/opt/zfs/zfs _zfs_version 그런 다음 설치하십시오. - 이름: ZFS deb 패키지 설치 ansible.builtin.shell: | 예 | dpkg -i --force-overwrite deb apt install -f -y deb 인수: chdir: "/opt/zfs/zfs _zfs_version 이론적으로 이 단계는 필요하지 *않습니다*(또는 단독으로 사용해야 함) 이미 설치 프로세스를 실행했지만 둘 중 하나를 수행할 때 Â다시 시작하면 이전 버전의 ZFS를 사용하라는 메시지가 표시되는 상황이 있습니다( apt purge) - 특히 커널 수준에서. 모드프로브 즉시 설치된 ZFS 모듈을 활성화하려면 다음을 사용하십시오. 모드프로브: - 이름: Modprobe zfs 모듈 블록: - 이름: zfs 커널 모듈 설치 community.general.modprobe: 이름: zfs 상태: 현재 ZFS 설치는 커널 모듈을 설치하는 것을 의미하지만 동적 커널 모듈 지원을 통해 아직 구워지지 않았기 때문에 로컬에 설치된 커널 모듈을 사용할 수 있도록 설정해야 합니다. - 이름: extra가 앞에 있는지 확인 ansible.builtin.lineinfile: 경로: /etc/modules-load.d/modules.conf regexp: '^search'줄: "search extra updates ubuntu built-in"state: present 이것이 하는 일은 커널 모듈 검색 경로를 관리하는 파일이 /etc/modules-load.d/modules.conf에 다음과 같은 줄이 있습니다. 지정된 추가 업데이트를 검색합니다. 일반적으로 다음으로 시작하는 줄이 하나 이상 있습니다. 검색하고 우리가 원하는 것은 추가 모듈 위치는 프로세스 초기에 검색됩니다. DKMS 하위 시스템을 통해 설치하려고 합니다. - 이름: dkms install zfs ansible.builtin.shell: | dkms install zfs _zfs_version }} 인수: chdir: "/opt/zfs/zfs _zfs_version 이 시점에서 현재 활성 ZFS 버전을 확인할 수 있어야 하며 다음과 같이 표시되어야 합니다. root@machine01 ~ # zfs 버전 zfs-2.1.1-1 zfs-kmod-2.1.1-1 몇 가지 SystemD 장치(보통 Digital Ocean에 몇 가지 훌륭한 문서가 있음)가 생성되지만 ZFS가 사용하려면 활성화해야 합니다. - 이름: zfs 관련 시스템 장치가 활성화되었는지 확인 블록: - ansible.builtin.systemd: name:itemstate: 시작됨 활성화됨: 예 루프: - zfs-import-cache.service - zfs-import.target - zfs-mount.service - zfs-share.service - zfs-zed.service - zfs-volume-wait.service - zfs.target 반복되는 변수는 실행과 유사합니다. 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).