Gestion des images avec Crane
Mise à jour :
Les conteneurs ont révolutionné la manière dont nous développons, déployons et gérons nos applications. Les conteneurs sont omniprésents dans nos infrastructures, permettant aux développeurs de créer, tester et exécuter des applications de manière isolée et reproductible. Cependant, à mesure que les projets grandissent en complexité, la gestion des images de conteneurs peut devenir une tâche énergivore. C’est là qu’intervient Crane, un outil puissant qui simplifie la gestion quotidienne des images Docker, vous permettant de maximiser votre efficacité et de gagner du temps précieux.
Installation de Crane
Installation de Crane sur Linux
ASDF-VM est un gestionnaire de versions polyvalent qui peut être utilisé pour installer Crane sur Linux.
asdf plugin add craneasdf install crane latestasdf set --home crane latest
Installation de Crane sur macOS
Si vous utilisez macOS et préférez Homebrew (Brew) pour gérer vos logiciels, voici comment installer Crane :
Ouvrez un terminal et exécutez la commande suivante pour installer Crane
avec brew
:
brew install crane
Vérification de l’Installation de Crane
Une fois l’installation terminée, vérifiez que Crane est correctement installé en exécutant la commande suivante :
crane version0.17.0
Mise en place du lab
Pour expliquer le fonctionnement de Crane, je vais installer une registry local.
docker run -d -p 5000:5000 --name registry registry
Je construis une image simple avec de Dockerfile sans aucune attention particulière :
FROM alpine:3.17RUN apk --no-cache add nginxCOPY index.html /var/www/htmlWORKDIR /var/www/htmlEXPOSE 80
On construit l’image :
docker build . -t localhost:5000/monserveurweb:0.1docker push localhost:5000/monserveurweb:0.1
S’authentifier à une registry
Pour s’identifier sur une registry distante, il faut utiliser la commande auth
:
crane auth login docker.com -u xxx -p "xxxxxxxx"2023/12/29 10:01:39 logged in via /home/bob/.docker/config.json
La Gestion des Images avec Crane
Crane, en tant qu’outil polyvalent, offre une gamme de commandes pour gérer les images de manière avancée. Mais attention, la plupart des commandes s’exécutent directement dans les registries.
Lister les images d’une registry avec catalog
La commande catalog
permet de lister toutes les images d’une registry :
crane catalog localhost:5000monserveurweb
Lister les tags avec ls
La commande ls
permet de lister tous les tags d’une image :
crane ls localhost:5000/monserveurweb0.1
Obtenir des Informations avec manifest
La commande manifest
permet d’obtenir les informations sur une image stockée
dans la registry.
crane manifest localhost:5000/monserveurweb:0.1{ "schemaVersion": 2, "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "config": { "mediaType": "application/vnd.docker.container.image.v1+json", "size": 1476, "digest": "sha256:28865db66a2e444148b37ad85b421ca60cc21e3fd4311290e6015c8650c13002" }, "layers": [ { "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", "size": 2829647, "digest": "sha256:f7dab3ab2d6ec29aa28769bec35331fb485b5837501b1e8556413d8b5a79c9c8" }, { "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", "size": 617439, "digest": "sha256:607cfc754b09e299e9a8aa9bf719e6cc29e202ebe255d0042551f6063dede42e" }, { "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", "size": 210, "digest": "sha256:18ba307d74fbf4e53a45ec11498855ec676eed30fb5f59d4f7f690af627172c4" }, { "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", "size": 32, "digest": "sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1" } ]}
On voit que l’image est composée de plusieurs Layers
Ajout de Metadata avec mutate
La commande mutate
permet de modifier les métadonnées d’une image de
conteneur. Elle permet de changer les labels (étiquettes) et les annotations
d’une image qui est déjà poussée dans un registre.
crane mutate localhost:5000/monserveurweb:0.1 --label "version=0.1"
Aplatir une Image avec flatten
La commande flatten
permet d’optimiser la taille des images de conteneurs.
Cette commande est conçue pour transformer une image composée de multiples
couches en une image à couche unique.
La commande prend toutes les couches d’une image de conteneur – chaque couche représentant une modification ou un ajout au système de fichiers – et les fusionne en une seule couche. Tous les fichiers et configurations présents dans les différentes couches sont conservés, mais ils sont regroupés en une structure de fichier unique.
Supposons que vous avez une image monimage:latest
avec plusieurs couches que
vous souhaitez aplatir pour simplification :
crane flatten localhost:5000/monserveurweb:0.1 -t localhost:5000/monserveurweb:flattened
On vérifie :
crane manifest localhost:5000/monserveurweb:flattened |jq{ "schemaVersion": 2, "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "config": { "mediaType": "application/vnd.docker.container.image.v1+json", "size": 1488, "digest": "sha256:953c8233cddd48fe1af893d7f5ff286c636d38b7c1bce3201d86b50a79505da0" }, "layers": [ { "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", "size": 3429829, "digest": "sha256:5d3c4f6638f699c4db149ffb1d285610f2f0818877d3c4b5363caa3c8f0a8d54" } ]}
Plus qu’un seul layer !
Bien que flatten
puisse réduire la taille de l’image, ce n’est pas toujours le
cas. Parfois, la fusion des couches peut entraîner une image de taille similaire
ou légèrement plus grande.
docker pull localhost:5000/monserveurweb:flattenedflattened: Pulling from monserveurweb5d3c4f6638f6: Pull completeDigest: sha256:e5ef885823e0f76979b15a073ffca5862f68cfffbcb90c8bcdd4c2b251c2e9d8Status: Downloaded newer image for localhost:5000/monserveurweb:flattenedlocalhost:5000/monserveurweb:flattened❯ docker imagesREPOSITORY TAG IMAGE ID CREATED SIZElocalhost:5000/monserveurweb 0.1 28865db66a2e 22 minutes ago 7.05MBlocalhost:5000/monserveurweb flattened 953c8233cddd 22 minutes ago 7.02MB
La taille a diminué légèrement.
Validation d’une Image avec validate
La commande validate
s’assure que l’image est conforme aux normes attendues,
évitant ainsi des problèmes potentiels lors du déploiement.
crane validate --remote localhost:5000/monserveurweb:flattenedPASS: localhost:5000/monserveurweb:flattened
Récupération du SHA256 avec digest
La commande digest
permet de récupérer le SHA256 d’une image.
crane digest localhost:5000/monserveurweb:0.1sha256:beb9fd8064525aa1787d60cfd6eba89c4580125f1e32a42e0ab006912cf48038
Exportation d’une Image avec export
La commande export
permet de télécharger une image et de la stocker dans un
fichier tar
. Cette commande peut être utile pour réaliser des analyses, des
sauvegardes ou des transferts.
crane export localhost:5000/monserveurweb:0.1 test.tar
Obtenir Toutes les Infos avec config
La sécurité est une préoccupation majeure dans la gestion des images de conteneurs. La commande config permet d’obtenir pas mal d’infos au passage :
crane config localhost:5000/monserveurweb:0.1 |jq{ "architecture": "amd64", "created": "2023-12-29T08:37:16.710048222+01:00", "history": [ { "created": "2023-03-29T18:19:37.625607335Z", "created_by": "/bin/sh -c #(nop) ADD file:9663235f252e072c52b0f9e25845841e4321cce2caa7467a0d736c6003b05c00 in / " }, { "created": "2023-03-29T18:19:37.727267748Z", "created_by": "/bin/sh -c #(nop) CMD [\"/bin/sh\"]", "empty_layer": true }, { "created": "2023-12-29T08:35:52.079904952+01:00", "created_by": "RUN /bin/sh -c apk --no-cache add nginx # buildkit", "comment": "buildkit.dockerfile.v0" }, { "created": "2023-12-29T08:37:16.651372094+01:00", "created_by": "COPY index.html /var/www/localhost/htdocs # buildkit", "comment": "buildkit.dockerfile.v0" }, { "created": "2023-12-29T08:37:16.710048222+01:00", "created_by": "WORKDIR /var/www/localhost/htdocs", "comment": "buildkit.dockerfile.v0" }, { "created": "2023-12-29T08:37:16.710048222+01:00", "created_by": "EXPOSE map[80/tcp:{}]", "comment": "buildkit.dockerfile.v0", "empty_layer": true } ], "os": "linux", "rootfs": { "type": "layers", "diff_ids": [ "sha256:9733ccc395133a067f01ee6e380003d80fe9f443673e0f992ae6a4a7860a872c", "sha256:aff9fd0896ef2350fed1acf3dc2cd146e1b262e5362aecec175c5d9d8e1fcaba", "sha256:266c487511e2156e3f32930a7fd2f223b7ed50aee50ab0409ac6debd34eb2874", "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef" ] }, "config": { "Cmd": [ "/bin/sh" ], "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ], "Labels": { "version": "0.1" }, "WorkingDir": "/var/www/localhost/htdocs", "ExposedPorts": { "80/tcp": {} } }}
On voit bien que crane
a ajouté le label version
à l’image.
Supprimer des Images avec delete
La commande delete
permet de supprimer les images obsolètes ou non sécurisées
des registres qui accepte cette opération.
crane ls localhost:5000/monserveurweb0.10.2flattened
crane delete localhost:5000/monserveurweb:0.2Error: DELETE http://localhost:5000/v2/monserveurweb/manifests/0.2: UNSUPPORTED: The operation is unsupported.
Ici ce n’est pas le cas, car le registre local ne supporte la destruction !
Manipulation des Index
La commande index
est utilisée pour manipuler et gérer des index d’images dans
un registre de conteneurs. Un index d’image, parfois appelé manifeste
multi-architecture ou manifeste d’index, est un type de manifeste dans les
systèmes de registre de conteneurs comme Docker. Il permet de référencer
plusieurs images de conteneurs, souvent pour différentes architectures ou
plateformes, sous un seul tag.
Pour créer un index qui regroupe plusieurs images de conteneurs pour différentes architectures :
crane index create monindex:latest --image monimage-amd64:latest --image monimage-arm64:latest
Ici, monindex:latest
deviendra un index qui référence les images
monimage-amd64:latest
et monimage-arm64:latest
.
Pour ajouter ou supprimer des images d’un index existant :
crane index add monindex:latest --image nouvelleimage:latestcrane index remove monindex:latest --image ancienneimage:latest
Copie entre Différente Registries
La commande copy
permet de copier des images entre différentes registries :
crane copy ubuntu:jammy localhost:5000/ubuntu:jammy2023/12/29 10:05:28 Copying from ubuntu:jammy to localhost:5000/ubuntu:jammy2023/12/29 10:05:30 pushed blob: sha256:bcb4f0da36a059c0aa61899290aec075393d2865c1edea112ea81ceaa12d53ae2023/12/29 10:05:30 pushed blob: sha256:ce679385b55913348f173b0d7a11c79a06f61abc95525b7e51f2705dd327fa5d2023/12/29 10:05:30 pushed blob: sha256:da935f0649133cbea2f5ad83db14bf782aa5ee9ad17cd609253e3750201a92982023/12/29 10:05:30 pushed blob: sha256:174c8c134b2a94b5bb0b37d9a2b6ba0663d82d23ebf62bd51f74a2fd457333da2023/12/29 10:05:31 pushed blob: sha256:a486411936734b0d1d201c8a0ed8e9d449a64d5033fdc33411ec95bc26460efb2023/12/29 10:05:31 localhost:5000/ubuntu@sha256:bbf3d1baa208b7649d1d0264ef7d522e1dc0deeeaaf6085bf8e4618867f03494: digest: sha256:bbf3d1baa208b7649d1d0264ef7d522e1dc0deeeaaf6085bf8e4618867f03494 size: 4242023/12/29 10:05:31 pushed blob: sha256:446a5eabbfe22b430a73fb05c818982ff8013141f79a000474d5e0e7e751b52e2023/12/29 10:05:31 pushed blob: sha256:005e2837585d0b391170fd9faf2e0c279d64ba0eb011cda8dedf28cb5839861e2023/12/29 10:05:31 localhost:5000/ubuntu@sha256:ba545858745d6307f0d1064d0d25365466f78d02f866cf4efb9e1326a4c196ca: digest: sha256:ba545858745d6307f0d1064d0d25365466f78d02f866cf4efb9e1326a4c196ca size: 4242023/12/29 10:05:31 pushed blob: sha256:d33cdf8c116214cd1f23278abc2741878af19658bf65c210a48280807622d8712023/12/29 10:05:31 localhost:5000/ubuntu@sha256:c6bd78eb69d21a2266b96a851002324b769483d704df3b73a37f78e6fe767f04: digest: sha256:c6bd78eb69d21a2266b96a851002324b769483d704df3b73a37f78e6fe767f04 size: 4242023/12/29 10:05:31 pushed blob: sha256:8cf433553d1d6625c1509159e9502639154da459bba2d5aadeb708dbe96372302023/12/29 10:05:31 localhost:5000/ubuntu@sha256:a325aa8b607ceefbf215a70887e7bce9c4413e510692087b7cd1be6db8e5191d: digest: sha256:a325aa8b607ceefbf215a70887e7bce9c4413e510692087b7cd1be6db8e5191d size: 4242023/12/29 10:05:31 pushed blob: sha256:6d5f22cb7a5ae76d71ff8d8d5254febad219eb4adbf9b849b5e1d5bd967691cd2023/12/29 10:05:31 localhost:5000/ubuntu@sha256:de1021a5203fe161639721ebfb11d2523c891c3092dd6c239f54995b554cbdc8: digest: sha256:de1021a5203fe161639721ebfb11d2523c891c3092dd6c239f54995b554cbdc8 size: 4242023/12/29 10:05:31 localhost:5000/ubuntu:jammy: digest: sha256:6042500cf4b44023ea1894effe7890666b0c5c7871ed83a97c36c76ae560bb9b size: 1133
On vérifie que l’image a bien été copié
crane catalog localhost:5000monserveurwebubuntu
crane ls localhost:5000/ubuntujammy
On a bien que la version attendue.
Ajouter un Tag à une Image
La commande tag
permet de créer des tags sur une image :
crane tag localhost:5000/ubuntu:jammy latest2023/12/29 10:10:35 existing manifest: sha256:de1021a5203fe161639721ebfb11d2523c891c3092dd6c239f54995b554cbdc82023/12/29 10:10:35 existing manifest: sha256:bbf3d1baa208b7649d1d0264ef7d522e1dc0deeeaaf6085bf8e4618867f034942023/12/29 10:10:35 existing manifest: sha256:c6bd78eb69d21a2266b96a851002324b769483d704df3b73a37f78e6fe767f042023/12/29 10:10:35 existing manifest: sha256:a325aa8b607ceefbf215a70887e7bce9c4413e510692087b7cd1be6db8e5191d2023/12/29 10:10:35 existing manifest: sha256:ba545858745d6307f0d1064d0d25365466f78d02f866cf4efb9e1326a4c196ca2023/12/29 10:10:35 localhost:5000/ubuntu:latest: digest: sha256:6042500cf4b44023ea1894effe7890666b0c5c7871ed83a97c36c76ae560bb9b size: 1133
crane ls localhost:5000/ubuntulatestjammy
Rebase d’une image
Toujours plus fort. La commande rebase
permet de reconstruire une image en
modifiant l’image de base :
crane rebase localhost:5000/monserveurweb:0.1 --old_base alpine:3.14 --new_base alpine:3.19 --tag localhost:5000/monserveurweb:0.3
On vérifie :
docker run localhost:5000/monserveurweb:0.3 cat /etc/os-releaseNAME="Alpine Linux"ID=alpineVERSION_ID=3.19.0PRETTY_NAME="Alpine Linux v3.19"HOME_URL="https://alpinelinux.org/"BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"
Récupération des Blobs d’une image
On peut utiliser la commande blob
pour récupérer un layer en particulier.
On récupère les sha d’une image :
crane manifest localhost:5000/monserveurweb:0.1 | jq
{ "schemaVersion": 2, "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "config": { "mediaType": "application/vnd.docker.container.image.v1+json", "size": 1488, "digest": "sha256:d40cbd089a7a45e15501d5518aa775b204097887639517696e7bd2705e9f6728" }, "layers": [ { "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", "size": 2829647, "digest": "sha256:f7dab3ab2d6ec29aa28769bec35331fb485b5837501b1e8556413d8b5a79c9c8" }, { "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", "size": 617439, "digest": "sha256:607cfc754b09e299e9a8aa9bf719e6cc29e202ebe255d0042551f6063dede42e" }, { "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", "size": 210, "digest": "sha256:18ba307d74fbf4e53a45ec11498855ec676eed30fb5f59d4f7f690af627172c4" }, { "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", "size": 32, "digest": "sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1" } ]}
On récupère le deuxième layer :
crane blob localhost:5000/monserveurweb:0.1@sha256:607cfc754b09e299e9a8aa9bf719e6cc29e202ebe255d0042551f6063dede42e > layer2.tar
On l’importe dans notre docker local :
docker import layer2.tar test:0.1sha256:5edf39486561613a8ebb84424bc14090037fc9d3e35cae41e76dc890aa469f31
docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEtest 0.1 5edf39486561 5 seconds ago 1.44MB
Bien utile pour du debug par exemple.
Intégration dans les Pipelines CI/CD
L’utilisation de Crane dans les pipelines CI/CD assure que la manipulation des images de conteneurs se fait de manière cohérente et automatisée, en respectant les bonnes pratiques de DevOps.
Crane peut-être utilisé par exemple dans des étapes de vos pipelines pour taguer automatiquement les images avec des numéros de version basés sur des tags Git, copier des images de conteneurs entre différentes registries, …
On peut tout imaginer.
Conclusion
En conclusion, Crane s’avère être un outil extrêmement puissant et flexible pour la gestion des images de conteneurs dans divers environnements DevOps. Son intégration dans les processus d’automatisation, notamment les pipelines CI/CD, permet de rationaliser et de sécuriser la manipulation des images de conteneurs. Que ce soit pour des tâches simples comme le transfert d’images entre différents registres ou pour des opérations plus complexes comme l’intégration dans des scripts d’automatisation, Crane offre une solution efficace et fiable.