From e9cda4101720715fa87a2c976b5a051eb9c624aa Mon Sep 17 00:00:00 2001 From: Quentin Date: Tue, 11 Apr 2023 09:45:46 +0000 Subject: [PATCH] =?UTF-8?q?Update=20Article=20=E2=80=9C2023-04-11-fabrique?= =?UTF-8?q?r-des-conteneurs-l=C3=A9gers-depuis-une-ci-cd=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...-des-conteneurs-légers-depuis-une-ci-cd.md | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/_posts/2023-04-11-fabriquer-des-conteneurs-légers-depuis-une-ci-cd.md b/_posts/2023-04-11-fabriquer-des-conteneurs-légers-depuis-une-ci-cd.md index 609d6e3..905a698 100644 --- a/_posts/2023-04-11-fabriquer-des-conteneurs-légers-depuis-une-ci-cd.md +++ b/_posts/2023-04-11-fabriquer-des-conteneurs-légers-depuis-une-ci-cd.md @@ -1,13 +1,13 @@ --- layout: post -title: Fabriquer et publier des conteneurs depuis une CI/CD +title: Fabriquer et publier des conteneurs sans daemon Docker date: 2023-04-11T10:51:40.008+02:00 status: draft sitemap: true category: developpement description: Construire et publier des conteneurs légers et multi-plateformes - depuis une CI/CD implique plusieurs défis à relever, on les adresse un par un - ici. + depuis une CI/CD implique plusieurs défis à relever quand on a pas de daemon + Docker à disposition, je vous partage mes réflexions. --- J'ai pas mal travaillé sur la CI/CD de [Garage](https://garagehq.deuxfleurs.fr/), et force est de constater qu'on a rencontré un nombre incroyable de problèmes. Entre autre, on a noté que les builds Rust sans cache sont trop lents par rapport à nos attentes, qu'il n'y avait pas de solution légère pour gérer les artefacts binaires et enfin que construire un conteneur quand on a un CI/CD à base de Docker, ça n'était pas possible car on n'avait pas accès au daemon docker ni la possibilité de faire du “docker in docker” de manière à peu près sécurisé. @@ -61,18 +61,29 @@ packages = builtins.mapAttrs (name: value: { }) archmap; ``` -Ce fichier est relativement simple à lire une fois qu'on sait comment le lire. Ici, on va construire par rafinement successif les outils pour construire notre conteneur. Le premier bloc consiste en une fonction qui permet de compiler un module Go à partir de la recette fournie par la bibliothèque standard NixOS. Je dis bien une fonction, car ce bloc prend en paramètre `arch` qui contient l'architecture cible de notre module. Ainsi, si on lui passe `arm64` on aura un binaire qui fonctionne sur les processeurs ARM 64 bits, si on passe `386`, on aura un binaire pour les vieux PC x86 32 bits, etc. +_On peut consulter le fichier en entier_ [_sur la forge_](https://git.deuxfleurs.fr/quentin/albatros/src/commit/d9facbb79c4551d90359c46b9f5d485c1503253a/flake.nix) _d'Albatros_. -Dans les blocs suivants, on raffine donc ce premier module. On va d'abord avoir une fonction qui va extraire le binaire statique du module généré par Go, ensuite une fonction Docker qui va mettre ce binaire statique dans un conteneur. +Ce fichier est relativement simple à lire une fois qu'on sait comment l'aborder. -Enfin, on va déclarer quelles architectures on choisit de supporter, là j'en ai choisi 4. On va donc faire une boucle (`mapAttrs`) pour générer le conteneur Docker qui va bien pour chaque architecture. +En fait on construit par rafinement successif. Le premier bloc consiste en une fonction qui permet de compiler un module Go à partir de la recette fournie par la bibliothèque standard NixOS. Je dis bien une fonction, car ce bloc prend en paramètre `arch` qui contient l'architecture cible de notre module. Ainsi, si on lui passe `arm64` on aura un binaire qui fonctionne sur les processeurs ARM 64 bits, si on passe `386`, on aura un binaire pour les vieux PC x86 32 bits, etc. + +Dans les blocs suivants, on raffine donc ce premier module. On va d'abord avoir une fonction qui va extraire le binaire statique du module généré par Go, ensuite une fonction Docker qui va mettre ce binaire statique dans un conteneur. + +Enfin, une fois notre logique définie, on va déclarer quelles architectures on choisit de supporter, là j'en ai choisi 4. On va donc faire une boucle (`mapAttrs`) pour générer le conteneur Docker qui va bien pour chaque architecture. ## Créer les artefacts avec nix build +On peut ensuite créer nos différentes archives Docker, en précisant le chemin de sortie pour s'y retrouver : +```bash +nix build .#packages.x86_64-linux.docker.albatros -o albatros.amd64.tar.gz +nix build .#packages.armv6l-linux.docker.albatros -o albatros.arm.tar.gz +nix build .#packages.aarch64-linux.docker.albatros -o albatros.arm64.tar.gz +nix build .#packages.i686-linux.docker.albatros -o albatros.386.tar.gz +``` +## Construire notre image multi-arch +Dans le monde des conteneurs, une image multiarch est juste une indirection, un fichier qui contient une liste de manifest avec des tags pour leur OS et leur architecture. Il faut donc créer un fichier qui liste le manifest de chacune de nos 4 images. - - - +Problème : aujourd'hui il n'est pas facile de construire un manifest multi-arch sans daemon docker.