Aller au contenu principal

Podman le moteur de conteneur alternatif à Docker

Podman est présenté comme une alternative pertinente à Docker, offrant une expérience utilisateur similaire tout en éliminant certains des défis de sécurité que pose le démon Docker tournant avec les privilèges root. Voyons cela ensemble.

Introduction

Podman, pour POD manager, est un outil Open Source qui sert à construire et exécuter des images de conteneurs. Podman est développé par la société Red Hat et des membres de la communauté.

Contrairement à Docker qui fonctionne sur une architecture client-serveur nécessitant un démon, Podman adopte une approche daemonless. Cela signifie que chaque action exécutée est un processus indépendant et non vient un démon, ce qui améliore la sécurité et simplifie la gestion des conteneurs.

Une autre des caractéristiques notables de Podman est sa capacité à exécuter des conteneurs sans nécessiter les privilèges root, offrant ainsi une sécurité accrue.

Podman est conçu pour être compatible avec Docker, ce qui facilite la transition pour ceux qui sont déjà familiarisés avec Docker. Les images Docker peuvent être exécutées sans aucune modification et les commandes de la cli Podman sont très similaires à celles de Docker, rendant le passage de Docker à Podman facile.

C'est quoi un pod pour Podman ?

Un Pod dans Podman est un concept emprunté à Kubernetes. Un pod Podman est composé d'un ou plusieurs conteneurs, qui sont regroupés dans un espace de noms, un réseau et un contexte de sécurité uniques.

Installation de Podman

Podman est peut-être installé sur des serveurs tournant sous Linux, MacOS et Windows.

Je me limiterai ici à décrire **l'installation d'une version récente de Podman sur une distribution Ubuntu :

sudo mkdir -p /etc/apt/keyrings
curl -fsSL "https://download.opensuse.org/repositories/devel:kubic:libconteneurs:unstable/xUbuntu_$(lsb_release -rs)/Release.key" \
  | gpg --dearmor \
  | sudo tee /etc/apt/keyrings/devel_kubic_libconteneurs_unstable.gpg > /dev/null
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/devel_kubic_libconteneurs_unstable.gpg]\
    https://download.opensuse.org/repositories/devel:kubic:libconteneurs:unstable/xUbuntu_$(lsb_release -rs)/ /" \
  | sudo tee /etc/apt/sources.list.d/devel:kubic:libconteneurs:unstable.list > /dev/null
sudo apt update -qq
sudo apt -qq -y install podman

Pour les autres distributions la documentation se trouve ici.

Vérification de l'installation de Podman

Il suffit de lancer la commande suivante :

podman --version
podman version 4.6.2

Commandes de base de Podman

remarque

Toutes les commandes lancées dans cette documentation sont faites avec un compte n'ayant pas de privilèges root !

Comme dis plus haut, La cli de Podman est très très proche de celles de Docker. Donc ceux qui connaissent Docker peuvent passer à la section sur la gestion des Pods.

Création d'une image

La création des images est gérée par Buildah qui est intégré comme l'est BuildKit dans Docker. La commande build de Podman permet de construire des images.

Je ne vais re-documenter cette partie, car elle est déjà disponible [ici]((/docs/conteneurs/images-conteneurs/build/buildah/).

Gestion des images

Rechercher des images dans les registry

Pour trouver des images dans la plupart des registry, on utilise la commande search :

podman search alpine
NAME                                                        DESCRIPTION
docker.io/library/alpine                                    A minimal Docker image based on Alpine Linux...
docker.io/alpinelinux/docker-cli                            Simple and lightweight Alpine Linux image wi...
docker.io/alpinelinux/alpine-gitlab-ci                      Build Alpine Linux packages with Gitlab CI
docker.io/alpinelinux/gitlab-runner-helper                  Helper image conteneur gitlab-runner-helper...
docker.io/alpinelinux/rsyncd
docker.io/alpinelinux/alpine-drone-ci                       Build Alpine Linux packages with drone CI
docker.io/alpinelinux/unbound...

Pour obtenir la liste des images officielles, on ajoute l'option --filter is-official :

podman search --filter is-official alpine
NAME                      DESCRIPTION
docker.io/library/alpine  A minimal Docker image based on Alpine Linux...

Pour obtenir la liste des tags disponibles, on ajoute l'option --list-tags :

podman search --list-tags --limit 10 docker.io/library/alpine
NAME                      TAG
...
NAME                      TAG
docker.io/library/alpine  2.6
docker.io/library/alpine  2.7
docker.io/library/alpine  20190228
docker.io/library/alpine  20190408
docker.io/library/alpine  20190508
docker.io/library/alpine  20190707
docker.io/library/alpine  20190809
docker.io/library/alpine  20190925
docker.io/library/alpine  20191114
docker.io/library/alpine  20191219
...
astuce

Pour retrouver les dernières images alpines avec podman :

podman search --list-tags --limit 1000 docker.io/library/alpine | grep '[3]\.1[0-9].*' | sort  | tail -n 10
docker.io/library/alpine  3.17.1
docker.io/library/alpine  3.17.2
docker.io/library/alpine  3.17.3
docker.io/library/alpine  3.17.4
docker.io/library/alpine  3.17.5
docker.io/library/alpine  3.18
docker.io/library/alpine  3.18.0
docker.io/library/alpine  3.18.2
docker.io/library/alpine  3.18.3
docker.io/library/alpine  3.18.4

Télécharger une image

Pour télécharger l’image Ubuntu possédant le tag 3.18.4 depuis le Docker Hub, on utilise la commande pull :

podman pull docker.io/library/alpine:3.18.4
Trying to pull docker.io/library/alpine:3.18.4...
Getting image source signatures
Copying blob 96526aa774ef skipped: already exists
Copying config 8ca4688f4f done
Writing manifest to image destination
8ca4688f4f356596b5ae539337c9941abc78eda10021d35cbc52659c74d9b443

Lister les images

Pour afficher toutes les images disponibles localement, on utilise la commande images :

podman images
REPOSITORY                TAG         IMAGE ID      CREATED      SIZE
docker.io/library/ubuntu  jammy       e4c58958181a  3 weeks ago  80.4 MB
docker.io/library/alpine  3.18        8ca4688f4f35  4 weeks ago  7.63 MB
docker.io/library/alpine  3.18.4      8ca4688f4f35  4 weeks ago  7.63 MB

Obtenir des informations sur une image

On utilisera la commande image inspect :

podman image inspect docker.io/library/alpine:3.18
[
     {
          "Id": "8ca4688f4f356596b5ae539337c9941abc78eda10021d35cbc52659c74d9b443",
          "Digest": "sha256:eece025e432126ce23f223450a0326fbebde39cdf496a85d8c016293fc851978",
          "RepoTags": [
               "docker.io/library/alpine:3.18",
               "docker.io/library/alpine:3.18.4"
          ],
          "RepoDigests": [
               "docker.io/library/alpine@sha256:48d9183eb12a05c99bcc0bf44a003607b8e941e1d4f41f9ad12bdcc4b5672f86",
               "docker.io/library/alpine@sha256:eece025e432126ce23f223450a0326fbebde39cdf496a85d8c016293fc851978"
          ],
          "Parent": "",
          "Comment": "",
          "Created": "2023-09-28T21:19:27.801479409Z",
          "Config": {
               "Env": [
                    "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
               ],
               "Cmd": [
                    "/bin/sh"
               ]
          },
          "Version": "20.10.23",
          "Author": "",
          "Architecture": "amd64",
          "Os": "linux",
          "Size": 7629894,
          "VirtualSize": 7629894,
          "GraphDriver": {
               "Name": "overlay",
               "Data": {
                    "UpperDir": "/home/bob/.local/share/conteneurs/storage/overlay/cc2447e1835a40530975ab80bb1f872fbab0f2a0faecf2ab16fbbb89b3589438/diff",
                    "WorkDir": "/home/bob/.local/share/conteneurs/storage/overlay/cc2447e1835a40530975ab80bb1f872fbab0f2a0faecf2ab16fbbb89b3589438/work"
               }
          },
          "RootFS": {
               "Type": "layers",
               "Layers": [
                    "sha256:cc2447e1835a40530975ab80bb1f872fbab0f2a0faecf2ab16fbbb89b3589438"
               ]
          },
          "Labels": null,
          "Annotations": {},
          "ManifestType": "application/vnd.docker.distribution.manifest.v2+json",
          "User": "",
          "History": [
               {
                    "created": "2023-09-28T21:19:27.686110063Z",
                    "created_by": "/bin/sh -c #(nop) ADD file:756183bba9c7f4593c2b216e98e4208b9163c4c962ea0837ef88bd917609d001 in / "
               },
               {
                    "created": "2023-09-28T21:19:27.801479409Z",
                    "created_by": "/bin/sh -c #(nop)  CMD [\"/bin/sh\"]",
                    "empty_layer": true
               }
          ],
          "NamesHistory": [
               "docker.io/library/alpine:3.18.4",
               "docker.io/library/alpine:3.18"
          ]
     }
]

Détruire des images

Pour détruire les images locales, on utilise la commande rmi :

podman rmi docker.io/library/alpine:3.18

Gestion des conteneurs

Lancer une image de conteneur

Pour lancer par exemple une image de conteneur alpine on utilise la commande run :

podman run alpine:3.18.4

Il ne se passe rien, c'est normal ! Notre image ne possède pas d'instruction CMD ou ENTRYPOINT.

Lancer le conteneur en mode interactif

Pour lancer une exécution interactive, c'est-à-dire qu'on se retrouve avec l'invite de commande du conteneur, on utilise l'option -it :

podman run -it alpine:3.18.4 sh
/ # cat /etc/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.18.4
PRETTY_NAME="Alpine Linux v3.18"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"
/ # exit

Pour sortir, il suffit soit de taper la commande exit ou la séquence de touche [CTRL] + [D].

Le mode interactif est très utile dans les phases de construction des images ainsi que dans celui du DEBUG.

Lancer le conteneur en tâche de fond

Pour lancer une image de conteneur en tache de fond, il faut utiliser l'option -dt. Pour cela, nous aurons besoin d'un conteneur httpd :

podman search --filter is-official httpd
NAME                     DESCRIPTION
docker.io/library/httpd  The Apache HTTP Server Project

Maintenant lançons le en exposant le port 80 :

podman run -dt -p 8080:80/tcp docker.io/library/httpd:2.4.58-alpine3.18

Testons :

curl http://localhost:8080
<html><body><h1>It works!</h1></body></html>

Ça fonctionne.

Nommer votre conteneur

Pour fixer le nom, il faut ajouter l'option --name :

podman run --name my-httpd -dt -p 8080:80/tcp docker.io/library/httpd:2.4.58-alpine3.18

Lister les conteneurs en cours d'exécution

Pour lister les conteneurs en cours, il faut utiliser commande ps :

podman ps
conteneur ID  IMAGE                                      COMMAND           CREATED         STATUS         PORTS                 NAMES
92c251fdfae8  docker.io/library/httpd:2.4.58-alpine3.18  httpd-foreground  12 seconds ago  Up 12 seconds  0.0.0.0:8080->80/tcp  my-httpd

Stopper/Démarrer un conteneur

Pour stopper un conteneur, il faut utiliser commande stop :

podman stop my-httpd
my-httpd

Vérifions :

podman ps
conteneur ID  IMAGE       COMMAND     CREATED     STATUS      PORTS       NAMES

Pour vérifier que notre conteneur juste stoppé, il faut utiliser l'option -a à la commande ps :

podman  ps -a
conteneur ID  IMAGE                                      COMMAND           CREATED         STATUS                     PORTS                 NAMES
36d9f97def24  docker.io/library/alpine:3.18.4            /bin/sh           2 hours ago     Exited (0) 2 hours ago                           epic_lichterman
22cb6ad44fae  docker.io/library/alpine:3.18.4            /bin/sh           2 hours ago     Exited (0) 2 hours ago                           strange_borg
9a537d03e575  docker.io/library/alpine:3.18.4            sh                2 hours ago     Exited (127) 2 hours ago                         sad_keller
f1276c998d63  docker.io/library/httpd:2.4.58-alpine3.18  httpd-foreground  19 minutes ago  Exited (0) 13 minutes ago  0.0.0.0:8080->80/tcp  sharp_carson
77515a5ecd1c  docker.io/library/httpd:2.4.58-alpine3.18  httpd-foreground  13 minutes ago  Exited (0) 12 minutes ago  0.0.0.0:8080->80/tcp  thirsty_kirch
92c251fdfae8  docker.io/library/httpd:2.4.58-alpine3.18  httpd-foreground  8 minutes ago   Exited (0) 2 minutes ago   0.0.0.0:8080->80/tcp  my-httpd

Relançons le conteneur my-httpd :

podman start my-httpd
podman ps
conteneur ID  IMAGE                                      COMMAND           CREATED         STATUS        PORTS                 NAMES
92c251fdfae8  docker.io/library/httpd:2.4.58-alpine3.18  httpd-foreground  11 minutes ago  Up 3 seconds  0.0.0.0:8080->80/tcp  my-httpd

Afficher les logs d'un conteneur

Pour afficher les logs du conteneur, on utilise la commande logs :

curl http://localhost:8080
<html><body><h1>It works!</h1></body></html>

podman logs my-httpd
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.0.2.100. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.0.2.100. Set the 'ServerName' directive globally to suppress this message
[Mon Oct 30 12:24:55.305997 2023] [mpm_event:notice] [pid 1:tid 140152919587656] AH00489: Apache/2.4.58 (Unix) configured -- resuming normal operations
[Mon Oct 30 12:24:55.306229 2023] [core:notice] [pid 1:tid 140152919587656] AH00094: Command line: 'httpd -D FOREGROUND'
[Mon Oct 30 12:30:28.407362 2023] [mpm_event:notice] [pid 1:tid 140152919587656] AH00492: caught SIGWINCH, shutting down gracefully
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.0.2.100. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.0.2.100. Set the 'ServerName' directive globally to suppress this message
[Mon Oct 30 12:36:14.377993 2023] [mpm_event:notice] [pid 1:tid 139817935989576] AH00489: Apache/2.4.58 (Unix) configured -- resuming normal operations
[Mon Oct 30 12:36:14.378099 2023] [core:notice] [pid 1:tid 139817935989576] AH00094: Command line: 'httpd -D FOREGROUND'
10.0.2.100 - - [30/Oct/2023:12:40:34 +0000] "GET / HTTP/1.1" 200 45

Se connecter à un conteneur en cours d'exécution

Pour se connecter à un conteneur tournant en tache de fond :

podman exec -it my_httpd sh

Détruire un conteneur

Pour détruire un conteneur, il faut utiliser la commande rm :

podman rm my-httpd
Error: cannot remove conteneur 92c251fdfae828c9cfaefea19e3bb7f858ca146c3e06159cf33e7a7035fb7d54 as it is running - running or paused conteneurs cannot be removed without force: conteneur state improper

Cela n'a pas fonctionné, car le conteneur est en cours d'utilisation. Pour forcer la destruction, il faut ajouter l'option -f :

> podman rm -f my-httpd
my-httpd
>
> podman ps
conteneur ID  IMAGE       COMMAND     CREATED     STATUS      PORTS       NAMES
> podman ps -a
conteneur ID  IMAGE                                      COMMAND           CREATED         STATUS                     PORTS                 NAMES
36d9f97def24  docker.io/library/alpine:3.18.4            /bin/sh           2 hours ago     Exited (0) 2 hours ago                           epic_lichterman
22cb6ad44fae  docker.io/library/alpine:3.18.4            /bin/sh           2 hours ago     Exited (0) 2 hours ago                           strange_borg
9a537d03e575  docker.io/library/alpine:3.18.4            sh                2 hours ago     Exited (127) 2 hours ago                         sad_keller
f1276c998d63  docker.io/library/httpd:2.4.58-alpine3.18  httpd-foreground  31 minutes ago  Exited (0) 25 minutes ago  0.0.0.0:8080->80/tcp  sharp_carson
77515a5ecd1c  docker.io/library/httpd:2.4.58-alpine3.18  httpd-foreground  25 minutes ago  Exited (0) 24 minutes ago  0.0.0.0:8080->80/tcp  thirsty_kirch

Faire le ménage

Attention, Podman comme Docker utilise pas mal d'espace disque. Heureusement, nous avons des commandes pour contrôler l'évolution de l'utilisation de l'espace disque. À commencer par la commande system ps.

podman system df
TYPE           TOTAL       ACTIVE      SIZE        RECLAIMABLE
Images         4           2           142.5MB     72.73MB (51%)
conteneurs     5           0           58.02kB     58.02kB (100%)
Local Volumes  0           0           0B          0B (0%)

Pour faire de la place, on utilise la commande system prune :

podman system prune
WARNING! This command removes:
        - all stopped conteneurs
        - all networks not used by at least one conteneur
        - all dangling images
        - all dangling build cache

Are you sure you want to continue? [y/N] y
Deleted conteneurs
22cb6ad44fae9cdbfa4a13ace7d0ceab874784daef4293238c1531e0b2e81777
36d9f97def247f6d18b01fb3febc415ac4b10ac627fdfefddd685aecfde04841
77515a5ecd1cd4108b27cab2ddc019fa50f2e424eb5d6bbd92fd89b9809eb85f
9a537d03e5757db86075431343a467d54781ffe9b61259159f80b2979e79f188
f1276c998d632a083a01f3efaa901b4da8348467f2fbe03d29bd8a2aaecea83c
Total reclaimed space: 58.02kB
podman system df
TYPE           TOTAL       ACTIVE      SIZE        RECLAIMABLE
Images         4           2           142.5MB     72.73MB (51%)
conteneurs     0           0           0B          0B (0%)
Local Volumes  0           0           0B          0B (0%)

Gestion des Pods sous Podman

Pour rappel, les pods sont des groupes de conteneurs qui partagent des ressources. Les pods Podman sont la fonctionnalité qui distingue Podman de Docker. Pour gérer les pods, il faut utiliser la commande podman pod.

Créer un pod

Pour créer un pod, il faut utiliser la commande create auquel on ajoute l'option --name pour le nommer :

podman pod create --name myFirstPod -p 8080:80
00f19ca19416163b0a0b393a8697821e5d1e6c99ead0182f62a7c01fe2290d4f

L'exposition des ports se fait au niveau du pod et non du conteneur.

Attacher un conteneur à un pod

Pour attacher un conteneur à un pod, il faut, au moment du lancement du conteneur, ajouter l'option --pod :

podman run --pod myFirstPod --name my-hhtpd -dt docker.io/library/httpd:2.4.58-alpine3.18

Testons :

curl http://localhost:8080

<html><body><h1>It works!</h1></body></html>

Cela fonctionne.

Les autres commandes

Les autres commandes sont identiques que celles utilisées pour la gestion des conteneurs.

Lister les pods

Pour lister les pods en cours, on utilise la commande ls :

podman pod ls
POD ID        NAME        STATUS      CREATED         INFRA ID      # OF conteneurS
00f19ca19416  myFirstPod  Created     37 seconds ago  990508ed24d5  1

Problèmes courants

Podman est conçu pour être exécuté sans privilèges root. Cependant, certaines configurations peuvent nécessiter des ajustements pour fonctionner correctement sans privilèges root.

Des problèmes peuvent survenir lors de la configuration des réseaux de conteneurs. Il peut être nécessaire de configurer manuellement les réseaux ou de s’assurer que certaines règles de pare-feu sont correctement configurées.

Bien que Podman soit compatible avec les commandes et les images Docker, il peut y avoir des cas où des ajustements sont nécessaires pour faire fonctionner certaines images Docker sans modifications.

Conclusion

Que de progrès depuis mon dernier test. L'utilisation de Podman sur un compte ne possédant pas les privilèges root fonctionne plutôt bien. Podman est devenu une alternative crédible à Docker.

Plus d'infos

Sites

Vidéos

Xavki