Je me réveille un matin avec une idée en tête : installer Docker sur un environnement CentOS / Red Hat !

Plutôt farfelu comme réveil, je vous l’accorde…

“Faciiile  !” vous allez me dire. Oui, mais… il y a quelques points sur lesquels vous allez devoir être attentifs. Docker a l’air simple à installer, oui il l’est. Avez-vous pensé à son exploitation et son entretien quotidien ? “Pas besoin, ça fonctionne tout seul.” Dans la réalité, ce n’est pas tout à fait vrai. Il faut correctement configurer Docker pour qu’il reste sur les rails.

 

Expérience éducative avec Docker

Le type d’environnement sur lequel je m’amuse :

cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)

 

Pour cela, je me positionne en tant que Master of Puppets sur le serveur : root

Installons naïvement Docker :

Documentation : https://docs.docker.com/install/linux/docker-ce/centos

yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install docker-ce

Vérifions la version de Docker installée

docker -v
Docker version 17.06.0-ce, build 02c1d87

 

Regardons quel est le filesystem associé au répertoire d’installation de Docker : /var/lib/docker

df -Th /var/lib/docker
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/vgroot ext4 15G 6.0G 7.8G 44% /var/lib/docker

 

Oh mon dieu !!! Docker est installé sur la partition “root” (aussi appelée “slash”) !!!
Imaginez que Docker remplisse le disque à lui tout seul… on va se retrouver comme les autruches, la tête au fond du trou ! Vous allez vite comprendre pourquoi.

1 ère tape : Isoler la partition où se trouve Docker dans le format actuel : ext4

On nettoie ce qui a été installé pour repartir de zéro

yum remove docker-ce

rm -rf /var/lib/docker

Si vous n’êtes pas à l’aise avec le partitionnement, suivre ce tutoriel pour le devenir: https://doc.ubuntu-fr.org/lvm

On vérifie qu’il reste bien du disque libre sur le serveur

vgs
VG #PV #LV #SN Attr VSize VFree
vg 2 6 0 wz--n- 59.49g 45.40g

 

On crée une partition (volume logique)

lvcreate -n docker -L 10g vg

On formate la partition en ext4

mkfs.ext4 /dev/mapper/vg-docker

On monte la partition sur le futur répertoire de docker /var/lib/docker

mkdir /var/lib/docker
mount /dev/mapper/vg-docker /var/lib/docker

On installe Docker

yum install docker-ce
systemctl start docker
systemctl enable docker

 

Si on regarde le “Storage Driver” de docker sous ext4

docker info
Storage Driver: Devicemapper

Docker : Docker storage driver – Device Mapper

 

Autre remarque, le filesystem est en ext4, rien de choquant j’entends… Parfait, faisons quelques tests =D

 

2ème étape : Eprouver Docker sur un FS en EXT4

Nous allons lancer un conteneur témoin, remplir le filesystem dédié à Docker et constater son comportement.

Lancer un conteneur témoin

docker run -d -it --name hello-world -p 8088:80 tutum/apache-php

Visualiser le conteneur lancé sur le port 8088

curl http://localhost:8088

Ca fonctionne !

Remplir le filesystem Docker jusqu’à ras bord

df -h /var/lib/docker
dd if=/dev/zero of=/var/lib/docker/bouchon bs=100M
df -h /var/lib/docker

Visualiser le conteneur lancé sur le port 8088

curl http://localhost:8088

Ca mouline vers l’infini et l’au-delàààaaa…

Je vous présente la magie Docker/EXT4 en direct live.

Docker ne sait pas très bien gérer son espace disque avec un filesystem EXT4.

Le problème, c’est que pour rétablir le service, vous vous rendrez vite compte qu’il faut arrêter docker, le supprimer et le réinstaller… Un peu bourrin comme méthode ? Effectivement… mais pas moyen de gérer ce problème autrement et simplement en ext4… On va chercher une autre méthode.

 

Un méconnu filesystem fait alors son apparition : le BtrFS (égalament connu sous le nom de “better fs”). Pour faire simple, c’est un filesystem qui fonctionne en couches (layers) pour y stocker ses états sur le disque (snapshots, état ponctuel du disque dans le temps).

Documentation sur BtrFS : https://doc.ubuntu-fr.org/btrfs

 

Comme de par hasard, les images Docker fonctionnent en couches (layers) également. Docker possède un “Storage Driver” compatible BtrFS, qui utilise les Layers du filesystems BtrFS pour mapper avec les Layers des images Docker. En résulte une meilleur gestion du disque, optimise l’espace ponctuellement occupé.

Ce n’est le meilleur des storage driver pour stabiliser une architecture.

Changeons maintenant de filesystem pour du BetterFS 😉

 

Configurer la partie Filesystem de Docker : BtrFs

Documentation : Docker storage driver – BtrFS

On nettoie nos précédentes expériences

yum remove docker-ce
umount /var/lib/docker
rm -rf /var/lib/docker
lvremove /dev/vg/docker

On vérifie l’espace disque disponible

vgs
VG #PV #LV #SN Attr VSize VFree
vg 2 6 0 wz--n- 59.49g 45.40g

 

On crée la partition

lvcreate -n docker -L 10g vg

On formate la partition en BtrFs

mkfs.btrfs /dev/mapper/vg-docker

On monte la partition sur le futur répertoire de docker /var/lib/docker

mkdir /var/lib/docker
mount /dev/mapper/vg-docker /var/lib/docker
df -T /var/lib/docker/

Installation de Docker

yum install docker-ce
systemctl start docker
systemctl enable docker

Vérifions que le driver ait bien été pris en compte

docker info
Storage Driver: btrfs
Build Version: Btrfs v4.4.1
Library Version: 101

Documentation : Docker storage driver – BtrFS

 

Filesystem : Check ! Eprouvons maintenant le disque pour voir sont comportement

docker run -d -it --name hello-world -p 8088:80 tutum/apache-php

On affiche la page

curl http://localhost:8088

Ca fonctionne !! (encore heureux!)

Remplir le filesystem Docker jusqu’à n’en plus pouvoir

df -h /var/lib/docker
dd if=/dev/zero of=/var/lib/docker/bouchon bs=100M
df -h /var/lib/docker

Visualiser le conteneur lancé sur le port 8088

curl http://localhost:8088

Il tourne encore ! Incroyable ! Chose impossible en ext4…

Nettoyons maintenant le bouchon déposé sur le disque

rm /var/lib/docker/bouchon

Et on visionne le résultat

curl http://localhost:8088

 

Taadaaam !!! Et Docker reprend de plus belle, sans interruption 😉 (bon c’est presque le cas, mais sur des petites archi c’est transparent :p)

A partir de maintenant, Docker saura gérer le filesystem de façon efficace.

 

Mieux gérer l’utilisation du disque par Btrfs

Petite subtilité, je vous avertis sur l’utilisation prolongée de docker sur ce type de filesystem. Comme je l’ai énoncé tout à l’heure, le BtrFs est constitué de couches (layers) où sont stockéee les images docker, mais pas que. La notion de snapshots arrive dans le tas quand on exploite des conteneurs avec de l’activité, des layers se créeent pour former des snapshots.

ll /var/lib/docker/btrfs/subvolumes
drwxr-xr-x 1 root root 178 Jan 26 11:43 005c608e9ac8709291f201cc7cdd33778a7123343e8dbf0b5252eef3056e88fd
drwxr-xr-x 1 root root 114 Jul 24  2017 02db81036cf8951e01522fd1b9dd65723fb02b43876132246b0e2c56f7e40c6f
drwxr-xr-x 1 root root 140 Oct 24 11:25 02f1cbf30778b63e4e040c8a274a0c5f419399f87eeee0e65a13225e47575dee
drwxr-xr-x 1 root root 160 Nov  6 12:02 0355e3860817e64e61702502e438e9b5756e717ffa7c64aff413dfca85b38323
drwxr-xr-x 1 root root 152 Nov  6 12:02 0355e3860817e64e61702502e438e9b5756e717ffa7c64aff413dfca85b38323

 

L’activité des conteneurs fait bouger le filesystem qui crée des snapshots dans /var/lib/docker/btrfs/subvolumes, ce qui va remplir le filesystem et le désemplir quand il les supprimera. On peut estimer les variations à hauteur de 10%, donc il est important de monitorer l’espace disque restant pour ne pas dépasser les 80% (histoire d’avoir de la marge).

Le filesystem BtrFs reste un système de fichiers en bloc et sa distribution est faite dynamiquement. Pour faire simple, la vie des conteneurs crée des décalages entre l’espace restant et le prochain espace allouable (c’est inhérent aux filesystem par blocs). On va devoir régulièrement reconstituer les fragments du filesystem et ainsi permettre de regrouper les blocs utilisés et accélérer les accès en lecture/écriture.

Pour ce faire, nous allons “défragmenter” le disque (ça peut faire mal à quelques personnes, désolé…^^)

btrfs filesystem balance start /var/lib/docker

Ajoutez cette règle dans la crontab du user root

crontab -l
# btrfs daily balancing
30 1 * * * /usr/sbin/btrfs filesystem balance start /var/lib/docker

 

Bonus track :

La version du Kernel peut vous sembler futile mais elle vous évitera quelques déboires avec Docker, surtout si vous cherchez de la stabilité =D (ce que tout le monde recherche apparemment)

Regardez votre version actuelle du kernel

uname -a
Linux my-server 3.10.0-514.10.2.el7.x86_64 #1 SMP Fri Mar 3 00:04:05 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

 

Installons un kernel-lt version 4

yum --enablerepo=elrepo-kernel install kernel-lt-4*
grubby --set-default $(ls /boot/vmlinuz-4* | tail -1)

On doit rebooter le serveur pour prendre ne charge les modifications

shutdown -r now

Une fois redémarré, on constate le changement

uname -a
Linux my-server 4.4.57-1.el7.elrepo.x86_64 #1 SMP Sun Mar 26 10:38:02 EDT 2017 x86_64 x86_64 x86_64 GNU/Linux

 

Conclusion

Le Storage driver fourni nativement avec docker, Device Mapper, peut s’avérer dangereux en Production dans certaines situations.

C’est pour cette raison qu’on s’est penché sur un autre Storage driver qu’est le BtrFS, qui s’appuie sur les mêmes concepts de Layers de docker et qui s’avère plus stable dans des situations critiques.
Le prix a payer est une configuration plus poussée en y ajoutant du Filesystem Balancing, de la Defragmentation et des sondes de monitoring  sur l’espace disque disponible.

 

What’s next ?

Dans un prochain article, on parlera de place Docker en Production, les erreurs à ne pas commettre et les points de vigilance.