ARTICLES
Adieu Docker
By Valentin Bremond
J’avoue, c’est un peu racoleur comme titre. D’autant plus que j’aime beaucoup Docker.
Enfin j’aime beaucoup ce qu’ils ont fait. Grâce à eux, tout le monde (y compris moi-même) aujourd’hui sait ce qu’est un conteneur. Ils ont complètement démocratisé le concept et l’utilisation des conteneurs (pour le meilleur et pour le pire d’ailleurs) et ont permis à d’autres projets (LXD, Rkt, machinectl, …) de se lancer / de gagner en visibilité.
Mais pourquoi diantre veux-tu virer Docker si t’aimes bien ?!
Docker, c’est avant tout un gros bordel qui tente de masquer le plus possible la complexité (relative) de l’utilisation des containers. Vous faites docker run fedora bash et hop, vous avez un shell sur une Fedora avec tout qui marche bien. C’est parfait pour débuter, pour tester en 2 secondes un truc, pour faire du dev sans se prendre la tête, mais ce qui me saoûle, c’est justement que je ne sais pas ce qu’il se passe derrière.
De la même manière, la registry Docker, c’est une image Docker (dockerception) que vous lancez et qui vous fournit une API REST pour jouer avec vos images. D’ailleurs, c’est quoi une image ? Mis à part en passant par un Dockerfile, vous savez build une image Docker from scratch ?
Non parce que quand vous faites FROM centos, ben il vous faut bien l’image CentOS. Comment elle est générée cette “base image” ?
Bref, trop d’inconnues pour moi.
Et puis bon, le boulot d’un devops / architecte système, c’est aussi de savoir associer plusieurs briques entre elles pour avoir un système complet, alors si on doit utiliser un seul outil qui fait tout, c’est moins challenging.
Et puis merde, le monde entier ne parle que de Docker, y’a pas que lui !
systemd
Tout le monde connaît systemd, personne ne l’aime. Je n’ai jamais vraiment compris pourquoi d’ailleurs, ça marche bien et c’est plutôt bien fait. J’imagine que c’est plus une question idéologique : Lennart est un peu le genre de personne à ne pas avoir peur des mots, ce qui ne plaît pas à tout le monde. Ils doivent être potes avec Linus d’ailleurs.
Mais je diverge.
Vous saviez que systemd intégrait un système de gestion des containers ? Ça s’appelle systemd-nspawn et c’est plutôt bien fait !
systemd-nspawn
C’est un outil intégré à systemd (donc si vous avez systemd, c’est bon) qui vous permet de spawner des containers à la mode Docker.
Exemple : systemd-nspawn --directory /my/distro/chroot bash.
Plusieurs différences avec Docker toutefois :
- vous pouvez spawner un OS complet, pas juste un processus : vous pouvez donc avoir un init (généralement systemd) qui se lance dans votre container et pas un simple processus
- il n’y a pas vraiment de notion d’image ici, systemd-nspawn va utiliser un dossier de chroot pour lancer votre OS
- la gestion du réseau est un peu plus pénible (mais vous pouvez le configurer avec des fichiers systemd, ce qui est plutôt cool) ; par contre j’ai pas encore bien pigé comment ça marchait donc je n’en parlerai pas (mais je mettrai à jour cet article quand j’aurai plus d’infos)
Utiliser des dossiers de chroot c’est sympa, mais ça devient assez vite relou à gérer quand vous voulez gérer plusieurs distros / applications. Du coup, les mecs, pas cons, ont créé un autre outil : machinectl.
machinectl
Ça, c’est un peu le superintendant de votre flotte de containers. C’est assez proche de Docker au final : ça vous permet de gérer des images et des containers.
Exemple : machinectl start fedora.
À noter que machinectl ne gère pas que des containers. Il peut tout aussi bien gérer des vraies VMs (mais bon nous on s’en fout dans notre cas présent).
Alors là je vous vois arriver avec vos gros souliers :
Oui mais t’avais dit tout à l’heure que t’aimais pas les images parce que c’était opaque truc bidule et là tu utilises un outil qui gère des images, tu nous prends pas un peu pour des cons ?
Tout à fait. Enfin non ! Enfin… Bref !
Les “images” que machinectl utilise sont en réalité (entre autres) soit des dossiers de chroot, soit des tar.gz de chroot. Et ça, c’est méga facile à générer :
1dnf -y --releasever=25 --installroot=/wherever/fedora25 --disablerepo="*" --enablerepo="fedora" --enablerepo="updates" install dnf fedora-releaseBoum, vous avez votre chroot Fedora 25. C’est pas quand même vachement plus clair que la magie noire du Dockerfile ?
Si vous voulez le promener facilement :
1cd /wherever/fedora25
2tar -czf ../fedora25.tar.gz .
3
4# Ou si vous avez du temps et pxz installé :
5tar -I pxz -cf ../fedora25.tar.xz .(cadeau : pxz, c’est parallel xz, utile si vous voulez compresser un truc en XZ et que vous avez plus d’un core sur votre processeur - ce qui devrait être le cas)
Vous pouvez ensuite faire connaître à machinectl votre image pour qu’il puisse l’utiliser : machinectl import-tar /wherever/fedora25.tar.gz fedora25. Vous vous doutez de la suite : machinectl start fedora25.
Workflow complet
Mettons qu’on veuille générer une image de Fedora 25 avec un Apache qui tourne dessus pour servir des fichiers quelconques :
1# On génère le chroot
2dnf -y --releasever=25 --installroot=/wherever/fedora25 --disablerepo="*" --enablerepo="fedora" --enablerepo="updates" install dnf fedora-release httpd
3
4# On installe tout dessus
5cd /wherever/fedora25
6cp /mon/site/conf/httpd.conf ./etc/httpd/conf.d/monsite.conf
7cp -r /mon/site/files/* ./var/www/html/
8systemd-nspawn --directory $(pwd) systemctl enable --now httpd
9
10# On package tout ça
11tar -czf ../monsite-fedora25.tar.gz .
12
13# On l'importe et on le lance
14machinectl import-tar /wherever/monsite-fedora25.tar.gz monsite
15machinectl start monsiteBon, par contre, comme j’expliquais honteusement plus haut, je n’ai pas encore trop creusé sur le sujet du réseau. Par défaut, les containers n’ont pas accès au réseau, mais vous pouvez tout à fait configurer le truc pour créer un “réseau interne” à la Docker (ou tout simplement lier une interface virtuelle du container avec une interface virtuelle sur le host). Le fonctionnement reste le même qu’avec Docker : vous pouvez binder un port du host sur un port du container. Je mettrai à jour cet article quand j’en saurai un peu plus.
Conclusion
Vous voyez, c’est pas compliqué d’utiliser une autre techno que Docker pour lancer des containers ! Évidemment, niveau simplicité, c’est pas la même chose. Mais au moins on comprend beaucoup mieux ce qu’il se passe et on n’a pas de gros démon qui tourne en permanence sur la machine.
En tous cas, c’est toujours bon de savoir ce qu’il se passe chez la concurrence.
Gotchas
Il y a toutefois quelques différences à connaître avec Docker pour ne pas se faire avoir.
overlayfs
Docker utilise overlayfs pour ses images, ce qui lui permet de réutiliser des couches entre différentes images ; ici ce n’est pas le cas : une image c’est un tar.gz et c’est marre. Si vous devez import-tar (ou plutôt pull-tar https://mon.image.com/monsite-fedora25.tar.gz qui fait pareil mais à travers le réseau) deux fois la même “image”, vous allez télécharger deux fois l’intégralité du fichier.
Les modifications persistent
Les containers sont démarrés par défaut dans leur chroot en RW, ce qui veut dire que toutes les modifications faites dans le chroot persistent (contrairement à Docker qui peut tout wiper quand le container se termine).
Si vous utilisez btrfs, vous pouvez demander à systemd-nspawn de vous créer un snapshot du chroot avant de lancer le container pour avoir un comportement proche de Docker (cf –ephemeral).
Vous pouvez également faire savoir à machinectl qu’une image doit être mise en read-only en utilisant : machinectl read-only monsite true. Évidemment, il est possible que des problèmes surviennent dans ce cas, à tester donc (un FS en read-only c’est pas un use case classique pour un OS).