5

By now, it's well possible to get Ubuntu 16.04 running on a ZFS root-fs. Ubuntu 16.04 has ZFS in the default package manager, and with guides like this, it's not hard to get started.

However, all guides I've seen require being able to boot from a Ubuntu installation image. For a Hetzner dedicated server, this is an uncommon installation procedure, as it requires engineers to visit the server and plug-in a remote KVM.

By default, the dedicated servers boot into a rescue system, which allows to install a variety of Linux distributions through their 'installiamge' script. However, this script does not support ZFS yet.

How to get a Hetzner dedicated server running on a ZFS root?

2 Answers 2

12

The basic idea is to get Ubuntu installed on a small partition on the harddrive, partition the hard-drive to use the remainder of the space for ZFS, and then copy the installation over. I'm mainly using this guide on instructions how to do that.

Lazy, and experience with Ansible? I wrote a little stack of scripts to automate these steps. They are available on: https://github.com/tijszwinkels/hetzner-ubuntu-16.04-zfs-root-ansible/blob/master/hetzner-ubuntu-16.04.yml Be careful, these scripts assume that the host is booted into the Hetzner rescue system, and they will wipe your drives as a very first step. Use at your own risk!

# SSH into the host.

# Wipe the drives. Assuming SSDs on 'sda' and 'sdb'.
/sbin/blkdiscard /dev/sda
/sbin/blkdiscard /dev/sdb

# Install Ubuntu 16.04 on a 4G partition using the Hetzner 'installimage' script
/root/.oldroot/nfs/install/installimage -a -n my-hostname -r yes -l 1 -p /:ext4:4G -K /root/.ssh/robot_user_keys -i /root/.oldroot/nfs/install/../images/Ubuntu-1604-xenial-64-minimal.tar.gz

# Reboot the system.
/sbin/shutdown -r now

# Wait for the host to come back up, and SSH in.

# Install the 'parted' parition editor
apt-get update && apt-get install -y parted

# Run parted on the first drive, create a partition in all remaining space. (UNTESTED!)
sudo parted /dev/sda
(parted) mkpart primary 4097MB -1s
(parted) quit

# Run parted on the second drive, create a partition in all remaining space. (UNTESTED!)
sudo parted /dev/sdb
(parted) mkpart primary 4097MB -1s
(parted) quit

# Install required ZFS packages
apt-get install -y zfs-dkms zfs-initramfs

# Create a ZFS pool named 'tank'
# Please note that I'm using the /dev/disk/by-id interface. This is more resilient than /dev/sda and /dev/sdb
zpool create -f -o ashift=13 -O atime=off -O dedup=off -O compression=lz4  tank mirror `ls /dev/disk/by-id/ata-*-part2` 

# Create OS partiton
zfs create tank/os

# Rsync the current system to the new partition.
rsync -a --one-file-system / /tank/os/

# Chroot into the system
cd /tank/os
mount --bind /dev dev
mount --bind /proc proc
mount --bind /sys sys
mount --bind /run run
chroot .

# Install GRUB into the drives
export ZPOOL_VDEV_NAME_PATH=YES
update-grub
grub-install /dev/sda
grub-install /dev/sdb

Now, you should have a Hetzner dedicated server that happily boots into Ubuntu 16.04 with a ZFS root fs. Good luck!

3
  • 1
    Thanks a lot, that was a time saver ! The only thing missing (which I found in your link) was to install zfs (apt install zfs-dkms zfs-initramfs). Also in my case, there was no disk with id ls /dev/disk/by-id/ata-*-part2 so I used good old /sdXy
    – user981733
    Jan 29, 2018 at 8:43
  • Thank you for sharing back your findings! - I added the instructions for installing the packages. I personally prefer the /dev/disk/by-id interface, as it's supposedly more robust to moving drives around onto other ports or initialization order, but no idea whether that's an issue in practice.
    – TinkerTank
    Jan 30, 2018 at 15:41
  • 1
    Thanks, that also worked for Debian 9 (using the GUI installimage and then starting from the apt-get command) except for one important detail: I had to do additionally is to zfs set mountpoint=/ tank/os before the final reboot. Without that zfs in the initramfs tried to mount to /root/tank/os which did not work and stopped booting the system.
    – Boris
    Oct 30, 2018 at 15:15
2

Magnificent guide, thank you @TinkerTank.

If you are using one of the newer NVMe Servers and following this guide, you might want to use these steps and device names instead:


# Boot into rescue from Robot
# SSH into the host.

# Wipe the drives. Assuming SSDs on 'sda' and 'sdb'.
# For SSD Servers
#/sbin/blkdiscard /dev/sda
#/sbin/blkdiscard /dev/sdb
# For NVMe Servers
/sbin/blkdiscard /dev/nvme0n1
/sbin/blkdiscard /dev/nvme1n1

# Install Ubuntu 16.04 on a 16G partition using the Hetzner 'installimage' script
# For Ubuntu 18.04 it should be this, but FAILS TO BOOT
#/root/.oldroot/nfs/install/installimage -a -n my-hostname -r yes -l 1 -p /:ext4:16G -K /root/.ssh/robot_user_keys -i /root/.oldroot/nfs/install/../images/Ubuntu-1804-bionic-64-minimal.tar.gz
# For Ubuntu 16.04:
/root/.oldroot/nfs/install/installimage -a -n my-hostname -r yes -l 1 -p /:ext4:16G -K /root/.ssh/robot_user_keys -i /root/.oldroot/nfs/install/../images/Ubuntu-1604-xenial-64-minimal.tar.gz
# Press x to continue immediately or wait a few seconds...

# Reboot the system.
#/sbin/shutdown -r now

reboot

# Wait for the host to come back up, and SSH in.
# Update the server
apt update
apt upgrade

# Create a partition on first disk with all the remaining space.
fdisk /dev/nvme0n1
# Press n then accept all defaults and save with w 

# Create a partition on the second disk with all remaining space.
fdisk /dev/nvme1n1
Press n then accept all defaults and save with w 

reboot

# Install required ZFS packages
apt install zfsutils-linux

# Create a ZFS pool named 'tank'
# Please note that I'm using the /dev/disk/by-id interface. This is more resilient than /dev/sda and /dev/sdb
# For SSD servers @hetznet: zpool create -f -o ashift=13 -O atime=off -O dedup=off -O compression=lz4  tank mirror `ls /dev/disk/by-id/ata-*-part2` 
# For NVMe servers:
zpool create -f -o ashift=13 -O atime=off -O dedup=off -O compression=lz4  tank mirror nvme0n1p2 nvme1n1p2

# Create OS partition
zfs create tank/os

# Rsync the current system to the new partition.
rsync -a --one-file-system / /tank/os/

# Chroot into the system
cd /tank/os
mount --bind /dev dev
mount --bind /proc proc
mount --bind /sys sys
mount --bind /run run
chroot .

# Install GRUB into the drives
export ZPOOL_VDEV_NAME_PATH=YES
update-grub
# For SSD Servers:
#grub-install /dev/sda
#grub-install /dev/sdb
# For NVMe servers:
grub-install /dev/nvme0n1p2
grub-install /dev/nvme1n1p2

exit
reboot


Now, you should have a Hetzner dedicated server that happily boots into Ubuntu 16.04 with a ZFS root fs. Good luck!

Works seamlessly on Ubuntu 16.04, fails to boot on Ubuntu 18.04. Anyone knows why and how to solve it?

Notice: instead of 4GB of HDD Space specified in the original tutorial, I launch the initial OS on a 16GB partition. Newer servers come with at least 2 x 512GB NVMe, so you can convert those 2 x 16 partitions onto 2 x 16GB SWAP partitions that Linux kernel will stripe by itself (faster than using one single Raid partition).

3
  • I just installed this with an Ubuntu 16.04 image but I'm unable to reach the SSH after the reboot. What could be the issue?
    – Netizen110
    Sep 14, 2021 at 9:17
  • BTW does it make sense to create a ZFS mirror on top of a software RAID? Does it have any implications?
    – gruentee
    Jul 26, 2022 at 17:01
  • You are not creating a ZFS mirror on top of a software RAID, You are creating a mirror witha (small) chunk of your disks (which it totally optional), And then you are creating a ZFS mirror with the remaining of the disk. Dec 22, 2023 at 17:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .