Installation d'une kimsufi sous FreeBSD en full-ZFS

Comme ZFS c'est beau, ça rend le poil soyeux et ça permet à l'admin de diminuer sa consommation d'aspirine, j'ai profité de mon changement de Kimsufi pour l'installer en tout ZFS, depuis le boot. Bien sûr, une solution aurait été de laisser l'installation sur / et de ne mettre que les données sur un volume ZFS, mais c'est trop facile, ça. Et puis on garde de l'UFS, c'est so-XXième siècle.

Pour installer en tout ZFS, il doit y avoir au moins trois solutions pour faire cette installation :

On est d'accord que le premier, c'est tricher. Chez moi le vKVM perdait régulièrement la connexion, alors j'ai utilisé le boot sur le réseau (le mode rescue-pro).

Let's go.

1. Installation

Cette partie est largement une reprise du wiki de FreeBSD sur l'installation d'un système en ZFS.

Cependant :

  • on ne boote pas sur l'ISO d'installation,
  • on boote sur une racine qui est en NFS lecture seule.

Il va donc falloir ruser (un peu) pour récupérer les paquets d'installation.

On boote alors sur le rescue-pro, on a bien sûr pris soin de donner sa clef publique SSH pour ne pas avoir à attendre le mail avec les identifiants.

Je n'ai pas réussi à installer ZFS en utilisant une table de partition MBR, alors que ça a marché du premier coup avec du GPT. Il paraît que GPT est la voie du futur, alors hop.

On détruit avec gpart destroy le partitionnement en place, et on recrée un nouveau schéma :

gpart create -s gpt ad4
gpart add -s 64K -t freebsd-boot ad4
gpart add -s 2G -t freebsd-swap -l swap ad4
glabel label swap ad4p2
gpart add -t freebsd-zfs -l data ad4
glabel label data ad4p3
gpart show

Autre possibilité : ne pas faire de partition de swap, mais créer un volume ZFS de swap. D'après la page du Wiki FreeBSD citée plus haut, ça empêche de créer des dumps lors d'un crash. En l'absence d'autres arguments, je suis parti sur une partition de swap à part.

Récupérer les fichiers d'installation. On crée un volume en tmpfs, et on ignore couragement l'avertissement qui apparaît dans le dmesg :

mkdir /root/sets
mount -t tmpfs -o size=300000000 dummy /root/sets
dmesg | tail
=> WARNING: TMPFS is considered to be a highly experimental
   feature in FreeBSD.

cd sets
ftp ftp.fr.freebsd.org
cd pub/FreeBSD/releases/amd64/8.2-RELEASE
!mkdir base kernels
mget base/* kernels/*

Dans mon cas, j'installe juste un hôte minimal pour des jails. Pour un serveur traditionnel, vous voudrez certainement installer les autres sets, mais au pire cela se fait très bien une fois l'installation terminée.

On crée le volume ZFS :

mkdir /root/newinstall
zpool create -m /root/newinstall zroot /dev/gpt/data
zpool set bootfs=zroot zroot

On crée les sous-volumes ZFS :

zfs create zroot/usr
zfs create zroot/var

zfs list

On devrait voir zroot monté dans /root/newinstall, zroot/var dans /root/newinstall, etc.

Encore une fois, pour un serveur complet on voudra peut-être créer d'autres volumes ZFS pour une séparation plus fine, peut-être un /var/log compressé ou un /var/empty en RO… Voir l'article du wiki de FreeBSD pour une idée de partitionnement possible. /home avec des quotas (voire un volume par luser) est une très bonne idée de chose à ajouter si on prévoit d'avoir d'autres utilisateurs.

Par contre, mettre la racine (de notre serveur) dans la racine (de notre pool ZFS) n'est pas forcément une très bonne idée. Heureusement, on peut corriger cela plus tard.

On installe le monde de base plus le noyau GENERIC :

setenv DESTDIR /root/newinstall
cd /root/sets
cd base ; sh install.sh ; cd ..

cd kernels ; sh install.sh generic ; cd ..
cd /root/newinstall/boot
rm -fr kernel
mv GENERIC kernel

chroot /root/newinstall

echo /dev/label/swap none swap sw 0 0 > /etc/fstab
echo 'zfs_load="YES"' > /boot/loader.conf
echo 'vfs.root.mountfrom="zfs:zroot"' >> /boot/loader.conf

vi /etc/rc.conf
sshd_enable="YES"
ntpdate_enable="YES"
ntpdate_hosts="213.186.33.99"
fsck_y_enable="YES"
named_enable="YES"
ifconfig_nfe0="inet 198.51.100.43/24"
defaultrouter="94.23.42.254"
hostname="foo.example.net"
zfs_enable="YES"

Mettre un mot de passe pour root (passwd), et se créer un utilisateur (adduser et répondre aux questions). Noter que par défaut sshd refuse les connexions en tant que root, donc créer un utilisateur mortel et le placer dans le groupe wheel est certainement une bonne idée.

Quitter le chroot.

On va installer le bootloader ZFS-capable. Là j'ai eu une surprise : ZFS s'est mis à utiliser toute la RAM, ce qui est normal vue l'installation qu'on vient de réaliser, mais au détriment de notre partition tmpfs, ce qui est étonnant étant donné qu'on a donné une réservation. Donc, j'ai démonté / remonté mon pool ZFS, mon tmpfs a retrouvé une taille normale, et j'ai pu récupérer le bootloader pour l'installer :

zpool export zroot
zpool import zroot
cp /root/newinstall/boot/pmbr /root/sets
cp /root/newinstall/boot/gptzfsboot /root/sets

zpool export zroot
gpart bootcode -b /root/newinstall/boot/pmbr -p /root/newinstall/boot/gptzfsboot -i 1 ad4
zpool import zroot

Il est peut-être possible d'installer le bootloader sans démonter le pool, je n'ai pas essayé. Il doit aussi certainement être possible d'utiliser celui est dans le /boot de l'environnement fourni par OVH, je n'y ai pas pensé sur le moment…

Il semble que ZFS ait besoin d'un cache pour booter correctement. Je n'ai pas trouvé d'articles expliquant quelle est l'utilité du cache et ce qui se passe s'il n'est pas disponible au boot.

zpool set cachefile=/root/newinstall/boot/zfs/zpool.cache

On remet les points de montage au bon endroit :

zfs set mountpoint=legacy zroot
zfs set mountpoint=/usr zroot/usr
zfs set mountpoint=/var zroot/var
zpool set bootfs=zroot zroot
zfs unmount -a

Et là on croise les doigts et on reboote.

2. Déplacement de la racine vers un autre dataset

Ceci permet de faire plusieurs choses :

  • appliquer une réservation d'espace pour la racine ;
  • lorsqu'une nouvelle MàJ va arriver, il suffira de l'installer dans un nouveau dataset et de dire au bootloader de prendre l'autre dataset.

Let's roll.

On copie notre racine actuelle dans un autre volume :

zfs snapshot zroot@1 zfs
send zroot@1 | zfs receive zroot/slash
zfs destroy zroot@1

Même chose pour /usr :

zfs snapshot zroot/usr@1
zfs send zroot/usr@1 | zfs receive zroot/slash/usr
zfs destroy zroot/usr@1

Bien sûr, même chose pour les autres FS si vous avez partagé votre /usr en morceaux.

Il m'a été indiqué que renommer zroot/usr dans zroot/slash/usr (avec zfs rename) est plus rapide, et surtout évite d'oublier un volume si /usr a été fractionné.

On indique qu'on veut booter sur zroot/slash :

zpool set bootfs=zroot/slash
vi /slash/etc/loader.conf

Et on ajuste la valeur de vfs.root.mountfrom.

On veut aussi changer notre /usr :

zfs set canmount=noauto zroot/usr
zfs set mountpoint=/usr zroot/slash/usr

À ce moment, on a deux volumes montés sur /usr. Ça marche, mais c'est un peu bancal ; on va donc rebooter de suite. Quand la machine revient, on vérifie avec zfs list et mount que tout est bien monter là où on l'attend (l'un montre la configuration des points de montage, et l'autre montre les vrais montages). On voit que zroot/slash a un mountpoint qui vaut /slash, mais est monté à / en vrai. Je ne sais pas à quel point ça peut être gênant.

Pour vérifier que le volume zroot n'est plus directement utilisé, on va le vider puis vérifier que la machine revient au reboot :

zfs set mountpoint=/whatever zroot
chroot /whatever
rm -fr *
# oups, il y a des fichiers avec l'option schg...
^D
chflags -R noschg /whatever
rm -fr /whatever/*
zfs set mountpoint=none zroot
rmdir /whatever
zfs destroy zroot/usr
reboot

(Attention si vous avez d'autres volumes qui héritent leur point de montage depuis zroot !)

Notez que je n'ai pas déplacé /var, qui ne sera pas concerné par les mises à jours. C'est peut-être un choix discutable.

3. Post-installation

Ensuite, il nous reste toutes les actions habituelles d'une installation FreeBSD :

  • configurer /etc/rc.conf pour activer les services que l'on veut ;
  • installer des jails pour nos serveurs qui vont parler au publique ;
  • ajouter l'arbre des ports pour installer des logiciels ;
  • (optionnellement) installer RTM d'OVH : http://guide.ovh.com/RealTimeMonitoring ;

Et moultes autres activités :)

Auteur : Frédéric Perrin

Date : samedi 27 août 2011, modifié le dimanche 18 septembre 2011

Sauf mention contraire, les textes de ce site sont sous licence Creative Common BY-SA.

Ce site est produit avec des logiciels libres 100% élevés au grain et en plein air.