Gestion des images avec Crane
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 crane
asdf install crane latest
asdf global 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 version
0.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.17
RUN apk --no-cache add nginx
COPY index.html /var/www/html
WORKDIR /var/www/html
EXPOSE 80
On construit l'image :
docker build . -t localhost:5000/monserveurweb:0.1
docker 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:5000
monserveurweb
Lister les tags avec ls
La commande ls
permet de lister tous les tags d'une image :
crane ls localhost:5000/monserveurweb
0.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:flattened
flattened: Pulling from monserveurweb
5d3c4f6638f6: Pull complete
Digest: sha256:e5ef885823e0f76979b15a073ffca5862f68cfffbcb90c8bcdd4c2b251c2e9d8
Status: Downloaded newer image for localhost:5000/monserveurweb:flattened
localhost:5000/monserveurweb:flattened
❯ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost:5000/monserveurweb 0.1 28865db66a2e 22 minutes ago 7.05MB
localhost: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:flattened
PASS: 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.1
sha256: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/monserveurweb
0.1
0.2
flattened
crane delete localhost:5000/monserveurweb:0.2
Error: 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:latest
crane 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:jammy
2023/12/29 10:05:28 Copying from ubuntu:jammy to localhost:5000/ubuntu:jammy
2023/12/29 10:05:30 pushed blob: sha256:bcb4f0da36a059c0aa61899290aec075393d2865c1edea112ea81ceaa12d53ae
2023/12/29 10:05:30 pushed blob: sha256:ce679385b55913348f173b0d7a11c79a06f61abc95525b7e51f2705dd327fa5d
2023/12/29 10:05:30 pushed blob: sha256:da935f0649133cbea2f5ad83db14bf782aa5ee9ad17cd609253e3750201a9298
2023/12/29 10:05:30 pushed blob: sha256:174c8c134b2a94b5bb0b37d9a2b6ba0663d82d23ebf62bd51f74a2fd457333da
2023/12/29 10:05:31 pushed blob: sha256:a486411936734b0d1d201c8a0ed8e9d449a64d5033fdc33411ec95bc26460efb
2023/12/29 10:05:31 localhost:5000/ubuntu@sha256:bbf3d1baa208b7649d1d0264ef7d522e1dc0deeeaaf6085bf8e4618867f03494: digest: sha256:bbf3d1baa208b7649d1d0264ef7d522e1dc0deeeaaf6085bf8e4618867f03494 size: 424
2023/12/29 10:05:31 pushed blob: sha256:446a5eabbfe22b430a73fb05c818982ff8013141f79a000474d5e0e7e751b52e
2023/12/29 10:05:31 pushed blob: sha256:005e2837585d0b391170fd9faf2e0c279d64ba0eb011cda8dedf28cb5839861e
2023/12/29 10:05:31 localhost:5000/ubuntu@sha256:ba545858745d6307f0d1064d0d25365466f78d02f866cf4efb9e1326a4c196ca: digest: sha256:ba545858745d6307f0d1064d0d25365466f78d02f866cf4efb9e1326a4c196ca size: 424
2023/12/29 10:05:31 pushed blob: sha256:d33cdf8c116214cd1f23278abc2741878af19658bf65c210a48280807622d871
2023/12/29 10:05:31 localhost:5000/ubuntu@sha256:c6bd78eb69d21a2266b96a851002324b769483d704df3b73a37f78e6fe767f04: digest: sha256:c6bd78eb69d21a2266b96a851002324b769483d704df3b73a37f78e6fe767f04 size: 424
2023/12/29 10:05:31 pushed blob: sha256:8cf433553d1d6625c1509159e9502639154da459bba2d5aadeb708dbe9637230
2023/12/29 10:05:31 localhost:5000/ubuntu@sha256:a325aa8b607ceefbf215a70887e7bce9c4413e510692087b7cd1be6db8e5191d: digest: sha256:a325aa8b607ceefbf215a70887e7bce9c4413e510692087b7cd1be6db8e5191d size: 424
2023/12/29 10:05:31 pushed blob: sha256:6d5f22cb7a5ae76d71ff8d8d5254febad219eb4adbf9b849b5e1d5bd967691cd
2023/12/29 10:05:31 localhost:5000/ubuntu@sha256:de1021a5203fe161639721ebfb11d2523c891c3092dd6c239f54995b554cbdc8: digest: sha256:de1021a5203fe161639721ebfb11d2523c891c3092dd6c239f54995b554cbdc8 size: 424
2023/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:5000
monserveurweb
ubuntu
crane ls localhost:5000/ubuntu
jammy
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 latest
2023/12/29 10:10:35 existing manifest: sha256:de1021a5203fe161639721ebfb11d2523c891c3092dd6c239f54995b554cbdc8
2023/12/29 10:10:35 existing manifest: sha256:bbf3d1baa208b7649d1d0264ef7d522e1dc0deeeaaf6085bf8e4618867f03494
2023/12/29 10:10:35 existing manifest: sha256:c6bd78eb69d21a2266b96a851002324b769483d704df3b73a37f78e6fe767f04
2023/12/29 10:10:35 existing manifest: sha256:a325aa8b607ceefbf215a70887e7bce9c4413e510692087b7cd1be6db8e5191d
2023/12/29 10:10:35 existing manifest: sha256:ba545858745d6307f0d1064d0d25365466f78d02f866cf4efb9e1326a4c196ca
2023/12/29 10:10:35 localhost:5000/ubuntu:latest: digest: sha256:6042500cf4b44023ea1894effe7890666b0c5c7871ed83a97c36c76ae560bb9b size: 1133
crane ls localhost:5000/ubuntu
latest
jammy
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-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.19.0
PRETTY_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.1
sha256:5edf39486561613a8ebb84424bc14090037fc9d3e35cae41e76dc890aa469f31
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test 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.