TP: Builder et pousser des images avec Podman, Buildah et Skopeo
Introduction
Section titled “Introduction”Dans ce TP, vous allez découvrir l’écosystème Podman, une alternative à Docker qui offre plusieurs avantages :
- Podman : Runtime de conteneurs sans daemon, compatible avec Docker
- Buildah : Outil spécialisé pour construire des images de conteneurs
- Skopeo : Outil pour inspecter, copier et transférer des images entre registries
Pourquoi Podman, Buildah et Skopeo ?
Section titled “Pourquoi Podman, Buildah et Skopeo ?”Avantages par rapport à Docker
Section titled “Avantages par rapport à Docker”- Pas de daemon : Podman n’utilise pas de processus daemon central, ce qui améliore la sécurité
- Rootless par défaut : Possibilité d’exécuter des conteneurs sans privilèges root
- Compatible OCI : Respect total des standards Open Container Initiative
- Séparation des responsabilités :
- Podman : Exécution et gestion des conteneurs
- Buildah : Construction d’images optimisée
- Skopeo : Gestion des images dans les registries
- Compatible Docker :
alias docker=podmanfonctionne pour la plupart des commandes
Cas d’usage
Section titled “Cas d’usage”- Environnements sans Docker : Kubernetes natif, certaines distributions Linux
- CI/CD : Builds sans privilèges root
- Sécurité renforcée : Pas de daemon avec privilèges élevés
- Gestion multi-registry : Skopeo facilite la migration d’images entre registries
Partie 1 : Installation de Podman, Buildah et Skopeo
Section titled “Partie 1 : Installation de Podman, Buildah et Skopeo”# Mettre à jour les paquetssudo apt update
# Installer Podman, Buildah et Skopeosudo apt install -y podman buildah skopeo
# Vérifier les installationspodman --versionbuildah --versionskopeo --versionConfiguration initiale de Podman
Section titled “Configuration initiale de Podman”# Créer les répertoires de configuration si nécessairemkdir -p ~/.config/containers
# (Optionnel) Configurer les registriescat << 'EOF' > ~/.config/containers/registries.conf[registries.search]registries = ['docker.io', 'quay.io', 'ghcr.io']EOFPartie 2 : Builder avec Buildah
Section titled “Partie 2 : Builder avec Buildah”Buildah offre plusieurs méthodes pour construire des images. Nous allons voir les deux approches principales.
Méthode 1 : Build depuis un Dockerfile existant
Section titled “Méthode 1 : Build depuis un Dockerfile existant”C’est la méthode la plus simple si vous avez déjà un Dockerfile.
# Se placer dans le dossier du TPcd section_images_dockerfiles/207_podman_buildah_skopeo
# Builder l'image avec Buildahbuildah build -t monsterstack:buildah .
# Alternative : utiliser bud (build using dockerfile)buildah bud -t monsterstack:buildah .
# Lister les imagesbuildah images# oupodman imagesMéthode 2 : Build scriptée (approche native Buildah)
Section titled “Méthode 2 : Build scriptée (approche native Buildah)”Buildah permet de construire des images de manière scriptée, offrant plus de contrôle et de flexibilité.
Créons un script build-with-buildah.sh :
#!/bin/bashset -e
# Créer un conteneur de travail depuis une image de basecontainer=$(buildah from python:3.10)
echo "Container ID: $container"
# Créer l'utilisateur uwsgibuildah run $container groupadd -r uwsgibuildah run $container useradd -r -g uwsgi uwsgi
# Installer les dépendances Pythonbuildah run $container pip install Flask uWSGI requests redis
# Configurer le workdirbuildah config --workingdir /app $container
# Copier les fichiers de l'applicationbuildah copy $container ./app /appbuildah copy $container boot.sh /boot.sh
# Rendre boot.sh exécutablebuildah run $container chmod a+x /boot.sh
# Définir les variables d'environnementbuildah config --env CONTEXT=PROD $containerbuildah config --env IMAGEBACKEND_DOMAIN=imagebackend $containerbuildah config --env REDIS_DOMAIN=redis $container
# Exposer les portsbuildah config --port 5000 --port 9191 $container
# Définir l'utilisateurbuildah config --user uwsgi $container
# Définir la commande par défautbuildah config --cmd '/boot.sh' $container
# Commiter le conteneur en imagebuildah commit $container monsterstack:buildah-scripted
# Nettoyer le conteneur de travailbuildah rm $container
echo "Image built successfully: monsterstack:buildah-scripted"Rendre le script exécutable et l’exécuter :
chmod +x build-with-buildah.sh./build-with-buildah.shComparer les deux méthodes
Section titled “Comparer les deux méthodes”# Lister toutes les imagespodman images
# Comparer les taillespodman images | grep monsterstackInspecter une image
Section titled “Inspecter une image”# Avec Buildahbuildah inspect monsterstack:buildah
# Avec Skopeo (plus détaillé)skopeo inspect containers-storage:localhost/monsterstack:buildahPartie 3 : Pousser des images avec Skopeo
Section titled “Partie 3 : Pousser des images avec Skopeo”Skopeo est un outil puissant pour gérer les images sans avoir besoin de les charger dans le storage local.
Inspecter une image distante
Section titled “Inspecter une image distante”# Inspecter une image sur Docker Hub (sans la télécharger)skopeo inspect docker://docker.io/library/nginx:alpine
# Inspecter notre image localeskopeo inspect containers-storage:localhost/monsterstack:buildahCopier une image vers un registry
Section titled “Copier une image vers un registry”Skopeo peut copier des images entre différents types de storage et registries.
Exemple 1 : Pousser vers Docker Hub
Section titled “Exemple 1 : Pousser vers Docker Hub”# Se connecter au registryskopeo login docker.io
# Copier l'image locale vers Docker Hubskopeo copy \ containers-storage:localhost/monsterstack:buildah \ docker://docker.io/votre-username/monsterstack:v1.0
# Alternative : tagger puis pousserpodman tag monsterstack:buildah docker.io/votre-username/monsterstack:v1.0podman push docker.io/votre-username/monsterstack:v1.0Exemple 2 : Pousser vers GitLab Container Registry
Section titled “Exemple 2 : Pousser vers GitLab Container Registry”# Se connecter au registry GitLabskopeo login registry.gitlab.com
# Copier l'imageskopeo copy \ containers-storage:localhost/monsterstack:buildah \ docker://registry.gitlab.com/votre-username/monsterstack:v1.0Exemple 3 : Copier entre registries (sans téléchargement local)
Section titled “Exemple 3 : Copier entre registries (sans téléchargement local)”# Copier directement de Docker Hub vers GitLab Registryskopeo copy \ docker://docker.io/nginx:alpine \ docker://registry.gitlab.com/votre-username/nginx:alpineGérer les credentials de registry
Section titled “Gérer les credentials de registry”# Voir les registries configuréscat ~/.config/containers/registries.conf
# Lister les authentificationscat ~/.config/containers/auth.json
# Se déconnecterskopeo logout docker.ioPartie 4 : Exécuter avec Podman
Section titled “Partie 4 : Exécuter avec Podman”Podman est compatible avec la plupart des commandes Docker.
Exécuter l’application en mode développement
Section titled “Exécuter l’application en mode développement”# Lancer les services avec podman-compose# Installer podman-compose si nécessairepip3 install --user podman-compose
# Ou utiliser podman directement (comme docker run)podman run -d \ --name monsterstack-frontend \ -p 5000:5000 \ -e CONTEXT=DEV \ -e REDIS_DOMAIN=redis \ -e IMAGEBACKEND_DOMAIN=imagebackend \ monsterstack:buildah
# Lancer Redispodman run -d --name redis redis:alpine
# Lancer le backend d'imagespodman run -d --name imagebackend amouat/dnmonster:1.0
# Créer un réseau et reconnecter les conteneurspodman network create monster_network
# Recréer les conteneurs avec le réseaupodman rm -f monsterstack-frontend redis imagebackend
podman run -d \ --name redis \ --network monster_network \ redis:alpine
podman run -d \ --name imagebackend \ --network monster_network \ amouat/dnmonster:1.0
podman run -d \ --name monsterstack-frontend \ --network monster_network \ -p 5000:5000 \ -e CONTEXT=PROD \ -e REDIS_DOMAIN=redis \ -e IMAGEBACKEND_DOMAIN=imagebackend \ monsterstack:buildahUtiliser Podman Compose
Section titled “Utiliser Podman Compose”Podman supporte docker-compose via podman-compose.
# Utiliser le docker-compose.yml existantpodman-compose up -d
# Voir les logspodman-compose logs -f
# Arrêterpodman-compose downVérifier le fonctionnement
Section titled “Vérifier le fonctionnement”# Tester l'APIcurl http://localhost:5000
# Vérifier les logspodman logs monsterstack-frontend
# Inspecter le conteneurpodman inspect monsterstack-frontend
# Voir les processuspodman top monsterstack-frontendUtiliser Podman en mode rootless
Section titled “Utiliser Podman en mode rootless”Un des avantages majeurs de Podman est le support rootless (sans privilèges root).
# Tout fonctionne sans sudo !podman run -d --name test-nginx -p 8080:80 nginx:alpine
# Voir les conteneurs en tant qu'utilisateur normalpodman ps
# Nettoyerpodman rm -f test-nginxPartie 5 : Workflow complet CI/CD
Section titled “Partie 5 : Workflow complet CI/CD”Voici un exemple de workflow complet utilisant Buildah et Skopeo dans un contexte CI/CD.
Script de build CI/CD
Section titled “Script de build CI/CD”Créons un script ci-build.sh :
#!/bin/bashset -e
# VariablesIMAGE_NAME="monsterstack"REGISTRY="registry.gitlab.com/votre-username"TAG="${CI_COMMIT_SHA:-latest}"
echo "=== Building image with Buildah ==="buildah build -t ${IMAGE_NAME}:${TAG} .
echo "=== Running tests ==="# Lancer les tests unitaires dans un conteneurpodman run --rm \ -v $(pwd)/app:/app:ro \ ${IMAGE_NAME}:${TAG} \ python3 -m pytest /app/tests/unit.py || true
echo "=== Pushing image with Skopeo ==="# Pousser vers le registryskopeo copy \ --dest-creds=${REGISTRY_USER}:${REGISTRY_PASSWORD} \ containers-storage:localhost/${IMAGE_NAME}:${TAG} \ docker://${REGISTRY}/${IMAGE_NAME}:${TAG}
echo "=== Tagging as latest ==="# Tagger aussi comme 'latest'skopeo copy \ --dest-creds=${REGISTRY_USER}:${REGISTRY_PASSWORD} \ containers-storage:localhost/${IMAGE_NAME}:${TAG} \ docker://${REGISTRY}/${IMAGE_NAME}:latest
echo "=== Build and push complete ==="Exemple de pipeline GitLab CI
Section titled “Exemple de pipeline GitLab CI”Créons un fichier .gitlab-ci-podman.yml :
stages: - build - test - push
variables: IMAGE_NAME: monsterstack IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
build-with-buildah: stage: build image: quay.io/buildah/stable:latest script: - buildah build -t $IMAGE_NAME:$CI_COMMIT_SHORT_SHA . - buildah push $IMAGE_NAME:$CI_COMMIT_SHORT_SHA oci-archive:image.tar artifacts: paths: - image.tar expire_in: 1 hour
test-image: stage: test image: quay.io/podman/stable:latest dependencies: - build-with-buildah script: - podman load -i image.tar - podman run --rm $IMAGE_NAME:$CI_COMMIT_SHORT_SHA python3 -m pytest /app/tests/unit.py || true
push-with-skopeo: stage: push image: quay.io/skopeo/stable:latest dependencies: - build-with-buildah before_script: - skopeo login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY script: # Charger l'image depuis l'archive OCI - skopeo copy oci-archive:image.tar docker://$IMAGE_TAG - skopeo copy oci-archive:image.tar docker://$CI_REGISTRY_IMAGE:latest only: - mainPartie 6 : Commandes utiles et comparaison
Section titled “Partie 6 : Commandes utiles et comparaison”Tableau de comparaison Docker vs Podman
Section titled “Tableau de comparaison Docker vs Podman”| Opération | Docker | Podman |
|---|---|---|
| Lancer un conteneur | docker run | podman run |
| Lister les conteneurs | docker ps | podman ps |
| Builder une image | docker build | buildah build ou podman build |
| Pousser une image | docker push | podman push ou skopeo copy |
| Inspecter une image | docker inspect | podman inspect ou skopeo inspect |
| Copier entre registries | ❌ | skopeo copy |
| Exécuter sans root | ⚠️ Limité | ✅ Natif |
Alias pour transition Docker → Podman
Section titled “Alias pour transition Docker → Podman”# Ajouter dans ~/.bashrc ou ~/.zshrcalias docker=podmanalias docker-compose=podman-compose
# Recharger le shellsource ~/.bashrcCommandes Buildah utiles
Section titled “Commandes Buildah utiles”# Lister les conteneurs de travailbuildah containers
# Lister les imagesbuildah images
# Supprimer une imagebuildah rmi monsterstack:buildah
# Nettoyer toutbuildah rm --allbuildah rmi --allCommandes Skopeo utiles
Section titled “Commandes Skopeo utiles”# Inspecter sans téléchargerskopeo inspect docker://nginx:alpine
# Lister les tags d'une imageskopeo list-tags docker://docker.io/library/nginx
# Copier depuis un registry vers un fichier tarskopeo copy docker://nginx:alpine docker-archive:nginx.tar
# Supprimer une image distante (si permissions)skopeo delete docker://registry.example.com/monsterstack:oldQuestions de réflexion
Section titled “Questions de réflexion”-
Pourquoi Buildah et Podman sont-ils séparés ?
- Séparation des responsabilités : build vs runtime
- Permet d’optimiser chaque outil pour sa tâche
- Possibilité d’utiliser Buildah dans des environnements sans Podman
-
Quels sont les avantages du mode rootless ?
- Sécurité accrue : pas de daemon root
- Isolation utilisateur : chaque utilisateur a son propre espace
- Conformité : certaines réglementations interdisent l’exécution en root
-
Quand utiliser Skopeo plutôt que
podman push?- Copie directe entre registries (sans local)
- Inspection d’images distantes
- Scripts CI/CD où Podman n’est pas installé
- Gestion de signatures d’images
-
Podman peut-il totalement remplacer Docker ?
- Pour la plupart des cas : oui
- Limitations : Docker Swarm non supporté (utiliser Kubernetes)
- Écosystème Docker (Desktop, extensions) non équivalent
Nettoyage
Section titled “Nettoyage”# Arrêter tous les conteneurspodman stop -a
# Supprimer tous les conteneurspodman rm -a
# Supprimer toutes les imagespodman rmi -a
# Nettoyer le système completpodman system prune -a --volumes
# Nettoyer Buildahbuildah rm --allbuildah rmi --allConclusion
Section titled “Conclusion”Vous avez maintenant découvert l’écosystème Podman :
✅ Buildah : Construction d’images flexible et scriptable ✅ Skopeo : Gestion d’images multi-registry sans daemon ✅ Podman : Runtime de conteneurs compatible Docker et rootless
Cas d’usage recommandés
Section titled “Cas d’usage recommandés”- CI/CD : Buildah pour builds sans privilèges
- Gestion multi-registry : Skopeo pour copier/migrer des images
- Environnements restreints : Podman en mode rootless
- Kubernetes natif : Podman génère des manifests Kubernetes
Pour aller plus loin
Section titled “Pour aller plus loin”- Podman Desktop : Interface graphique alternative à Docker Desktop
- Quadlets : Systemd units pour gérer des conteneurs Podman
- Podman pods : Groupes de conteneurs (équivalent Kubernetes pods)
- Buildah + multistage : Builds optimisés complexes