Des conteneurs ouverts aux utilisateurs

Quand on installe des services sur un serveurs et qu’on a déjà eu l’occasion de se battre avec des mises à jours, des configurations optimisées au jour le jour et non documentées, et autres joyeusetés, on pense rapidement à mettre en boîte ces services.

La mise en boîte consiste à mettre dans une boîte (un conteneur) une application et tout ce qui lui est nécessaire pour fonctionner puis à l’exécuter de façon isolée sur un système. Ce qu’on met dans la boîte peut aller d’un exécutable seul jusqu’à une distribution complète mais jamais le noyau du système (c’est la différence avec la virtualisation). Lors de l’exécution, la boîte communique avec le système qui l’héberge pour savoir quand s’exécuter, dans quel contexte, fournir des informations sur son état, communiquer des résultats, etc. Ces interfaces sont standardisées par l’OCI , ce qui garantit une certaine interopérabilité des boîtes. L’isolation des boîtes est assurée dans nativement depuis la version 2.6.24 du noyau linux grâce aux groupes de contrôle (cgroups).

On peut faire le parallèle avec la situation où quelqu’un s’invite chez un ami en lui proposant d’apporter le repas. On appelera celui qui reçoit “hôte” (en anglais host avec l’ambiguïté présente dans les deux langues) et celui qui s’invite “invité” (en anglais guest, sans ambiguïté). Par construction, le repas se déroulera chez l’hôte (il fournit la machine et le noyau) et l’invité fournit la nouriture (l’application), mais il reste beaucoup à définir : qui fournit la vaisselle, la nappe et les serviettes, l’invité peut-il utiliser la cuisine de l’hôte et de quels moyens peut-il se servir, l’invité doit-il apporter une table et des chaises… Dans la pratique, les conventions sociales réglent une bonne partie de ces aspects, il semblerait intrusif que redécore la salle à manger et peu commode qu’il vienne avec un four mais l’hôte peut trouver agréable que l’invité vienne avec les plats de service adapté à ce qu’il apporte et qu’il fasse la vaisselle et le ménage avant de partir.

En matière de systèmes informatiques, les standards sont souvent plus précis et plus impératifs que les conventions sociales mais laissent tout de même une marge de manœuvre au concepteur.

Pour comprendre on va prendre le fameux “hello world” en version podman

Soit le petit programme podman_hello_world.c suivant :

//###
//  ASCII art by the incomparable Máirín Duffy,
//  duffy@redhat.com, X/Twitter: @mairin
//  January 2022
//###

#include <stdio.h>
int main() {
    puts("\
!... Hello Podman World ...!\n\
\n\
         .--\"--.           \n\
       / -     - \\         \n\
      / (O)   (O) \\        \n\
   ~~~| -=(,Y,)=- |         \n\
    .---. /`  \\   |~~      \n\
 ~/  o  o \\~~~~.----. ~~   \n\
  | =(X)= |~  / (O (O) \\   \n\
   ~~~~~~~  ~| =(Y_)=-  |   \n\
  ~~~~    ~~~|   U      |~~ \n\
\n\
Project:   https://github.com/containers/podman\n\
Website:   https://podman.io\n\
Desktop:   https://podman-desktop.io\n\
Documents: https://docs.podman.io\n\
YouTube:   https://youtube.com/@Podman\n\
X/Twitter: @Podman_io\n\
Mastodon:  @Podman_io@fosstodon.org");
}

On le compile avec :

gcc -O2 -static -o podman_hello_world podman_hello_world.c

L’option static produit un exécutable qui n’a pas besoin de bibliothèque externe pour son exécution, c’est une application autonome qui n’a besoin que d’elle même.

À partir de là, on crée un fichier texte nommé Containerfile :

FROM scratch
COPY podman_hello_world /usr/local/bin/podman_hello_world
CMD ["/usr/local/bin/podman_hello_world"]

Et le conteneur est prêt.

La solution la plus répandue, docker, semble en perte de vitesse (2025). La valeur montante serait podman.

podman est bien integré à systemd et n’utilise que des droits utilisateurs.

Dépendances :#

Dépend#

  • libc6 ça va
  • […]
  • conmon un outil pour surveiller les conteneurs et communiquer avec eux
  • crun|runc l’environnement d’execution pour des conteneurs OCI (crun est conçu pour être plus rapide que runc)
  • golang-github-containers-common des fichiers de configuration pour les conteneurs
  • libsubid5 bibliothèque pour gérer les identifiants d’utilisateurs et de groupes délégués
  • netavark une pile réseau pour conteneurs

Recommande#

  • buildah outil de construction d’images OCI
  • catatonit|dumb-init|init un système d’initialisation minimal pour des conteneurs
  • containers-storage des outils pour manipuler le stockage des conteneurs sur disque
  • criu et libcriu2 outils pour créer des points de sauvegarde de conteneurs et les restaurer
  • passt environnement réseau en mode utilisateur (pasta)
  • slirp4netns une pseudo pile réseau pour conteneurs
  • uidmap outils pour gérer les identifiants d’utilisateurs et de groupes délégués

Va pour podman d’autant qu’il existe un paquet dans debian trixie

frv@cepet:~ $ sudo apt install podman 
Installation de :                               
  podman

Installation de dépendances : 
  aardvark-dns                     libcompel1
  buildah                          libcriu2
  catatonit                        libnet1
  conmon                           libslirp0
  containernetworking-plugins      libsubid5
  containers-storage               netavark
  criu                             passt
  crun                             python3-protobuf
  fuse-overlayfs                   python3-pycriu
  golang-github-containers-common  slirp4netns
  golang-github-containers-image   uidmap

Paquets suggérés :
  libwasmedge0  docker-compose

Sommaire :
  Mise à niveau de : 0. Installation de : 23 Supprimé : 0.
  Non mis à jour : 56
Taille du téléchargement : 68,7 MB
  Espace nécessaire : 296 MB / 786 GB disponible

Continuer ? [O/n]

[…]

Paramétrage de netavark (1.14.0-2) ...
Created symlink '/etc/systemd/system/default.target.wants/
netavark-dhcp-proxy.service' → '/usr/lib/systemd/system/ne
tavark-dhcp-proxy.service'.
Created symlink '/etc/systemd/system/sockets.target.wants/
netavark-dhcp-proxy.socket' → '/usr/lib/systemd/system/net
avark-dhcp-proxy.socket'.
Created symlink '/etc/systemd/system/firewalld.service.wan
ts/netavark-firewalld-reload.service' → '/usr/lib/systemd/
system/netavark-firewalld-reload.service'.
Unit /usr/lib/systemd/system/netavark-firewalld-reload.ser
vice is added as a dependency to a non-existent unit firew
alld.service.

Quadlets#