Sommaire
Bonjour à tous,
Le 1er février 2023 sortait la version 4.4 de Podman. Podman est un moteur de conteneur open source, développé par Red Hat, qui offre une gestion avancée des conteneurs et des images sur des systèmes Linux. En rivalité avec Docker, il permet aux utilisateurs de créer, exécuter et gérer des environnements de conteneurisation de manière efficace et sécurisée.
Cette version 4.4 comprenait notamment l’introduction de Quadlet, un nouveau générateur de service Systemd pour écrire et maintenir facilement des services pour les conteneurs et pods créé par Podman. Cela peut sembler anecdotique dit comme cela mais il s’agit d’une véritable révolution dans la façon de générer et d’administrer les services pour les conteneurs et pods.
Le projet Spirio est l’occasion pour moi d’approfondir mes connaissances de l’écosystème de Podman. Cet article est le premier d’une petite série afin de vous partager mes découvertes à travers la configuration de mysql et de WordPress avec des Quadlet.
Présentation
Fonctionnement des Quadlet
La syntaxe des fichiers Quadlet est très proche de celles des fichiers Unit de Systemd. Un exemple ci-dessous:
[Unit]
Description=A minimal container
[Container|Volume|Network]
Image=centos
[Service]
Restart=always
[Install]
WantedBy=default.target
Les directives qui peuvent être dans ce fichier se trouvent dans le manuel – man [podman-systemd.unit][https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html]. On retrouve la plupart des directives des fichiers docker-compose tel que volumes, hostname, networks, image etc.
Les fichiers Quadlet peuvent être disposés dans différents répertoires :
- /etc/containers/systemd/
- /etc/containers/systemd/user (Pour l’execution de pod en mode rootless)
- ~/.config/containers/systemd/ (Pour l’execution de pod par l’utilisateur courant)
Personnellement, je préfère les placer dans le répertoire /etc/containers/systemd/ afin d’avoir tous les fichiers Quadlet au même endroit.
Installation de Podman
Introduit dans la version 4.4 qui date de février 2023, l’exhaustivité ‘du format Quadlet ne fut pas complète même si elle s’améliore au fil des versions. On observera notamment le support de uidmap/gidmap en version 4.7 et Entrypoint /StopTimeout en version 5.0 (sortie il y a quelques jours).
De ce fait, il est nécessaire d’avoir une version assez récente de Podman afin de pouvoir exploiter pleinement la puissance des Quadlets. La version disponible sur Debian 12 est la version 4.3.1 et nous allons installer la version de testing afin de pouvoir utiliser la version 5.0.
echo 'APT::Default-Release "stable";'| sudo tee /etc/apt/apt.conf.d/99defaultrelease
echo "deb http://deb.debian.org/debian/ trixie main non-free-firmware non-free" | sudo tee /etc/apt/sources.list.d/testing.list
echo "deb http://security.debian.org/debian-security trixie-security main non-free-firmware non-free" | sudo tee -a /etc/apt/sources.list.d/testing.list
echo "deb http://deb.debian.org/debian/ trixie-updates main non-free-firmware non-free" | sudo tee -a /etc/apt/sources.list.d/testing.list
sudo apt update
sudo apt install podman/testing
Installation de Mysql
Création du volume
Afin de savoir quels sont les volumes nécessaires à Mysql pour fonctionner, on peut utiliser la commande podman inspect pour en savoir plus.
podman inspect --format {{.Config.Volumes}} mysql:latest
map[/var/lib/mysql:{}]
La commande nous indique qu’il y a un volume avec comme chemin /var/lib/mysql. Nous allons créer un répertoire /srv/wp-mysql afin de le lier à ce répertoire. L’objectif de cet article est de vous familiariser avec Quadlet, nous allons créer manuellement un volume au format Quadlet en spécifiant ce chemin.
mkdir /srv/wp-mysql
# cat /etc/containers/systemd/wp-mysql.volume
[Unit]
Description=Mysql Database Container Volume
[Volume]
Type=bind
Device=/srv/wp-mysql
[Install]
WantedBy=default.target
Afin que ce volume s’exécute au démarrage du serveur, il faut ajouter le [Install] WantedBy=default.target.
Pour information, il est possible de ne pas créer de volume dédié, car Podman est en capacité de les créer à la volée. Il est également possible de lier directement les deux répertoires sans avoir à utiliser de de volume.
Création du réseau
Nous allons créer un réseau spécifiquement dédié à la base de données Mysql et à WordPress. Cela permet d’améliorer la sécurité en les isolant des réseaux des conteneurs.
# cat /etc/containers/systemd/wp.network
[Unit]
Description=Wordpress Container Network
[Network]
[Install]
WantedBy=default.target
Création des secrets
Depuis la version 2.0 de Podman sortie en avril 2021, Podman permet de mettre à disposition des conteneurs des secrets de façon sécurisée. Dans le cadre de l’installation de WordPress, nous avons besoin de deux secrets. Le premier est le mot de passe du compte root de Mysql et le second est le mot de passe d’accès à la base de données de WordPress.
Tous les fichiers de configuration de WordPress et de sa base de données seront conservés dans le répertoire /etc/wordpress. Nous allons commencer par générer les secrets.
sudo mkdir /etc/wordpress
openssl rand -base64 32|tee /etc/wordpress/wp-mysql_MYSQL_ROOT_PASSWORD
openssl rand -base64 32|tee /etc/wordpress/wp-mysql_MYSQL_PASSWORD
Une fois générés, nous allons les charger avec Podman afin de pouvoir les utiliser dans les fichiers Quadlets.
podman secret create wp-mysql_MYSQL_ROOT_PASSWORD /etc/wordpress/wp-mysql_MYSQL_ROOT_PASSWORD
podman secret create wp-mysql_MYSQL_PASSWORD /etc/wordpress/wp-mysql_MYSQL_PASSWORD
Création du Quadlet
# cat /etc/containers/systemd/wp-mysql.container
# wp-mysql.container
[Container]
ContainerName=wp-mysql
Image=docker.io/library/mysql:latest
Environment=MYSQL_ROOT_PASSWORD_FILE=/run/secrets/wp-mysql_MYSQL_ROOT_PASSWORD MYSQL_DATABASE=wordpress MYSQL_USER=wordpress MYSQL_PASSWORD_FILE=/run/secrets/wp-mysql_MYSQL_PASSWORD
Secret=wp-mysql_MYSQL_ROOT_PASSWORD wp-mysql_MYSQL_PASSWORD
Exec='--default_authentication_plugin=caching_sha2_password' '--character-set-server=utf8mb4' '--collation-server=utf8mb4_unicode_ci'
Network=wp.network
Volume=wp-mysql.volume:/var/lib/mysql
[Service]
Restart=always
[Install]
WantedBy=default.target
Quelques explications :
- Image=docker.io/library/mysql:latest
Le nom absolu de l’image avec spécification du registre permet d’éviter de permettre un démarrage sans manipulation de l’administrateur. - Environment=MYSQL_ROOT_PASSWORD_FILE=/run/secrets/wordpress-mysql_MYSQL_ROOT_PASSWORD MYSQL_DATABASE=wordpress MYSQL_USER=wordpress MYSQL_PASSWORD_FILE=/run/secrets/wp-mysql_MYSQL_PASSWORD
Définition des variables d’environnement pour définir les mots de passe ROOT et pour l’utilisateur wordpress ainsi que la création d’un utilisateur et d’une base de données wordpress - Secret=wp-mysql_MYSQL_ROOT_PASSWORD wp-mysql_MYSQL_PASSWORD
Chargement des secrets - Exec=’–default_authentication_plugin=caching_sha2_password’ ‘–character-set-server=utf8mb4’ ‘–collation-server=utf8mb4_unicode_ci’
Paramètre de démarrage de Mysql - Network=wp.network
Utilisation du réseau que nous avons créé préalablement. - Volume=wp-mysql.volume:/var/lib/mysql
Utilisation du volume que nous avons créé préalablement. - Restart=always
Redémarrage en cas d’arrêt du service. - WanteBy=default.target
Démarrage du service lors du démarrage du système.
Installation de WordPress
Création du volume
Afin de savoir quels sont les volumes nécessaires à WordPress pour fonctionner, on peut utiliser la commande podman inspect pour en savoir plus.
podman inspect --format {{.Config.Volumes}} wordpress:latest
map[/var/www/html:{}]
La commande nous indique qu’il y a un volume avec comme chemin /var/www/html. Nous allons créer un répertoire /srv/wp-wordpress afin de le lier à ce répertoire. L’objectif de cet article est de vous familiarisez avec Quadlet, nous allons créer manuellement un volume au format Quadlet en spécifiant ce chemin.
mkdir /srv/wp-wordpress
# cat /etc/containers/systemd/wp-wordpress.volume
[Unit]
Description=Wordpress Container Volume
[Volume]
Type=bind
Device=/srv/wp-wordpress
[Install]
WantedBy=default.target
Création du Quadlet
# cat /etc/containers/systemd/wp-wordpress.container
# wp-wordpress.container
[Unit]
Requires=wp-mysql.service
[Container]
ContainerName=wp-wordpress
Image=docker.io/library/wordpress:latest
Environment=WORDPRESS_DB_HOST=wp-mysql.dns.podman:3306 WORDPRESS_DB_NAME=wordpress WORDPRESS_DB_USER=wordpress WORDPRESS_DB_PASSWORD_FILE=/run/secrets/wp-mysql_MYSQL_PASSWORD WP_HOME=https://spirio.fr WP_SITEURL=https://spirio.fr
Secret=wp-mysql_MYSQL_PASSWORD
Network=wp.network
IP=10.89.1.3
PublishPort=127.0.0.1:8000:2000
Volume=wp-wordpress.volume:/var/www/html/
[Service]
Restart=always
[Install]
WantedBy=default.target
Quelques explications :
- Requires=wp-mysql.service
Cela permet d’indiquer que le service de WordPress nécessite que le service wp-mysql soit fonctionnel pour démarrer. Si ce n’est pas le cas, le service wp-mysql sera démarré. - ContainerName=wp-wordpress
Le nom du conteneur dans Podman - Image=docker.io/library/wordpress:latest
Le nom absolu de l’image avec spécification du registre permet d’éviter de permettre un démarrage sans manipulation de l’administrateur. - Environment=WORDPRESS_DB_HOST=wordpress-mysql.dns.podman:3306 WORDPRESS_DB_NAME=wordpress WORDPRESS_DB_USER=wordpress WORDPRESS_DB_PASSWORD_FILE=/run/secrets/wordpress-mysql_MYSQL_PASSWORD WP_HOME=https://spirio.fr WP_SITEURL=https://spirio.fr
Les variables d’environnement nécessaire au fonctionnement de WordPress. L’identification de la base de données est réalisée via résolution DNS. Les réseaux créés par Podman intègre un DNS local qui permet de résoudre sur les machines connectées les noms des conteneurs. - Secret=wp-mysql_MYSQL_PASSWORD
Chargement des secrets - Network=wordpress.network
Utilisation du réseau que nous avons créé préalablement. - IP=10.89.1.3
La spécification d’une adresse IP permet de mettre en place des règles réseaux spécifiques à ce conteneur et de l’isoler. - PublishPort=127.0.0.1:8080:80
Indique que le port 80 du conteneur doit être accessible via le port 127.0.0.1:8080 de l’hôte. Cela permettra de disposer un reverse proxy sur le port 80/443 et rediriger les flux vers ce localhost. - Volume=/srv/wordpress/html:/var/www/html/
Chargement du volume qui contient les fichiers de WordPress. - Restart=always
Redémarrage du service en cas d’échec - WantedBy=default.target
Démarrage du service lors du démarrage du système.
Orchestration
La configuration des Quadlets est terminée. Pour vérifier qu’il n’y a pas d’erreur, nous pouvons utiliser la commande /usr/lib/systemd/system-generator/podman-generator –dryrun.
/usr/lib/systemd/system-generator/podman-generator --dryrun
Tout semble correcte, il est désormais nécessaire de recharger la configuration de Systemd et de démarrer les services.
systemctl daemon-reload
systemctl start wp-network
systemctl start wp-mysql-volume
systemctl start wp-wordpress-volume
systemctl start wp-wordpress
systemctl status wp-wordpress
Pour aller plus loin
Quelques pistes pour ceux qui veulent aller plus loin :
- Isoler les conteneurs des autres conteneurs ;
- Créer un utilisateur WordPress et faire fonctionner WordPress et sa base de données en mode rootless ;
- Spécifier l’utilisateur sous lequel les processus à l’intérieur du conteneur doivent s’exécuter. Cette option est utile pour améliorer la sécurité en limitant les privilèges du conteneur.
Ces pistes seront explorées dans un second article ultérieurement.
Conclusion
Comme vous avez pu le voir au cours de cet article, le format Quadlet améliore la lisibilité de la configuration des conteneurs ainsi que la génération de services Systemd. J’espère que vous avez trouvé cet article utile et qu’il vous a donné envie d’essayer de gérer vos conteneurs avec Podman.
Le format Quadlet est encore en pleine mouvance, il manque un certains nombres de paramètre natif de Podman, notamment les Entrypoint mais cela arrive.