Aller au contenu principal

Gestion des images avec Crane

logo 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.

Plus d'infos