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 :
- partir du système existant et installé, créer un volume, faire un
cp
de notre/
UFS vers ce volume ZFS, pointer le chargeur de boot vers ce volume ; - booter depuis le réseau (OVH permet de booter sur un FreeBSD 8.2, yay), et faire l'installation comme cela ;
- booter sur vKVM depuis une ISO.
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 :)