BTRFS et Docker

BTRFS et Docker

Présentation

Le B-tree filesystem est un système de fichiers pour Linux, avec un support expérimental de Windows.
Moins rapide en écriture que Ext4, il dispose cependant de plus de fonctionnalités

  • découpage du système en subvolumes
  • dégragmentation à chaud
  • création de snapshots qui permettent des sauvegardes et restauration instantanées
  • fonctions RAID: JBOD, RAID0, RAID1 ... (RAID5/6 sont cassés), et conversions entre les types de RAID à chaud !
  • on peut ajouter/enlever/réparer des disques et équilibrer des données à chaud
  • dé-duplication online et offline
  • compression à la volée

Le RAID de Btrfs, contrairement à une carte hardware ou à LVM, se passe au niveau logique, donc il faut créer des partitions.

Note: Btrfs n'a pas besoin d'une table de partition, on peut écrire le système de fichiers directement sur le périphérique, cependant c'est peu commun donc ça risque de ne pas booter

Migration

Création du système de fichiers

J'ai utilisé deux disques de capacité indentique en vue de passer tout le système en RAID1 (disque miroir).
Pour créer un RAID, on peut partir d'un système de fichiers existant sur un seul disque, sinon

mkfs.btrfs -m raid1 -d raid1 /dev/sdc1 /dev/sdd1

On peut ensuite rajouter des disques

btrfs device add /dev/sde1 /point/de/montage/du/FS/existant
btrfs balance start -dconvert=raid1 -mconvert=raid1

On peut contrôller indépendamment les données -d et les métadonnées -m. Le wiki recommande de cloner les métadonnées.
Ne pas oublier de mettre le flag amorçable sur la partition BTRFS (sur chacun des disques du RAID) si on veut pouvoir démarrer sur le volume.

En cas de problème

Découpage

Btrfs peut découper le système de fichiers en sous-volumes, qui agissent comme des dossiers, mais peuvent être montés et on peut en créer des snapshots.
Lorsqu'on monte une partition btrfs, c'est les sous-volume racine qui est monté par défaut. Tout autre sous volume devra être crée dans celui-ci ou dans un autre sous-volume.
Le plus flexible est de créer tous ses subvolumes à la racine btrfs, et de les monter comme voulu. Par exemple on peut faire les sous-volumes suivants

  • @home monté dans /home
  • @root mis en sous-volume par défaut
  • @var monté dans /var

le arobase est souvent utilisé pour différencier les dossiers et les subvolumes
Sans oublier

root@server:~# mount /dev/sdx /mnt
root@server:~# btrfs subvolume create @root /mnt
root@server:~# btrfs subvolume create @home /mnt
root@server:~# btrfs subvolume list /mnt #pour trouver l'ID
ID 257 gen 143 top level 5 path @root
ID 318 gen 144 top level 5 path @home
ID 326 gen 145 top level 5 path @var
root@server:~# btrfs subvolume set-default 257 /mnt #mettre l'id du volume root
root@server:~# mount /dev/sdx -o subvol=@home /home

Snapshots

D'après le wiki, les snapshots ne remplacent pas les backups !
Il faut avoir monté le volume btrfs racine

btrfs mount /dev/sdx -o subvol=/ /media/btrfs
cd /media/btrfs;mkdir snapshots
btrfs subvolume snapshot @root snapshots/root-snap

On peut restaurer en montant la snapshot à l'emplacement du sous-volume, ou si on a crée la snapshot en lecture seule (-r), on peut supprimer le sous-volume et faire une snapshot de la snapshot read-only avec le nom original.

Docker

Si vous migrez votre système de ext4 à btrfs, Docker ne redémarrera pas, vos données de containers et de volumes seront inaccesibles ... :(
Pas de panique, vos volumes sont toujours là. Cependant vous pouvez dire au revoir à votre configuration si vous n'avez pas de backup.

Pro tip: vous avez une chance de tout relancer si vous copiez vos données sur un partition ext4 montée sur /var/lib/docker/ en ayant stoppé Docker)

Avant la migration

Vous pouvez sauvegarder vos images, containers, et volumes; mais il faudra se re-taper la config.
voir ici pour sauvegarder des volumes indépendants

$ docker save image:tag > image-tag.tar
$ docker export Conteneur-précieux -o conteneur-précieux.tar #sauvegarde le container entier SANS SES VOLUMES
$ docker load -i image.tar
$ docker import conteneur-précieux.tar nouveau-conteneur #restaure le conteneur
$ docker run -d -...config du précédent.. nouveau-conteneur

SURTOUT il faut faire une sauvegarde du dossier /var/lib/docker à un autre endroit, et garder particulièrement /var/lib/docker/volumes

Configuration

Btrfs fait du Copy-on-Write, ce qui veut dire que lors d'une modification d'un fichier, il écrit les modification en plus sans supprimer ce qu'il y avait avant. C'est la base du système de snapshots et de la déduplication.
Il se trouve que Docker fait pareil pour les layers des images des containers. Si vous lancez un conteneur mysql:ubuntu et nginx:ubuntu, inutile de télécharger deux fois l'image ubuntu.
Sur ext4, docker utilise le driver de stockage overlay2, overlay ou devicemapper. Mais il existe un driver spécial btrfs (de même pour zfs).
Pour le changer, mettre dans /etc/docker/daemon.json

{
  "storage-driver": "btrfs"
}

Relancez docker.
Vous pouvez conservez vos anciens volumes Docker si vous les copiez dans /var/lib/docker/volumes avant de relancer Docker.
Cependant vous pouvez dire adieu à vos containers.