Incus auf Debian mit OpenZFS

Vielleicht schreib ich später noch was zum Warum, hier erst mal, was ich mir aufgesetzt habe:

Nach der Anleitung hier bzw. hier habe ich Debian Bookworm auf ZFS mit nativer Encryption und Dropbear installiert.

Es war schon spät und ich habe 2 Fehler gemacht, vor denen ich warnen möchte:

1.) in der Anleitung wird 2x das root passwort gesetzt und ich dachte mir beim 2. Mal, so ein Quatsch, hab ich doch grade erst. Tja, das erste war für die Installationsumgebung (u.a. damit man per ssh drauf kommt und nicht im ILO installieren muß (Grusel)), das zweite wäre für das zu installierende System gewesen. Nun, als ich dann fertig war, stellte ich fest, daß mein neu installiertes System keine User/PW-Kombi hatte, mit der man rein käme und stellte dabei auch fest, daß Debian zwischenzeitlich im single-User Mode niemanden mehr rein lässt, der sich nicht als root ausweisen kann.

2.) Mein HPE Microserver Gen10 plus hat 4x 10TB-Festplatten und 2x USB3.2 angebundene 1TB-SSDs (die ich erst mal nicht nutze). Eine der beiden Anleitungen, die ich parallel verfolgte wies darauf hin, man solle unbedingt disk-by-id Pfade für ZFS nutzen. Nachdem der Server bislang immer verlässlich die Platten als sda, sdb, sdc und sdd identifizierte, hielt ich das für übervorsichtig und ließ es sein. Hatte beim 1. Versuch (ohne Vergabe des root-PWs) auch funktioniert … Bereits beim 2. Versuch ging es schief und ich hatte erhebliche Probleme (mangels Routine mit ZFS) damit, ZFS von den SSDs runterzukratzen (bei diesem Installationsversuch waren unter sda, sdb, sdc und sdd zwei der SSDs drunter…)

im 3. Versuch war dann alles wie es sein sollte. Ich habe aus den Backports noch ZFS 2.2 installiert, weil das für die Overlays bei Containern notwendige Features mitbringt.

Incus kam dann nach der Anleitung von hier bzw. hier installiert mit dem Repository von Zabbly.

Ich habe dann einen LXContainer mit Debian installiert, in dem ich Docker installiert habe. Incus kann zwar inzwischen auch OIContainer installieren, da fehlt mir aber noch einiges zum gewohnten Docker-Compose.

Die LXContainer erhalten by default Netzwerk-Adressen im 172.-er Netz, die von außen erstmal nicht erreichbar sind, ich wollte aber einen LXContainer (quasi statt einer VM) aufsetzen, in dem ich docker compose nutzen kann und der “natürlich” auch IP-Adresse von meinem DHCP-Server aus dem 192.-er Netz kriegen sollte, die von außen erreichbar sind.

Dazu habe ich auf dem Host ein Bridge-Interface eingerichtet, dem ich die Mac-Adresse des physischen Interfaces gab (damit die IP stabil bleibt):

in der Datei /etc/network/interfaces.d/br0-setup

# Define the bridge interface
auto br0
iface br0 inet dhcp
    bridge_ports ens1f0
    bridge_stp off
    bridge_fd 0
    bridge_maxwait 0
    bridge_hw aa:bb:cc:dd:ee:ff

das “zugehörige” physische Interface ens1f0 wird nicht initialisiert (weil ich sonst 2 IP-Adresse aus dem gleichen 192-Segment kriege, was z.B. NFS überhaupt nicht leiden kann). Die MAC-Adresse von ens1f0 wird für br0 übernommen in der letzten Zeile.

Damit auch der incus-LXContainer (der bei mir “docker” heißt wg. der beabsichtigten Verwendung) sich an diese Bridge klemmt erstellt man auf dem Host ein Networkprofile für incus (ich denke ich bin dieser Anleitung gefolgt):

root@hpe:~# incus profile create mainlan
Profile mainlan2 created
root@hpe:~# incus profile device add mainlan eth0 nic \ nictype=bridged parent=br0
Device eth0 added to mainlan
root@hpe:~# incus profile show mainlan
config: {}
description: ""
devices:
  eth0:
    nictype: bridged
    parent: br0
    type: nic
name: mainlan
used_by: []
project: default

Dann habe ich den container erzeugt und dabei das Profile genutzt (eine Zeile!):

incus launch images:debian/12 docker --profile default --profile mainlan -c boot.autostart=true   -c security.nesting=true   -c security.syscalls.intercept.mknod=true   -c security.syscalls.intercept.setxattr=true

Die -c (config) Parameter mit “security.” sind notwendig, um im LXContainer später Docker-Container nutzbar zu machen. boot.autostart=true ist selbsterklärend 🙂

Für die Docker-Installation bin ich einer Anleitung wie dieser gefolgt (bis auf zfs statt btrfs Storage backend für incus)

Hier noch (weitgehend unkommentiert und unredigiert) meine Notizen während der Installation:

# boot live Cd

sudo -i
apt install --yes openssh-server
echo  PermitRootLogin Yes >>/etc/ssh/sshd_config:

passwd # set temp-root-password for live-system	

sudo systemctl restart ssh

ssh root@<ip-address> # to avoid typing on console / getting copy+paste

vi /etc/apt/sources.list #add contrib
deb http://deb.debian.org/debian bookworm main contrib non-free-firmware

apt update
apt install --yes debootstrap gdisk zfsutils-linux

DISKS="/dev/disk/by-id/wwn-0x5000000000000001 /dev/disk/by-id/wwn-0x5000000000000002 /dev/disk/by-id/wwn-0x5000000000000003 /dev/disk/by-id/wwn-0x5000000000000004" 

# never use “/dev/sda” etc. !!!!

swapoff --all

for DISK in $DISKS
do
wipefs -a $DISK
sgdisk --zap-all $DISK
sgdisk  -a1 -n1:24K:+1000K -t1:EF02 -I $DISK
sgdisk     -n2:1M:+512M   -t2:EF00 -I $DISK
sgdisk     -n3:0:+1G      -t3:BF01 -I $DISK
sgdisk     -n4:0:0        -t4:BF00 -I $DISK #for unencrypted or zfs native crypt
done

# additional/optional for flash storage:
for DISK in "/dev/disk/by-id/usb-Samsung_PSSD_T7_S5T4NS0R000001M-0:0" "/dev/disk/by-id/usb-Samsung_PSSD_T7_S5T4NS0R000001M-0:0"
do
blkdiscard -f $DISK
done 

zpool create -f \
    -o ashift=12 \
    -o autotrim=on \
    -o compatibility=grub2 \
    -o cachefile=/etc/zfs/zpool.cache \
    -O devices=off \
    -O acltype=posixacl -O xattr=sa \
    -O compression=lz4 \
    -O normalization=formD \
    -O relatime=on \
    -O canmount=off -O mountpoint=/boot -R /mnt \
    bpool raidz /dev/disk/by-id/wwn-0x5000000000000001-part3 /dev/disk/by-id/wwn-0x5000000000000002-part3 /dev/disk/by-id/wwn-0x5000000000000003-part3 /dev/disk/by-id/wwn-0x5000000000000001-part3

zpool create -f \
    -o ashift=12 \
    -o autotrim=on \
    -O encryption=on -O keylocation=prompt -O keyformat=passphrase \
    -O acltype=posixacl -O xattr=sa -O dnodesize=auto \
    -O compression=lz4 \
    -O normalization=formD \
    -O relatime=on \
    -O canmount=off -O mountpoint=/ -R /mnt \
    rpool raidz /dev/disk/by-id/wwn-0x5000000000000001-part4 /dev/disk/by-id/wwn-0x5000000000000002-part4 /dev/disk/by-id/wwn-0x5000000000000003-part4 /dev/disk/by-id/wwn-0x5000000000000004-part4


zfs create -o canmount=off -o mountpoint=none rpool/ROOT
zfs create -o canmount=off -o mountpoint=none bpool/BOOT



zfs create -o canmount=noauto -o mountpoint=/ rpool/ROOT/debian
zfs mount rpool/ROOT/debian
zfs create -o mountpoint=/boot bpool/BOOT/debian


zfs create                     rpool/home
zfs create -o mountpoint=/root rpool/home/root
chmod 700 /mnt/root
zfs create -o canmount=off     rpool/var
zfs create -o canmount=off     rpool/var/lib
zfs create                     rpool/var/log
zfs create                     rpool/var/spool


zfs create -o com.sun:auto-snapshot=false rpool/var/cache
zfs create -o com.sun:auto-snapshot=false rpool/var/lib/nfs
zfs create -o com.sun:auto-snapshot=false rpool/var/tmp
chmod 1777 /mnt/var/tmp

zfs create -o canmount=off rpool/usr
zfs create                 rpool/usr/local

zfs create -o com.sun:auto-snapshot=false rpool/var/lib/incus

mkdir /mnt/run
mount -t tmpfs tmpfs /mnt/run
mkdir /mnt/run/lock

debootstrap bookworm /mnt

mkdir /mnt/etc/zfs
cp /etc/zfs/zpool.cache /mnt/etc/zfs/

hostname hpe
hostname > /mnt/etc/hostname
vi /mnt/etc/hosts

# add hostname and ip to /mnt/etc/hosts

ip addr show

vi /mnt/etc/network/interfaces.d/ens1f0

auto ens1f0
iface ens1f0 inet dhcp

/mnt/apt/sources.list:

deb http://deb.debian.org/debian bookworm main contrib non-free-firmware
deb-src http://deb.debian.org/debian bookworm main contrib non-free-firmware

deb http://deb.debian.org/debian-security bookworm-security main contrib non-free-firmware
deb-src http://deb.debian.org/debian-security bookworm-security main contrib non-free-firmware

deb http://deb.debian.org/debian bookworm-updates main contrib non-free-firmware
deb-src http://deb.debian.org/debian bookworm-updates main contrib non-free-firmware

mount --make-private --rbind /dev  /mnt/dev
mount --make-private --rbind /proc /mnt/proc
mount --make-private --rbind /sys  /mnt/sys
chroot /mnt /usr/bin/env DISK=$DISK bash --login

apt update
apt install --yes console-setup locales

dpkg-reconfigure locales tzdata keyboard-configuration console-setup

apt install --yes dpkg-dev linux-headers-generic linux-image-generic
apt install --yes zfs-initramfs
echo REMAKE_INITRD=yes > /etc/dkms/zfs.conf

apt install systemd-timesyncd
apt install ntp

DISK="/dev/disk/by-id/wwn-0x5000000000000001"
# ggf. auch für die anderen Disks einrichten

apt install dosfstools

mkdosfs -F 32 -s 1 -n EFI ${DISK}-part2
mkdir /boot/efi
echo /dev/disk/by-uuid/$(blkid -s UUID -o value ${DISK}-part2) \
   /boot/efi vfat defaults 0 0 >> /etc/fstab
mount /boot/efi
apt install --yes grub-efi-amd64 shim-signed

apt purge --yes os-prober

passwd

!!!

vi /etc/systemd/system/zfs-import-bpool.service :


[Unit]
DefaultDependencies=no
Before=zfs-import-scan.service
Before=zfs-import-cache.service

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/sbin/zpool import -N -o cachefile=none bpool
# Work-around to preserve zpool cache:
ExecStartPre=-/bin/mv /etc/zfs/zpool.cache /etc/zfs/preboot_zpool.cache
ExecStartPost=-/bin/mv /etc/zfs/preboot_zpool.cache /etc/zfs/zpool.cache

[Install]
WantedBy=zfs-import.target

apt install --yes --no-install-recommends dropbear-initramfs
mkdir -p /etc/dropbear/initramfs

# Optional: Convert OpenSSH server keys for Dropbear
for type in ecdsa ed25519 rsa ; do
    cp /etc/ssh/ssh_host_${type}_key /tmp/openssh.key
    ssh-keygen -p -N "" -m PEM -f /tmp/openssh.key
    dropbearconvert openssh dropbear \
        /tmp/openssh.key \
        /etc/dropbear/initramfs/dropbear_${type}_host_key
done
rm /tmp/openssh.key



cat >/etc/apt/apt.conf  <<-EOF
APT::Install-Recommends “0”;
APT::Install-Suggests "0";
EOF


Posted

in

by

Tags: