C.3 · Construire et distribuer des images
Podman : des conteneurs sans démon et sans root
Leçon théorique · questionnaire de validation · gratuit, dans le navigateur
Podman fait la même chose que Docker, avec presque les mêmes commandes, mais sans démon et sans root. Il est l'outil par défaut sur Red Hat Enterprise Linux, Fedora et leurs dérivés, et il apporte une notion directement inspirée de Kubernetes : le pod. Cette leçon est théorique : votre machine de lab n'a pas de moteur de conteneurs.
Ce que vous saurez à la fin : expliquer ce que change l'absence de démon et l'exécution sans root, utiliser Podman comme Docker, regrouper des conteneurs dans un pod, générer du YAML Kubernetes, et faire tourner un conteneur comme un service avec systemd (Quadlet).
1. Sans démon
Avec Docker, la commande docker parle à un démon (dockerd) qui tourne en root et lance les conteneurs. Avec Podman, la commande lance elle-même le conteneur (via conmon et un runtime comme crun) : pas de service central.
| Docker | Podman | |
|---|---|---|
| Démon | dockerd, en root |
aucun |
| Si le démon tombe | tous les conteneurs sont concernés | sans objet |
| Conteneurs d'un utilisateur | lancés par le démon root | appartiennent à l'utilisateur |
2. Sans root (rootless)
Un utilisateur ordinaire lance ses conteneurs sans aucun privilège. Grâce aux espaces de noms utilisateur, il est « root » dans le conteneur, mais ce root correspond à son propre compte (et à une plage d'identifiants qui lui est réservée, /etc/subuid) sur la machine. Un attaquant qui s'échappe du conteneur n'obtient que les droits de cet utilisateur.
Limites à connaître : un utilisateur ne peut pas publier les ports inférieurs à 1024 par défaut, et le réseau passe par une couche en espace utilisateur (pasta ou slirp4netns), un peu moins performante.
3. Les mêmes commandes
podman run -d --name web -p 8080:8080 docker.io/nginxinc/nginx-unprivileged:1.27-alpine
podman ps ; podman logs web ; podman exec -it web sh
podman build -t api:1.0 . # lit les Dockerfile (ou Containerfile)
alias docker=podman # suffit dans la plupart des cas
Bonne habitude : écrire le nom complet des images (docker.io/library/nginx). Podman demande sinon dans quel registre chercher (/etc/containers/registries.conf), ce qui évite de tirer par erreur une image homonyme d'un registre inconnu.
4. Les pods
Comme dans Kubernetes, un pod Podman regroupe des conteneurs qui partagent le réseau (ils se joignent par localhost) :
podman pod create --name appli -p 8080:8080
podman run -d --pod appli --name base -e POSTGRES_PASSWORD=exemple docker.io/library/postgres:17
podman run -d --pod appli --name api mon-api:1.0
podman pod ps
Et le pont vers Kubernetes :
podman kube generate appli > appli.yaml # produit le YAML Kubernetes du pod
podman kube play appli.yaml # et l'inverse : lance un YAML Kubernetes avec Podman
5. Un conteneur comme un service : Quadlet
Pour qu'un conteneur démarre avec la machine et soit supervisé, Podman s'intègre à systemd (leçon L.9) avec Quadlet : un petit fichier décrit le conteneur, systemd génère le service.
# ~/.config/containers/systemd/web.container (ou /etc/containers/systemd/ pour root)
[Container]
Image=docker.io/nginxinc/nginx-unprivileged:1.27-alpine
PublishPort=8080:8080
AutoUpdate=registry
[Install]
WantedBy=default.target
systemctl --user daemon-reload
systemctl --user start web
AutoUpdate=registry permet à podman auto-update de tirer la nouvelle version d'une image et de redémarrer le service.
6. Quand choisir Podman ?
Sur les distributions Red Hat (c'est l'outil fourni), sur les machines partagées où l'on ne veut pas donner l'équivalent de root aux utilisateurs, et partout où l'on veut éviter un démon privilégié. Pour Kubernetes, rien ne change : les images sont au format standard OCI, construites par l'un ou l'autre, et exécutées par containerd ou CRI-O.
Validez la leçon avec le questionnaire.