
# BTRFS et Docker

Languages
=> /fr/posts/migrer-docker-btrfs/ 🇫🇷Français



## 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

```bash
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 flagamorç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

```bash
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

```bash
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³

```bash
$ 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`

```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.


## 

=> https://github.com/maharmstone/btrfs 🔗 [1]: support expérimental de Windows
=> https://github.com/g2p/bedup 🔗 [2]: offline
=> https://stackoverflow.com/questions/21597463/how-to-port-data-only-volumes-from-one-host-to-another 🔗 [3]: voir ici pour sauvegarder des volumes indépendants

Navigation
=> /fr/ Accueil
=> /fr/posts/ Publications
=> /recherche/ Recherche