Personnaliser son image de conteneur centos

conteneur centos docker podman

Les images officielles docker pour CentOS sont mise à jour à chaque nouvelle version, mais même la version latest nécessite rapidement une mise à jour.

Bien qu'on puisse lancer la mise à jour dans les premières lignes de notre Dockerfile, cela alourdi inutilement l'image finale (empilement), alors qu'il suffirait de disposer d'une image déjà à jour.

Le processus est assez simple pour peu que l'on dispose des utilitaires rpm et dnf (ou yum si on est sur une centos 7).

tip

Depuis une distribution Fedora, il faut réduire drastiquement le nombre de fichiers de langue qui seront installés en premier lieu, car on n'a besoin que de l'anglais (obligatoire) et du français (facultatif) pour la glibc. Yum respecte correctement l'option --setopt=override_install_langs et cela n'est donc pas nécessaire depuis une distribution CentOS <= 7.

On ajoute le fichier /etc/rpm/macros.image-language-conf

%_install_langs C:en:en_US:en_US.UTF-8:fr:fr_FR:fr_FR.UTF-8

On télécharge la version la plus récente du RPM centos-release

wget https://rpmfind.net/linux/centos/7.6.1810/os/x86_64/Packages/centos-release-7-6.1810.2.el7.centos.x86_64.rpm

On créé un répertoire d'accueil pour notre image

mkdir -p centos

On exporte le chemin absolu de notre répertoire d'accueil

export centos_root=$(pwd)/centos

A partir d'ici toutes les commandes sont à lancer avec le super-utilisateur root, donc on sudo.

On initialise la base de données RPM à l'intérieur de notre répertoire d'accueil

sudo mkdir -p ${centos_root}/var/lib/rpm
sudo rpm --root ${centos_root} --initdb

On installe notre paquet dans notre pseudo-chroot et on importe la clé GnuPG afin de vérifier l'authenticité des futures paquets.

sudo rpm --root ${centos_root} -ivh --nodeps centos-release*.rpm
sudo rpm --root ${centos_root} --import ${centos_root}/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

On installe yum dans notre pseudo-chroot (avec dnf si on est sur une Fedora, avec yum si on est sur une CentOS). On précise quelques options:

  • On ne veut pas toutes les langues, mais seulement quelques langues (anglais et français). Bien que cela ne fonctionne pas avec dnf (c'est pour cela que l'on a bridé l'installation des langues au début), je le laisse car ça fonctionne avec yum.
  • On ne veut pas les docs des paquets
  • On ne veut pas de mise en cache
sudo dnf -y --installroot=${centos_root} --setopt=keepcache=0 --setopt=tsflags='nodocs' --setopt=override_install_langs=en_US.UTF-8:fr_FR.UTF-8 install yum

Maintenant que notre utilitaire yum est installé, on le configure afin que nos choix soient permanents

sudo sed -i "/distroverpkg=centos-release/a override_install_langs=en_US.utf8:fr_FR.UTF-8ntsflags=nodocs" ${centos_root}/etc/yum.conf
    • On va maintenant créer un chroot classique depuis notre répertoire d'accueil et y exécuter quelques commandes:
    • On copie notre fichier de résolution de nom
    • On monte le répertoire dev (requis pour l'installation de certains outils)
    • On rentre dans notre chroot:
      • On installe quelques outils supplémentaires: procps-ng et iputils
      • On purge le cache de l'utilitaire yum
      • On purge notre chroot de toutes traces de dnf
      • On purge notre chroot de tous fichiers de log
    sudo cp /etc/resolv.conf ${centos_root}/etc
    sudo mount -o bind /dev ${centos_root}/dev
    sudo chroot ${centos_root} /bin/bash << EOF
    yum install -y procps-ng iputils
    yum clean all
    rm -rf /var/cache/yum
    rm -rf /etc/dnf
    rm -rf /var/cache/dnf
    rm -rf /var/lib/dnf
    rm -f /var/log/*.log

On démonte nos montages pour le chroot

sudo rm -f ${centos_root}/etc/resolv.conf
sudo umount ${centos_root}/dev

On créer une image de conteneur à partir de notre répertoire

sudo tar -C ${centos_root} -c . | docker import - local/centos

Et voilà, il ne reste plus qu'à tester Interrogation de docker à propos de notre image

docker images | grep local/centos
local/centos                                           latest              3f44a0f687be        3 seconds ago        198 MB

Test de l'image

docker run -ti --rm local/centos bash
bash-4.2# yum update
Loaded plugins: fastestmirror
Determining fastest mirrors
* base: centos.crazyfrogs.org
* extras: centos.crazyfrogs.org
* updates: centos.crazyfrogs.org
base | 3.6 kB 00:00:00
extras | 3.4 kB 00:00:00
updates | 3.4 kB 00:00:00
(1/4): base/7/x86_64/group_gz      | 166 kB 00:00:00
(2/4): extras/7/x86_64/primary_db  | 201 kB 00:00:00
(3/4): updates/7/x86_64/primary_db | 5.0 MB 00:00:01
(4/4): base/7/x86_64/primary_db    | 6.0 MB 00:00:01
No packages marked for update

C'est gagné, il n'y a pas de mise à jour disponible.

On pourrait aller plus loin encore en installant le dépôt EPEL dans notre chroot, entre le yum install et le yum clean all. A vous de voir si tous vos conteneurs en ont besoin.

Et podman dans tout ça ?

Ben ça dépend, en remplaçant docker par podman, ça fonctionne très bien si la partition du répertoire d'accueil est en ext4, par contre avec xfs, ça ne fonctionne pas. Le plus simple si toutes vos partitions sont en xfs, c'est de créer une petite partition (512Mo devrait être suffisant) en ext4.

Sources

Article précédent Article suivant