Utilisation de Docker

Résumé

En plus de la machine virtuelle nous allons utiliser docker pour séparer les différentes applications. Le but de ce TP est d'installer 5 conteneurs :

  1. un docker mysql qui servira de base de donnée;
  2. un docker phpmyadmin pour piloter cette base;
  3. un docker nginx qui sera le serveur web de base et servira aussi en tant que proxy inverse en assurant la répartition des requêtes dans les différents conteneurs;
  4. un docker wordpress qui servira de serveur de partage de fichiers
  5. un docker wordpress:cli pour l'initialisation
  6. et éventuellement un docker redis.

Objectifs

  • Apprendre à manipuler les dockers.
  • Savoir configurer les dockers via les options de lancement.
  • Savoir configurer les dockers en partageant certains fichiers de configurations avec la machine hôte.
  • Savoir configurer les dockers en modifiant l'image par un Dockerfile.
  • Gérer les réseaux interne des dockers.
  • Utiliser docker compose pour gérer plusieurs docker simplement.

Notation

Nous allons noter ces TPs en fonction du travail accompli. Pour cela, il faut impérativement noter votre binôme et l'adresse IP de votre VM dans les cases prévues de tomuss : BinomeTpDocker et IPTpDocker.

Le travail sera noté par un script de vérification. Une première version de ce script est disponible ici, elle sera completé donc votre note n'est pas égale à celle que vous obtiendrez par ce script, mais cela donne une idée du fonctionnement.

wget https://perso.univ-lyon1.fr/fabien.rico/site/_media/cloud:2022:test.zip -O test.zip
sudo apt install -y python3-pip unzip zip
unzip test.zip
cd Test
sudo pip3 install -r requirement.txt
./verif.py debut wordpress

Avant de commencer

Vous allez utiliser la plateforme openstack du département cloud-info.univ-lyon1.fr Merci de ne pas faire de snapshot de vos machines, normalement, vous conservez dans vos rapports les commandes nécessaires au bon fonctionnement du TP.

  • Créez une VM par groupe :
    1. Attention a bien la créer dans le projet CloudComputing (TIW) ou CSV (SRS)
    2. basée sur le snapshot snap-tp-cloud
    3. avec le flavor c2-small
    4. avec une clef ssh dont vous déposez la clef secrète dans la case clefTpDocker de tomuss

Comme pour beaucoup de serveurs connus, il existe plusieurs images qui permettent l'installation de mysql très simplement.

  • Recherchez la liste des dockers fournissant mysql, (commande docker search) vous verrez qu'ils sont classés par défaut grâce à un système de recommandation via des étoiles. Quels sont les 3 mieux notés ?
  • Recherchez de la même manière sur le site docker hub. Ce site donne plus de détails notamment les différentes versions pour une image, les Dockerfile

Il faut savoir reconnaître rapidement la qualité d'une image, dans l'exemple de mysql vous avez 2 possibilités (nous excluons mariadb)1). :

La documentation de la seconde est beaucoup plus fournie et elle semble proposer un grand nombre d'options de configuration, c'est cette dernière que vous allez choisir.

  • Quelles sont les versions proposées et comment reconnait-on la dernière ?
  • Sur quelle distribution est basée la version 5 de mysql ? <hi #f3f3f3>Regardez les Dockerfiles</hi>
  • Téléchargez la dernière image de la version 5 grâce à la commande ``docker pull`` (c'est la 5.7.39 à ce jour)
  • Vérifiez que l'image est bien téléchargée, son nom et son tag.
  • Lancez un premier docker basé sur cette image dont :
    1. le nom est docktest;
    2. le hostname est test;
    3. dont le mot de passe du root mysql est généré aléatoirement.

Notez le mot de passe de l'administrateur.

Lors du lancement un grand nombre d'informations sont affichées. En fait, par défaut le lancement bloque le terminal et affiche tous les résultats de la commande. Parmi ces derniers vous pouvez noter la ligne GENERATED ROOT PASSWORD: … qui contient le mot de passe administrateur de la base. Dans la suite, vous utilisez sans doute l'option -d pour lancer le docker de manière détachée, les informations ne seront plus affichées, mais conservées et disponible via la commande docker log ….

docker logs docktest 2>&1 | grep GENERATED
  • Grâce à la commande docker inspect … trouvez l'adresse attribuée au docker
  • Pouvez-vous vous connecter sur le serveur mysql avec la commande telnet (le port par défaut est 3306).
  • Pouvez-vous le faire via la commande mysql ?

Il est toujours possible d'installer le client mysql sur votre VM, mais ici, on va utiliser celui qui se trouve dans le docker. En effet, on peut toujours ajouter un processus au conteneur via la commande docker exec …

  • En utilisant la commande
    docker exec -it NOMDUDOCKER mysql -u root -pMOTDEPASSE

    connectez-vous au serveur mysql.

  • Exécutez un shell bash dans le docker (commande docker exec -it …) et créer un fichier à la racine /toto à la racine du docker contenant coucou.
  • Sortez du docker et essayez de retrouver le fichier sur la VM. Pour cela, vous pouvez utiliser docker inspect … notamment la partie Data. Que représentent les répertoires MergedDir et UpperDir et LowerDir ?2)

Partage de volumes

mysql est une base de données qui stocke ces données dans le répertoire /var/lib/mysql. Dans la configuration actuelle, ce répertoire est interne au docker et difficile d'accès. Cela peut poser des problèmes si vous souhaitez changer le docker sans perdre les données stockées. Pour éviter cela, vous allez donc recréer le docker en partageant le répertoire de stockage avec la machine hôte. Pour cela il faut utiliser l'option -v du docker run.

  • Détruisez le docker docktest.
  • Recréez un docker basé sur mysql 5.7 dont :
    1. le nom est serv-mysql;
    2. le hostname est base;
    3. le mot de passe root est ppaasswwoorrdd;
    4. qui partage le répertoire /var/lib/mysql du docker avec le répertoire /home/ubuntu/docker/data/base/ de la VM.
  • Après la fin du démarrage du docker (qui prend un peu de temps) listez le contenu du fichier /home/ubuntu/docker/data/base/
  • Créez une base de données en exécutant la commande
    mysql -u root -pppaasswwoorrdd -e 'CREATE DATABASE A_BASE;'

    dans le docker

  • Relistez le même répertoire, quelle est la différence ?

mysql n'est qu'un serveur de base de donnée, on ne peut l'utiliser que via des commandes SQL. Pour simplifier son utilisation, on ajoute en général une interface comme le logiciel phpMyAdmin. C'est une interface web permettant simplement de faire la plupart des opérations sur le serveur. Il est basé sur un code en php et donc un serveur capable de l'interpréter.

  • Peut-on ajouter phpMyAdmin au docker mysql pour former un docker avec le serveur et l'interface. Si oui pourquoi ne le fait-on pas ?

Gestion du réseau et liaison entre les dockers

Vous allez utiliser la possibilité de créer un réseau interne aux dockers et de fixer les noms utilisés dans ce réseau.

En effet, dans un tel réseau, il est possible de choisir les nom et les adresses IPs des dockers, de choisir la valeur de leurs variables d'environnement ou de paramétrer leur fichier /etc/hosts tout cela va permettre facilement de lancer un nouveau conteneur basé sur phpMyAdmin et qui se connecte à notre base.

  • Vous devez tout d'abord créer un réseau utilisateur via la commande docker network create …. Attention, il faut utiliser l'option subnet pour définir le réseau. Créer un réseau de nom resTP et utilisant la plage d'adresses 172.18.10.0/24.
  • Arrêtez le docker serv-mysql Attention ne le supprimez pas
  • puis recréez un nouveau docker mysql utilisant le réseau resTP (option --net), en attribuant une adresse (option --ip) et en lui associant un alias réseau (option --network-alias) :
    1. basé sur mysql:5
    2. le nom est serv-bdd;
    3. le hostname est basededonnee;
    4. le mot de passe root est ppaasswwoorrdd;
    5. qui partage le répertoire /var/lib/mysql du docker avec le répertoire /home/ubuntu/docker/data/base/ de la VM.
    6. utilisant l'adresse 172.18.10.100.
    7. Utilisant l'alias réseau bdd

Vous pourrez noter que comme le nouveau docker partage le même répertoire de données, les bases précédemment crées et le mot de passe de l'administrateur sont déjà configurés au lancement. Cela signifie que le docker mysql est capable d'initialiser la base la première fois, mais ensuite, les données sont préservées tant que le répertoire de données n'est pas effacé.

Lancement de l'interface phpMyAdmin

Vous allez utiliser le docker phpMyAdmin pour mettre en place l'interface. Dans la documentation ne suivez pas la méthode Usage with linked server qui est dépréciée. Utilisez la méthode avec un serveur externe qui permet de définir le serveur de base de données via une variable d'environnement.

  • créez un docker basé sur phpmyadmin/phpmyadmin :
    1. dont le nom est serv-madm;
    2. qui partage le port 8080 de votre VM avec le port 80 du docker;
    3. qui utilise le serveur de base de donnée bdd (alias de notre docker serv-bdd);
    4. qui utilise le réseau resTP en lui attribuant l'adresse 172.18.10.101 et l'alias pma.tpcloud.
  • Verifiez que serv-madm est bien dans le même réseau que le docker serv-bdd (avec un docker inspect ..).
  • Connectez-vous sur l'interface web entrez le login mot de passe de l'administrateur mysql et créer une nouvelle base de données : B_BASE. Constatez les modifications du répertoire partagé.
  • La VM peut-elle contacter ces dockers ? Une autre VM le peut-elle ?
  • Reconnectez-vous sur l'interface web, tout devrait fonctionner et les bases créées précédemment devraient être encore fonctionnelles. Cela signifie donc que le docker mysql est capable de conserver les données déjà existantes.

En général pour configurer un service, il est nécessaire de modifier des fichiers. Mais ces fichiers sont internes au docker donc difficiles d'accès. De plus, les outils d'édition les plus courants (nano, vim, emacs …) ne font pas parti d'un conteneur classique ce qui complique encore cette modification. Pour résoudre le problème, on peut :

  1. Pré-configurer le docker via le Dockerfile ou les outils de création (voir plus tard);
  2. Copier des fichiers entre la VM et le docker;
  3. Utiliser le partage des répertoires entre la VM et le docker.

Nous allons utiliser la dernière méthode pour configurer un proxy inverse nginx.

Le fichier de configuration principale de nginx est /etc/nginx/nginx.conf. Nous allons partir d'un fichier copié depuis un docker nginx fonctionnel .

  • créez un docker basé sur la dernière image nginx tel que :
    1. son nom soit serv-nginx;
    2. il soit dans le réseau resTP avec l'adresse 172.18.10.105;
    3. le port 80 de l'hôte soit envoyé sur le port 80 du docker;
    4. le fichier nginx.conf soit lié au fichier /etc/nginx/nginx.conf du docker, le container ne doit pas pouvoir écrire dans le fichier (sur l'hote placez le dans /home/ubuntu/docker/conf/nginx.conf);
    5. le répertoire /home/ubuntu/docker/data/nginx/ soit lié au répertoire /www/ du docker.
  • vérifiez le bon fonctionnement du serveur nginx en allant à l'adresse http://IPDEVOTREVM/
  • Modifiez la configuration du serveur pour que la racine du site web soit le répertoire partagé /www/
  • Ajoutez un fichier index.html dans la racine du site en utilisant la commande :
      echo "voir <a href='/pma/'>phpMyAdmin</a>" > /home/ubuntu/docker/data/nginx/index.html
      
  • Modifiez la configuration du serveur pour que l'url http://IPDEVOTREVM/pma/ soit renvoyée vers le docker serv-madm. Pour cela il faut
    1. utiliser la configuration de nginx comme reverse proxy
    2. reconstruire le docker serv-madm
      1. en le plaçant directement dans le réseau resTP avec l'alias pma.tpcloud et l'adresse 172.18.10.101;
      2. en lui donnant l'url par laquelle il sera contacté via la variable PMA_ABSOLUTE_URI;
      3. en supprimant le transfert de port (8080 vers 80) car il est inutile (et gênant pour la suite).

Vous allez maintenant ajouter un élément au site : wordpress. C'est un CMS très utilisé. Il est disponible ici ou dans une version dockerisée.

La documentation propose d'utiliser en plus de ce docker un docker mysql.

  • Adaptez le docker serv-bdd pour qu'il crée un utilisateur et une base de données :
    1. basé sur mysql 8
    2. le nom est serv-bdd;
    3. le hostname est basededonnee;
    4. le mot de passe root est ppaasswwoorrdd;
    5. qui partage le répertoire /var/lib/mysql du docker avec le répertoire /home/ubuntu/docker/data/base8/ de la VM3).
    6. utilisant l'adresse 172.18.10.100 dans le réseau resTP avec l'alias bdd;
    7. avec un utilisateur userwordpress dont le mot de passe est passwordpress;
    8. avec une base de données wordpress.
  • Créer un docker serv-wordpress
    1. basé sur l'image wordpress;
    2. qui utilise cette basse de données (voir les variables WORDPRESS_DB_HOST, WORDPRESS_DB_USER, WORDPRESS_DB_PASSWORD et WORDPRESS_DB_NAME;
    3. dont l'adresse est 172.18.10.107;
    4. dont l'alias dans le réseau resTP est wordpress;
    5. qui écoute sur le port 8080 de la machine hôte et transfert le tout sur le port 80 du docker.
  • Testez-le, à l'adresse http://IPDEVOTREVM:8080/ attention, le site n'est pas encore installé, on tombe normalement sur une page proposant l'installation qu'il ne faut pas lancer.
  • Reconfigurez le serveur nginx pour que la racine du site web soit connectée avec le docker serv-wordpress.
  • Testez en allant sur l'URL http://IP_DE_VOTRE_VM/.

Création d'une première image

Certaines configurations ne sont pas proposées par le docker wordpress. Par exemple, celui-ci ne dispose pas du module redis de php, or ce module est utile pour la suite du TP. DE plus, les vm de l'université n'ont pas accès à internet ce qui empèche le site de bien fonctionner. Vous allez donc dans un premier temps modifier l'image wordpress pour l'adapter.

La modification d'une image se fait grâce à des fichiers de description Dockerfile. En fait, chaque création d'image correspond à un répertoire qui contient les données nécessaires à la modification ainsi que le fichier de description Dockerfile. Vous pouvez noter que la plupart des documentations de dockers sont en fait constituées par un dépôt git correspondant à ce répertoire. Comme vous pouvez le voir ici.

Nous vous proposons de commencer par ce répertoire de travail.

  • Construisez une nouvelle image nommée wordpress-perso:0.1 basée sur ce Dockerfile.
  • Testez la nouvelle image et vérifiez que tout fonctionne en créant un docker serv-wordpress
    1. basé sur l'image wordpress:0.1;
    2. qui utilise cette basse de données (voir les variables WORDPRESS_DB_HOST, WORDPRESS_DB_USER, WORDPRESS_DB_PASSWORD et WORDPRESS_DB_NAME;
    3. dont l'adresse est 172.18.10.107;
    4. dont l'alias dans le réseau resTP est wordpress;
    5. qui écoute sur le port 8080 de la machine hôte et transfert le tout sur le port 80 du docker;
    6. qui partage le répertoire /home/ubuntu/docker/php/ de la machine avec le répertoire /var/www/html/ du conteneur.

wordpress est un logiciel qui génère beaucoup d'uploads. Or, la limite imposée par php est souvent trop faible (2Mo par dépots). Nous allors changer cela. Comme ce TP n'est pas un apprentissage de la configuration php, il vous faut juste savoir que cela correspond à copier le fichier uploads.ini proposé dans l'archive à un emplacement précis du conteneur.

  • Modifiez le Dockerfile pour copier le fichier uploads.ini dans le répertoire /usr/local/etc/php/conf.d de l'image.
  • Reconstruisez l'image avec le tag wordpress-perso:0.2.
  • Ajouter à cette image le tag wordpress-perso:latest.
  • reconstruisez le docker serv-wordpress en précisant l'image wordpress-perso sans mentionner de version. Vérifiez que vous obtenez bien l'image 0.2.

Installation de wordpress

Pour le moment le site wordpress n'est pas fonctionnel. En effet, ce dernier a besoin d'une installation qui va initialiser la base de donnée. Il est possible de faire cette installation en ligne de commande via les script wordpress:cli

Ce script est utilisable sous la forme d'un docker supplémentaire à utiliser. Vous pouvez voir un exemple de fonctionnement à la fin de la documentation des docker ''wordpress''.

  • Lancez un docker wordpress:cli en lien avec le docker serv-worpress de manière à finaliser le site :
    1. avec comme url l'url de votre site http://IP_DE_VOTRE_VM/
    2. avec comme titre du site Mon Site Wordpress
    3. avec un administrateur de login lemaitre de mot de passe ppaasswwoorrdd et de mail monmail@univ-lyon1.fr
    4. sans lui envoyer de mail à l'initialisation.
  • Vérifiez le bon fonctionnement du site.

Vous devez être capable de lancer un petit ensemble de services via des dockers. Mais cela n'est pas suffisant. En effet, avec la méthode actuelle, pour que le site fonctionne, il faut être capable de lancer les dockers avec les bonnes options, dans un ordre précis, avec des fichiers de configuration qui dépendent de ces options … Tout cela est difficile à distribuer. Il est donc nécessaire de faire la même chose mais de manière automatique.

En effet, pour automatiser les opérations sur les conteneurs, il est possible d'écrire une description des commandes utilisées dans un fichier, c'est le rôle de docker-compose. Docker compose est capable de faire à votre place toutes les commandes docker nécessaires à partir de ce que vous avez décrit dans un fichier docker-compose.yml.

Vous pouvez avoir une description de ces fichiers à cette adresse. Attention, l'api docker évolue rapidement, il est important de se limiter à une version pour travailler. De plus, il ne faut pas confondre la version de l'exécutable docker-compose, celle du logiciel docker et celle du fichier de description docker-compose.yml.

La version la plus importante est celle du fichier de description, elle est écrite au début du fichier :

version: '3'
services:
  foo:
    image: busybox

Nous vous conseillons d'utiliser pour ce TP la version de l'exemple : 3. C'est la dernière de la version 3. La documentation conseillée est donc celle de la version 3 et il est important de vérifier que la documentation que vous consultez est bien basée sur cette version pour expliquer les problèmes.

Dans la version 3, le fichier est composé de plusieurs sections correspondant aux sous-commandes docker utilisées dont vous utiliserez les 2 suivantes :

  1. services est la section qui donne la liste des dockers et de leurs options, cela correspond aux commandes docker run … ou docker create …
  2. networks est la section qui décrit les réseaux à utiliser. Cela correspond à la commande docker network …

D'autre sections que vous n'allez pas utiliser

  1. volumes est la section qui décrit les volumes à utiliser. Cela correspond à la commande docker volume …
  2. secrets est la section pour stocker des information secrète qu'on ne veux pas voir apparaître dans les fichiers de configuration (et qui nécessite un cluster).

Cas spécial des volumes

Vous aurez effectivement besoin de volume, mais la section volumes correspond à la création de volumes en dehors des dockers. Jusqu'à présent, vous n'avez jamais utilisé la commande docker volumes … ce qui signifie que vous n'aurez pas à utiliser la section pour ce TP. Tous vos volumes seront des volumes de type bind, c'est à dire créés lors du docker run (section service) et partagée avec la machine hôte. Attention donc à bien consulter la bonne partie de la documentation .

Pour être plus prévis, les volumes sont des espaces de stockage persistants utilisés par les dockers. Vous pouvez les créer soit en les utilisant dans un docker soit en les créant à part via la commande docker volume…. Si vous êtes curieux, La description de la section volumes d'un docker-compose est ici. Mais pour ce TP vous n'aurez qu'a consulter la description de l'utilisation des volumes par les dockers grâce à la sous-section volumes d'un service. Cette documentation est .

Dans un fichier docker-compose.yml

  • La section volumes globale vous permettra de créer un volume ou de déclarer un volume qui a été créé en dehors du docker compose. Elle permet aussi d'utiliser des drivers spéciaux.
  • La sous-section volumes de la description d'un service est celle qui attachera effectivement le volume au docker créé, cela correspondra à l'option -v de la commande docker-run. C'est à cet endroit que vous pouvez associer un répertoire du docker avec un répertoire de la machine.

Section networks

C'est la section qui vous permettra de créer et configurer le réseau. Correspondant à ce que vous avez fait via la commande docker network …. Vous êtes invité à consulter cette documentation, notamment la partie ipam qui permet de gérer l'intervalle d'adresse utilisé.

Section services

Cette section décrit les dockers qui devront être créés. Pour cette version, chaque service correspond à un docker et une commande docker-run …. La documentation est très fournie, vous aurez notamment besoin :

  1. De pouvoir choisir l'image à partir de laquelle le docker est créé, cela peut être
    • une image utilisable via le mot clef image;
    • une image construite via le mot clef build.
  2. D'imposer le réseau utilisé via le mot clef networks. Regardez notamment comment choisir l'adresse ip et donner un alias à ce docker.
  3. D'ajouter au docker des partages de répertoires de type bind volumes.
  4. De déclarer des variables d’environnement dans le docker environment.
  5. De mettre en place des transferts de ports réseaux entre la VM et le docker ports.
  6. De spécifier des dépendances entre les dockers depends_on.
  7. De spécifier le comportement des dockers en cas d'arret restart

Installez le programme docker-compose manuellement

Vous devez créer un ensemble de fichiers et un docker-compose.yml qui recrée l'architecture vue au début du TP.

Le répertoire doit être /home/ubuntu/compose/ et contenir tous les fichiers et partages nécessaires à cette architecture.

  ./compose/
    |_ docker-compose.yml
    |_ Data/
    |  |_ mysql/
    |  |_ php/
    |_ Config/
    |  |_ nginx/nginx.conf
    |_ Build/
       |_wordpress/
           |_ Dockerfile
           |_ uploads.ini

Vous devez faire un fichier compose qui crée des dockers équivalents aux dockers et au réseau créé auparavant. Ces dockers utiliseront le port http, vous devez donc tout d'abord arréter les dockers précédant (attention, conservez-lez pour la notation).

Pour résumer il faut :

  • un réseau tp.cloud
    1. utilisant les adresses 172.22.10.0/24.
  • un service nginx qui servira de frontale web
    1. basé sur la dernière version de l'image nginx;
    2. qui a une adresse fixe dans le réseau tp.cloud : 172.22.10.20;
    3. lancé après les services phpmyadmin et wordpress;
    4. qui partage le port 80 de la machine avec le port 80 du docker;
    5. qui est configuré via le partage du fichier ./Config/nginx/nginx.conf;
    6. qui renvoie les requêtes http://IP_DE_VOTRE_VM/ sur wordpress1.tp.cloud et http://IP_DE_VOTRE_VM/madm/ sur pma.tp.cloud;
    7. qui utilise l'alias web.tp.cloud;
    8. qui se relance automatiquement en sauf si on l’éteint volontairement.
  • Un service basededonnees
    1. basé su l'image mysql dans la version 8 ;
    2. dont le répertoire de données est associé à ./Data/mysql/;
    3. qui a une adresse dynamique dans le réseau tp.cloud;
    4. qui est connu des autres dockers sous plusieurs noms : mysql.tp.cloud, base.tp.cloud ou bdd.tp.cloud;
    5. dont le mot de passe root est ppaasswwoorrdd;
    6. qui contient un utilisateur wp_user de mot de passe wp_pass et une base wp_base.
    7. qui se relance automatiquement en sauf si on l’éteint volontairement.
  • Un service myadmin
    1. basé sur l'image phpmyadmin/phpmyadmin;
    2. qui démarre après basededonnees;
    3. qui a une adresse dynamique dans le réseau tp.cloud;
    4. qui est connu des autres dockers sous plusieurs noms : phpmyadmin.tp.cloud ou pma.tp.cloud;
    5. qui interroge le serveur bdd.tp.cloud;
    6. dont vous redefinisser le healthcheck par la commande
    7. qui se relance automatiquement en sauf si on l’éteint volontairement.
  • Un service wordpress1
    1. basé sur une image construite d'après le contenu du répertoire ./Build/wordpress/;
    2. qui démarre après le docker basededonnees;
    3. dont le volume contenant le code est associé au répertoire ./Data/php/;
    4. qui a une adresse dynamique dans le réseau tp.cloud;
    5. qui est connu des autres dockers sous plusieurs noms : wordpress1.tp.cloud ou wp1.tp.cloud;
    6. qui utilise la base de donnée et l'utilisateur mysql wp_user;
    7. qui se relance automatiquement en sauf si on l’éteint volontairement.
  • Un service wordpress_install
    1. qui partage les volumes de wordpress1
    2. dans le réseau tp.cloud
    3. qui démarre uniquement quand le conteneur wordpress1 est en train de tourner et que la base de donnée est healthy;
    4. qui installe le wordpress avec l'administrateur monadm, le mot de passe monpass, le mail monmail@tp.cloud
    5. qui ne se relance pas automatiquement.

Vous constaterez que les dockers créés par compose n'ont pas le nom des services. En effet, s'il n'est pas précisé par le champ container_name, compose ajoute le nom du répertoire et un numéro unique. C'est utile pour que les noms de ces dockers soient différents de ceux que vous aviez crée auparavant. Gardez les noms par défauts.

Load balancing

Vous allez ajouter un conteneur wordpress identique au premier et configurer le proxy nginx pour qu'il répartisse la charge.

  • Créez un service wordpress2
    1. basé sur une image construite d'après le contenu du répertoire ./Build/wordpress/;
    2. qui démarre après le docker wordpress1;
    3. dont le volume contenant le code est associé au répertoire ./Data/php/;
    4. qui a une adresse dynamique dans le réseau tp.cloud;
    5. qui est connu des autres dockers sous plusieurs noms : wordpress2.tp.cloud ou wp2.tp.cloud;
    6. qui utilise la base de donnée et l'utilisateur mysql wp_user;
    7. qui se relance automatiquement en sauf si on l’éteint volontairement.
  • Configurez le proxy nginx pour répartir la charge sur les deux wordpress (voir ici
  • Si vous utilisez la répartition par défaut (round robin) vous constaterez qu'il est impossible de se connecter au site wordpress (url http://IPDEVOTREVP/wp-admin/. Pourquoi ? Corrigez cela.

Vous allez utiliser les propriété de la plateforme openstack pour faire un docker capable de déclarer un nom DNS à votre VM et générer un certificat letsEncrypt valide.

Pour cela il faut vous baser sur la documentation fournie (mais un peu modifiée voir la suite) :

  1. celle de la création d'un jeton d'application pour openstack (afin de permettre à un script de donner des ordres à la plateforme]];
  2. celle de l'installation des commandes openstack (seulement l'installation, pour l'authentification vous utiliserez un jeton applicatif)

Travail a faire

  • Vous n'avez pas à créer la zone DNS décrite dans la documentation, les opérations se feront via le docker alors l'interface d'openstack ne dois servire que de moyen de vérification.
  • Vous devez créer une image docker qui prendra quelques paramètres :
    1. le nom a créer dans 2 variables d'environnement CERTBOT_NAME contenant le nom de machine et CERTBOT_DOMAIN le domaine DNS utilisé (voir tomuss dans votre cas);
    2. votre mail (il est important d'en mettre un valide car c'est pour créer un certificat valide) dans la variable CERTBOT_MAIL;
    3. L'adresse IP de votre VM dans la variable CERTBOT_IP
    4. un fichier contenant les paramètres d'authentification (qui est fourni par openstack à la création du jeton d'authentification).
  • Vous devez intégrer ce conteneur à votre compose pour qu'il lance la création du certificat avant le lancement de nginx et configurer ce dernier pour qu'il l'utilise.

Détails pour vous aider

PArtez de l'image basée sur le Dockerfile de l'archive suivante, il faut liui ajouter :

  1. les outils clients openstack et le logiciel certbot
  2. le script letsencrypt-designate fourni par la documentation
  3. un script que vous allez créer qui servira de commande de base au docker.

Le script de création de domaine a pour but de vérifier que le domaine n'est pas déjà présent dans le volume (/etc/letsencrypt). Si ce n'est pas le cas, il enregistre un nouveau nom de domaine (champs A du DNS) pour votre IP puis fait une requête à let's encrypt pour obtenir un certificat pour ce nom de domaine. Pour vos test, demander bien un pseudo certificat, le système risque de vous bloquer si vous faites trop d'erreur.

Si le certificat est déjà présent, il peut simplement lancer le renouvellement du certificat avec la commande certbot renew

Vous pouvez partir de cet exemple de script:

#!/bin/bash -x
# -x permet de debugger

# vérification de la présence des variables nécessaires
if [ -z "${CERTBOT_NAME}" ] ; then
    echo "La variable CERTBOT_NAME n'existe pas"
    exit 1
fi
if [ -z "${CERTBOT_DOMAIN}" ]; then
    echo "La variable CERTBOT_DOMAIN n'existe pas"
    exit 1
fi
if [ -z "${CERTBOT_MAIL}" ]; then
    echo "La variable CERTBOT_MAIL n'existe pas"
    exit 1
fi
if [ -z "${CERTBOT_IP}" ]; then
    echo "La variable CERTBOT_IP n'existe pas"
    exit 1
fi


# calcul du nom de machine
FQDN="${CERTBOT_NAME}.${CERTBOT_DOMAIN}"

# formule magique qui trouve le répertoire contenant les certificats généré par let's encrypt
# on cherche par find un répertoire de letsencrypt qui contient le fichier de certificat
# puis on filtre selon le nom de domaine demandé (présent dans le nom du fichier)
# avant d'extraire le nom du répertoire
REPLENC=$(find /etc/letsencrypt/live/ -name cert.pem | grep ${FQDN} | xargs dirname)
# si cette variable est vide il n'y a pas de certificat
# sinon, il y en a un

if [ -z $REPLENC ];
then
    echo "Mon rep $REPLENC n'existe pas on demande le certificat"
    # A REMPLIR, il faut demander le nom DNS et générer le certificat
    
else
    echo "Le repertoire $REPLENC existe alors on ne fait qu'un renouvellement"
    certbot renew
fi;

Configuration de nginx pour faire du SSL

Pour changer de port, ce serveur va utiliser le protocole https au lieu de http. Pour permettre cela, je vous donne la configuration de base de nginx en tant que serveur https ainsi que les 2 fichiers de certificat et de clef secrète nécessaires. Ces fichiers doivent être bindés avec les fichiers utilisés par nginx pour initier le protocole SSL (voir les champs ssl_certificate_key et ssl_certificate de la configuration de nginx.

Voia la configuration qui remplace la partie serveur écoutant sur le port 80 :

 server {
           # ecoute sur le port 443 et activation du SSL
           listen       443 ssl;
    	   server_name  localhost;
           # nom di fichier de certificat
 	   ssl_certificate /etc/nginx/certif.crt;
           # nom du fichier de clef secrette
	   ssl_certificate_key /etc/nginx/clef.key;

           location /CHEMINQUEVOUSVOULEZREDIRIGER {
              # attention le / à la fin de la ligne suivante est important.
              # sans lui, l'adresse http://IPVM/truc/ est envoyée sur http://.../truc/ au lieu de http://.../
              proxy_pass http://METTEZCEQUEVOUSDEVEZICI/;
              # ces directive sont importante pour que nginx prévienne le site qu'il est derrière un reverse proxy
              # en ssl
              proxy_set_header Host $host;
              proxy_set_header X-Real-IP $remote_addr;
	      proxy_set_header X-Forwarded-For $remote_addr;
	      proxy_set_header X-Forwarded-Proto $scheme;
           }
           ...

doivent être associées au proxy_pass.


1)
mariadb est un fork de mysql qui est apparu après le rachat de l'entreprise par la firme oracle, il est très proche de mysql et nous ne l'utiliserons pas ici
2)
il vaut mieux être root pour cette question : sudo su
3)
ici il faut bien penser à changer le répertoire de données. En effet, la création de table et d'utilisateur n'est fait que si la base de données est nouvelle donc sans rien dans son répertoire de stockage
  • cloud/2022/tp_docker.txt
  • Dernière modification : 2022/09/30 10:05
  • de fabien.rico