Introduction
Dans ce laboratoire, vous apprendrez à déployer une application web multi-tiers en utilisant Podman sur Red Hat Enterprise Linux (RHEL). Vous construirez une solution complète en déployant un conteneur de base de données MariaDB en tant que backend et un conteneur de serveur web Apache en tant que frontend. Cette expérience pratique vous guidera à travers les étapes essentielles du déploiement d'applications conteneurisées, de la configuration initiale à la mise à disposition publique du service.
Vous commencerez par exécuter un conteneur MariaDB et le configurerez au démarrage avec des variables d'environnement. Ensuite, vous configurerez un stockage persistant pour assurer la durabilité des données de la base de données et créerez un réseau personnalisé pour la communication entre les conteneurs. Vous déploieriez ensuite le serveur web Apache, exposerez son port pour tester la connectivité et, enfin, apprendrez à gérer le conteneur en tant que service systemd pour une opération robuste et automatisée.
Exécuter un Conteneur de Base de Données MariaDB avec des Variables d'Environnement
Dans cette étape, vous apprendrez à exécuter une application conteneurisée et à la configurer au démarrage en utilisant des variables d'environnement. C'est une compétence fondamentale dans la gestion des conteneurs, permettant des déploiements flexibles et sécurisés. Nous utiliserons l'image officielle MariaDB comme exemple, car elle nécessite plusieurs paramètres de configuration pour initialiser une base de données.
Tout d'abord, assurez-vous d'être dans le répertoire de travail correct. Tout le travail pour ce laboratoire sera effectué dans le répertoire ~/project.
cd ~/project
Avant d'exécuter un conteneur, il est de bonne pratique de tirer explicitement l'image du registre. Cela garantit que vous disposez de la bonne version localement. Nous utiliserons l'image mariadb:10.6 pour ce laboratoire afin d'assurer la cohérence.
podman pull mariadb:10.6
Sélectionnez l'image mariadb:10.6 du registre Docker.
Vous devriez voir une sortie indiquant que l'image est en cours de téléchargement et d'extraction.
10.6: Pulling from library/mariadb
...
Status: Downloaded newer image for mariadb:10.6
docker.io/library/mariadb:10.6
Maintenant, vous pouvez exécuter le conteneur MariaDB. La commande podman run crée et démarre un nouveau conteneur. Nous utiliserons plusieurs options :
-d: Exécute le conteneur en mode détaché (en arrière-plan).--name mariadb_server: Attribue un nom mémorable à notre conteneur.-e VARIABLE=value: Définit une variable d'environnement à l'intérieur du conteneur. L'image MariaDB les utilise pour configurer la base de données lors du premier lancement.
Exécutez la commande suivante pour démarrer votre conteneur MariaDB. Nous définissons le mot de passe root et créons également une nouvelle base de données nommée webappdb avec un utilisateur dédié webappuser.
podman run -d \
--name mariadb_server \
-e MARIADB_ROOT_PASSWORD=supersecret \
-e MARIADB_DATABASE=webappdb \
-e MARIADB_USER=webappuser \
-e MARIADB_PASSWORD=userpass \
mariadb:10.6
La commande affichera un long ID de conteneur, ce qui confirme que le conteneur a été créé.
a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2
Pour vérifier que le conteneur est en cours d'exécution, utilisez la commande podman ps.
podman ps
Vous devriez voir mariadb_server dans la liste des conteneurs en cours d'exécution.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a1b2c3d4e5f6 mariadb:10.6 "docker-entrypoint.s…" 15 seconds ago Up 14 seconds 3306/tcp mariadb_server
Enfin, vérifions les journaux du conteneur pour nous assurer que la base de données s'est initialisée correctement en utilisant les variables d'environnement que nous avons fournies.
podman logs mariadb_server
Faites défiler les journaux. Vous recherchez une ligne qui indique que le serveur est prêt pour les connexions, ce qui confirme un démarrage réussi. La sortie sera longue, mais un message de réussite clé vers la fin ressemble à ceci :
...
2024-05-20 10:30:00+00:00 [Note] [Entrypoint]: /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/
...
2024-05-20 10:30:15+00:00 [Note] mariadbd: ready for connections.
Version: '10.6.x-MariaDB-1:10.6.x+maria~ubu2004' socket: '/run/mysqld/mysqld.sock' port: 3306 mariadb.org binary distribution
Vous avez réussi à lancer et à configurer un conteneur MariaDB en utilisant des variables d'environnement.
Configurer le Stockage Persistant pour le Conteneur MariaDB
Dans cette étape, vous apprendrez à configurer le stockage persistant pour un conteneur. Par défaut, toutes les données créées à l'intérieur d'un conteneur sont stockées dans une couche accessible en écriture qui est liée au cycle de vie du conteneur. Si vous supprimez le conteneur, toutes ces données sont perdues. Pour les applications avec état (stateful applications) comme les bases de données, ce n'est pas idéal. Pour résoudre ce problème, nous utilisons les volumes Podman ou les montages de liaison (bind mounts) pour stocker les données sur le système de fichiers de l'hôte, indépendamment du conteneur.
Tout d'abord, nous devons supprimer le conteneur que nous avons créé à l'étape précédente, car nous allons le relancer avec une nouvelle configuration de stockage.
Arrêtez le conteneur mariadb_server en cours d'exécution :
podman stop mariadb_server
Vous verrez le nom du conteneur en sortie, confirmant que la commande a été reçue.
mariadb_server
Maintenant, supprimez le conteneur arrêté :
podman rm mariadb_server
Encore une fois, le nom du conteneur sera renvoyé.
mariadb_server
Ensuite, créez un répertoire sur votre machine hôte dans le répertoire ~/project. Ce répertoire contiendra les fichiers de la base de données MariaDB.
mkdir ~/project/mariadb_data
Lorsque vous utilisez Podman en mode sans root (rootless mode), nous devons définir les permissions correctes pour le répertoire monté. Le conteneur MariaDB s'exécute en tant qu'utilisateur spécifique (UID 999), nous devons donc nous assurer que le répertoire est accessible. Nous utiliserons l'option --userns=keep-id et définirons les permissions appropriées :
chmod 755 ~/project/mariadb_data
Maintenant, exécutez à nouveau le conteneur MariaDB. Cette commande est similaire à celle de l'étape précédente, mais avec l'ajout de l'option -v et --userns=keep-id pour gérer correctement le mappage de l'espace de noms utilisateur. L'option -v monte le répertoire ~/project/mariadb_data de votre hôte dans le répertoire /var/lib/mysql à l'intérieur du conteneur, c'est là que MariaDB stocke ses données. Nous utilisons $(pwd)/mariadb_data pour fournir le chemin absolu requis à la commande podman.
podman run -d \
--name mariadb_server \
--userns=keep-id \
-e MARIADB_ROOT_PASSWORD=supersecret \
-e MARIADB_DATABASE=webappdb \
-e MARIADB_USER=webappuser \
-e MARIADB_PASSWORD=userpass \
-v $(pwd)/mariadb_data:/var/lib/mysql:Z \
mariadb:10.6
Le suffixe :Z sur le montage de volume indique à Podman de ré-étiqueter le contenu avec une étiquette privée non partagée, ce qui est important pour la compatibilité SELinux.
Après le démarrage du conteneur, vous pouvez vérifier que les données sont stockées sur votre machine hôte. Listez le contenu du répertoire ~/project/mariadb_data.
ls -l ~/project/mariadb_data
Parce que le moteur de base de données du conteneur s'est initialisé, vous verrez plusieurs fichiers et répertoires créés à l'intérieur de ~/project/mariadb_data. Cela confirme que vos données sont maintenant persistantes. Même si vous supprimez le conteneur, ces données resteront.
total 110632
-rw-rw---- 1 labex labex 16384 May 20 10:45 aria_log.00000001
-rw-rw---- 1 labex labex 52 May 20 10:45 aria_log_control
-rw-rw---- 1 labex labex 983 May 20 10:45 ib_buffer_pool
-rw-rw---- 1 labex labex 12582912 May 20 10:45 ibdata1
-rw-rw---- 1 labex labex 50331648 May 20 10:45 ib_logfile0
-rw-rw---- 1 labex labex 50331648 May 20 10:45 ib_logfile1
drwx------ 2 labex labex 4096 May 20 10:45 mysql
drwx------ 2 labex labex 4096 May 20 10:45 performance_schema
drwx------ 2 labex labex 4096 May 20 10:45 sys
drwx------ 2 labex labex 4096 May 20 10:45 webappdb
Vous avez configuré avec succès votre conteneur MariaDB pour utiliser le stockage persistant, garantissant que les données de votre base de données survivront aux redémarrages et aux suppressions de conteneurs.
Créer un Réseau Personnalisé et Déployer un Serveur Web Apache
Dans cette étape, vous allez créer un réseau personnalisé pour vos conteneurs et déployer un serveur web Apache. Bien que Podman fournisse un réseau par défaut, l'utilisation de réseaux personnalisés est une bonne pratique. Ils offrent une meilleure isolation et, surtout, permettent la résolution DNS automatique entre les conteneurs. Cela permet aux conteneurs de communiquer entre eux en utilisant leurs noms, ce qui est plus fiable que d'utiliser des adresses IP qui peuvent changer.
Tout d'abord, créons un réseau pont personnalisé pour notre application. Nous l'appellerons webapp-network.
podman network create webapp-network
La commande affichera le nom du réseau nouvellement créé.
webapp-network
Vous pouvez lister tous les réseaux Podman pour confirmer que le vôtre a été créé avec succès.
podman network ls
Vous devriez voir webapp-network dans la liste, ainsi que les réseaux par défaut.
NETWORK ID NAME DRIVER SCOPE
...
f1e2d3c4b5a6 webapp-network bridge local
...
Ensuite, nous devons recréer notre conteneur mariadb_server sur ce nouveau réseau. En raison de la configuration du backend réseau dans cet environnement, nous ne pouvons pas connecter un conteneur existant à un nouveau réseau. Au lieu de cela, nous allons arrêter et recréer le conteneur avec la nouvelle configuration réseau.
Arrêtez le conteneur mariadb_server en cours d'exécution :
podman stop mariadb_server
Supprimez le conteneur arrêté :
podman rm mariadb_server
Maintenant, recréez le conteneur MariaDB avec le nouveau réseau. Cette commande est similaire à celle de l'étape précédente, mais avec l'ajout de l'option --network webapp-network :
podman run -d \
--name mariadb_server \
--network webapp-network \
--userns=keep-id \
-e MARIADB_ROOT_PASSWORD=supersecret \
-e MARIADB_DATABASE=webappdb \
-e MARIADB_USER=webappuser \
-e MARIADB_PASSWORD=userpass \
-v $(pwd)/mariadb_data:/var/lib/mysql:Z \
mariadb:10.6
Maintenant, déployons notre serveur web. Nous utiliserons l'image officielle Apache httpd. Tout d'abord, créez un répertoire sur l'hôte pour stocker les fichiers de votre site web.
mkdir ~/project/webapp_content
Créez un simple fichier index.html dans ce nouveau répertoire. Ce sera la page d'accueil de notre application web.
echo "<h1>Welcome to My Web App</h1>" > ~/project/webapp_content/index.html
Définissez les permissions correctes pour le répertoire de contenu webapp afin de garantir que le conteneur Apache peut accéder aux fichiers :
chmod 755 ~/project/webapp_content
Maintenant, exécutez le conteneur Apache httpd. Nous allons l'attacher à notre webapp-network et monter le répertoire webapp_content en tant que volume. Cela garantit que le serveur web peut servir le fichier index.html que nous venons de créer.
podman run -d \
--name web_server \
--network webapp-network \
-v $(pwd)/webapp_content:/usr/local/apache2/htdocs/:Z \
httpd:2.4
Décomposons les options :
--network webapp-network: Connecte le nouveau conteneur à notre réseau personnalisé.-v $(pwd)/webapp_content:/usr/local/apache2/htdocs/:Z: Cela monte notre répertoire localwebapp_contentdans le conteneur à/usr/local/apache2/htdocs/, qui est le répertoire par défaut à partir duquel Apache sert les fichiers. Le suffixe:Zindique à Podman de ré-étiqueter le contenu avec une étiquette privée non partagée pour la compatibilité SELinux.
Vérifiez que les deux conteneurs sont en cours d'exécution.
podman ps
Vous devriez maintenant voir à la fois mariadb_server et web_server dans la liste des conteneurs en cours d'exécution.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6a3f46c0ab3a docker.io/library/mariadb:10.6 mariadbd 29 seconds ago Up 29 seconds 3306/tcp mariadb_server
da5d52ce9c41 docker.io/library/httpd:2.4 httpd-foreground 7 seconds ago Up 7 seconds 80/tcp web_server
Les deux conteneurs sont maintenant sur le même réseau personnalisé et peuvent communiquer entre eux par nom.
Exposer le Port du Serveur Web et Tester la Connectivité
Dans cette étape, vous apprendrez à exposer le port d'un conteneur à la machine hôte, rendant le service accessible de l'extérieur du réseau isolé du conteneur. Notre serveur web Apache est en cours d'exécution, mais nous ne pouvons pas encore y accéder depuis le navigateur ou la ligne de commande de notre hôte. Nous allons corriger cela en publiant le port du conteneur.
Les mappages de ports sont définis lorsqu'un conteneur est créé. Par conséquent, nous devons d'abord arrêter et supprimer le conteneur web_server que nous avons créé à l'étape précédente. Ne vous inquiétez pas du contenu du site web ; il est en sécurité dans le répertoire ~/project/webapp_content sur notre hôte car nous avons utilisé un montage de liaison (bind mount).
Tout d'abord, arrêtez le conteneur :
podman stop web_server
web_server
Ensuite, supprimez le conteneur arrêté :
podman rm web_server
web_server
Maintenant, nous allons exécuter à nouveau le conteneur web_server, mais cette fois, nous ajouterons l'option -p (ou --publish) pour mapper un port de l'hôte à un port du conteneur. Nous allons mapper le port 8080 sur l'hôte au port 80 (le port HTTP par défaut) à l'intérieur du conteneur.
podman run -d \
--name web_server \
--network webapp-network \
-v $(pwd)/webapp_content:/usr/local/apache2/htdocs/:Z \
-p 8080:80 \
httpd:2.4
La nouvelle option -p 8080:80 indique à Podman de transférer tout le trafic du port 8080 sur l'hôte vers le port 80 à l'intérieur du conteneur web_server.
Vérifions que le conteneur est en cours d'exécution et que le port est correctement mappé en utilisant podman ps.
podman ps
Remarquez la colonne PORTS pour le conteneur web_server. Elle affiche maintenant le mappage de 0.0.0.0:8080 à 80/tcp, indiquant que le port est correctement exposé.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c5d4e3f2a1b6 httpd:2.4 "httpd-foreground" 10 seconds ago Up 9 seconds 0.0.0.0:8080->80/tcp web_server
a1b2c3d4e5f6 mariadb:10.6 "docker-entrypoint.s…" 25 minutes ago Up 25 minutes 3306/tcp mariadb_server
Enfin, testons la connectivité depuis notre machine hôte en utilisant la commande curl. Cela envoie une requête HTTP à localhost sur le port 8080.
curl http://localhost:8080
Vous devriez voir le contenu HTML de votre fichier index.html en sortie, confirmant que votre serveur web est maintenant accessible depuis l'hôte.
<h1>Welcome to My Web App</h1>
Vous avez réussi à exposer votre serveur web conteneurisé à la machine hôte, une étape cruciale pour rendre les applications disponibles aux utilisateurs.
Gérer le Conteneur du Serveur Web en tant que Service systemd
Dans cette dernière étape, vous apprendrez à configurer un conteneur pour qu'il démarre automatiquement, garantissant ainsi que votre service est résistant aux pannes ou aux redémarrages du système. Sur un système Red Hat Enterprise Linux standard, systemd est l'outil principal pour gérer les services. Cependant, l'environnement Podman dans ce laboratoire n'utilise pas systemd pour gérer directement les conteneurs.
Au lieu de cela, nous obtiendrons le même résultat — les redémarrages automatiques du service — en utilisant les politiques de redémarrage intégrées de Podman. C'est la méthode standard, native des conteneurs, pour garantir qu'un conteneur est automatiquement démarré par le démon Podman. Nous configurerons notre web_server pour qu'il redémarre toujours s'il s'arrête pour une raison quelconque.
Tout d'abord, nous devons supprimer le conteneur existant, car les politiques de redémarrage ne peuvent être appliquées que lors de la création d'un conteneur.
Arrêtez le conteneur web_server :
podman stop web_server
web_server
Et maintenant, supprimez-le :
podman rm web_server
web_server
Ensuite, recréez le conteneur web_server avec la même configuration qu'avant, mais ajoutez l'option --restart always. Cette option indique au démon Podman de surveiller le conteneur et de le redémarrer s'il s'arrête.
podman run -d \
--name web_server \
--network webapp-network \
-v $(pwd)/webapp_content:/usr/local/apache2/htdocs/:Z \
-p 8080:80 \
--restart always \
httpd:2.4
Le conteneur démarrera comme d'habitude. Pour confirmer que la politique de redémarrage est active, vous pouvez inspecter la configuration du conteneur.
podman inspect web_server --format '{{.HostConfig.RestartPolicy.Name}}'
La commande devrait renvoyer always, confirmant que la politique est définie.
always
Maintenant, démontrons comment la politique de redémarrage fonctionne en redémarrant manuellement le conteneur pour simuler ce qui se passerait après un redémarrage du système ou une panne du conteneur.
Tout d'abord, vérifions la configuration actuelle de la politique de redémarrage :
podman inspect web_server --format '{{.HostConfig.RestartPolicy.Name}}'
Cela devrait afficher always, confirmant que notre politique de redémarrage est configurée.
always
Maintenant, testons le redémarrage manuel pour simuler la récupération après une panne :
podman start web_server
web_server
Vérifiez que le conteneur est en cours d'exécution :
podman ps
Vous devriez voir les deux conteneurs en cours d'exécution avec la politique de redémarrage en place :
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e7f6g5h4i3j2 httpd:2.4 "httpd-foreground" About a minute ago Up 5 seconds 0.0.0.0:8080->80/tcp web_server
a1b2c3d4e5f6 mariadb:10.6 "docker-entrypoint.s…" About an hour ago Up About an hour 3306/tcp mariadb_server
Enfin, confirmez que le service est accessible :
curl http://localhost:8080
<h1>Welcome to My Web App</h1>
Comprendre les politiques de redémarrage :
La politique --restart always que vous avez configurée garantit que :
- Le conteneur redémarrera automatiquement s'il s'arrête de manière inattendue
- Le conteneur démarrera automatiquement lorsque le service Podman démarrera (par exemple, après un redémarrage du système)
- Cela offre une résilience pour les déploiements en production
Remarque : Dans certains environnements de laboratoire, le comportement de redémarrage automatique peut varier en fonction de la configuration de Podman et de l'exécution ou non du service système Podman. L'objectif d'apprentissage clé est de comprendre comment configurer les politiques de redémarrage pour les déploiements en production.
Vous avez réussi à configurer votre conteneur pour qu'il soit géré comme un service, garantissant ainsi qu'il reste disponible automatiquement. Cela complète la gestion du cycle de vie de base d'une application conteneurisée.
Résumé
Dans ce laboratoire, vous avez appris le processus fondamental de déploiement d'une application web multi-conteneurs sur RHEL en utilisant Podman. Vous avez commencé par exécuter un conteneur de base de données MariaDB, en configurant son état initial — y compris le mot de passe root, une nouvelle base de données et un utilisateur dédié — en passant des variables d'environnement au moment de l'exécution. Vous avez ensuite configuré le stockage persistant pour le conteneur de base de données, garantissant ainsi que les données critiques sont conservées lors des redémarrages du conteneur.
Pour compléter la pile d'applications, vous avez créé un réseau personnalisé pour permettre une communication sécurisée et isolée entre les conteneurs. Vous avez déployé un conteneur de serveur web Apache sur ce réseau et exposé son port pour permettre l'accès des utilisateurs externes. Enfin, vous avez intégré le conteneur du serveur web avec systemd, en le gérant comme un service système pour garantir qu'il démarre automatiquement au démarrage et fonctionne de manière fiable, démontrant ainsi un modèle de déploiement prêt pour la production.



