====== Utilisation de Docker====== ====0. Remarques==== ===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 3 conteneurs : - un docker ''nginx'' en tant que proxy inverse, il assurera la répartition des requêtes http sur les différents conteneurs; - 1 dockers ''apache'' pour avoir un premier site web/php. - un docker mysql pour stocker les données du site web. ===Avant de commencer=== Si pour ce TP vous ne disposez pas d'une machine avec docker installé, vous pouvez utiliser le //snapshot// ''snap-docker-ready'' qui est une machine avec docker pré-installé et configuré. ====I. Installation d'un docker nginx==== Comme pour beaucoup de serveurs connus, il existe un docker officiel qui permet l'installation de ''nginx'' très simplement. Pour cela vous allez simplement télécharger l’image et créer un docker dont le répertoire de configuration sera partagé avec l’hôte. Dans votre rapport, vous noterez chaque commande faite pour effectuer les installations et configurations. * Recherchez la liste des dockers fournissant ''nginx'', (commande ''docker search'') vous verrez qu'ils sont classés par défaut grâce à un système de recommandation via des étoiles. * Recherchez de la même manière sur le site [[https://store.docker.com/|docker store]]. Ce site donne plus de détails notamment les différentes versions pour une image, les ''Dockerfile''... * Comment reconnait-on la dernière version ? * Quels sont les différences entre la version //mainline// et la dernière version //mainline-perl// ? Regardez les Dockerfiles * Téléchargez l'image de la dernière version //mainline// (''docker pull ...'') * 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 le nom est ''test'', dont le hostname est ''test'' et faites en sorte que la machine virtuelle renvoie le port 80 et le port 443 sur ce docker (commandes ''docker run -d ...'' ou ''docker create'' puis ''docker start'') * Testez si le docker fonctionne et répond sur le port 80 de la VM * 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 ...'' notament la partie ''Data''. Que représentent les répertoires ''MergedDir'' et ''UpperDir'' et ''LowerDir'' ? Vous avez peut-être remarqué que les outils les plus courants (nano, vim, emacs ...) ne font pas parti du docker //nginx// ce qui rend difficile la modification des fichiers dans le docker. Pour résoudre le problème, on peut : - Pré-configurer le docker via le ''Dockerfile'' ou les outils de création (voir plus tard); - Installer dans le docker votre éditeur préféré; - Copier des fichiers entre la VM et le docker; - Partager des répertoires entre la VM et le docker. Nous allons utiliser la dernière méthode dans ce cas pour gérer les configurations de ''nginx'' qui sont dans le répertoire ''/etc/nginx'' du docker, mais pour cela il faut recréer un docker. * **Avant de le supprimer** Copiez le répertoire ''/etc/nginx'' du docker ''test'' dans le répertoire ''/docker/nginx/config'' de la VM (commande ''docker cp ...'') * Supprimez le docker ''test''(commande ''docker rm ...'') * Recréez un docker dont le nom est ''nginx'', le hostname est ''nginx'', qui partage les mêmes ports que le précédent et dont le répertoire ''/etc/nginx'' correspond au répertoire ''./docker/nginx/config/'' de la VM. **Attention** le contenu précédent du répertoire du docker ''test'' doit **exactement** remplacé le contenu du répertoire ''/etc/nginx'' du nouveau docker. Cela dépend de la manière dont vous l'avez copier. La commande à taper n'est donc pas forcement identique à celle de votre voisin. * Pour vérifier que cela fonctionne bien, modifiez la configuration des logs de nginx depuis la VM (fichier ''/docker/nginx/config/nginx.conf''), relancer le docker (''docker restart ...''), afficher les logs dynamiquement (commande ''docker logs -f nginx'') et générer un log en utilisant le navigateur pour demander une page inexistante. Si vous avez des problèmes de fonctionnement, testez : - les //logs// du docker avec la commande ''docker logs nomdocker'' - le contenu des fichiers utilisés par le docker (surtout s'il s'agit de fichiers partagés car beaucoup d'erreurs sont faites durant le partage). Vous trouverez [[http://perso.univ-lyon1.fr/fabien.rico/site/cloud:tp_cloud_faq#avec_le_partage_le_docker_nginx_ne_demarre_pas|ici]] une explication de l'erreur la plus courante. Lorsque tout fonctionne, vous pouvez passer à la section suivante. ====II. Installation d'un docker apache==== Le but ici est de voir comment créer une image docker personnalisée via la construction d'image : ''docker build ...''. //Apache// est le plus populaire des serveur de site web. Il est souvent associé à //php// et vous allez devoir créer une image contenant ces deux modules et capable de dialoguer avec une base de données. Il existe des dockers //apache// prêts à l'emploi, mais il sont(site web) basés sur des versions minimalistes et il est alors difficile de rajouter des modules. Vous allez donc utiliser un docker basé sur une distribution standard : //ubuntu (xenial)//, et modifier l'image via l'utilisation d’un ''Dockerfile''. Un ''Dockerfile'' est un fichier décrivant à partir d’une image de base la suites des actions à réaliser pour créer une nouvelle image ainsi que l’environnement dans lequel sera exécuté le conteneur. A partir du fichier {{ :cloud:dockerfile_apache.zip |Dockerfile fourni}}, vous allez écrire un nouveau fichier pour construire une image qui contient apache et le lance par défaut avec les modules ''php-pear'' , ''php-ldap'', ''php-auth'', ''php-mysql'', ''php-common'', ''libapache2-mod-php''. * Construisez une première image (nommée ubuntuapache:v0) sans modifier le fichier, vous pourrez utiliser cette image pour tester les commandes. * Modifiez le fichier ''Dockerfile'' * pour installer les modules nécessaires; * pour activer l'affichage des erreurs //php// [[http://perso.univ-lyon1.fr/fabien.rico/site/cloud:tp_cloud_faq#l_application_tiny-master_affiche_une_page_vide|voir ici]] pour une explication de la raison et de la commande sed à faire dans le docker. * Lancez un docker dont le répertoire principale d’apache ''/var/www/html/'' est partagé avec l’hôte ''/docker/apache/html/''. Ne faites pas de partage de port. * Quel est l'adresse de ce docker ? (via la commande ''docker inspect ...''') * Testez le fonctionnement du serveur. Attention, ce dernier ne peux pas être contacté directement depuis votre PC car vous n'avez pas partagé de port entre le docker et la VM, vous devez donc utiliser soit un tunnel ssh, soit un client local à la VM comme ''telnet''((pour tester un site web avec ''telnet'', il faut taper la commande ''telnet adresse_du_site 80'' puis une fois la connexion étable taper ''GET /'')). Les clients //évolués// comme //wget// ou //curl// peuvent ne pas être valident car ils utilisent automatiquement les serveurs proxy définis par le système. * Configurez //nginx// pour que le chemin ''/site'' soit envoyé sur le serveur apache en utilisant le ''proxy_pass'' du serveur nginx et l'adresse IP du docker apache. Vous trouverez [[https://www.nginx.com/resources/admin-guide/reverse-proxy/| ici une documentation sur la configuration de nginx]] en tant que reverse proxy. * Testez le site avec un fichier php contenant : ".print_r($_SERVER, true).""; ?> * Ce code php affiche les variables du serveur (tableau ''$_SERVER''). Quel est l'adresse du serveur ? Le chemin utilisé ? L'adresse du client ? ====III. Utilisation du réseau==== Comme vous l'avez vu, il est possible d'utiliser les adresses IP attribuées par le service docker pour configurer les liaisons entre ces derniers, mais ces adresses peuvent changer. Cela peut poser des problèmes par exemple lorsque vous devez réutiliser un docker préparé dans un certains contexte. Pour simplifier la gestion, il est possible de choisir les adresses IP des dockers, de choisir la valeur de leurs variables d'environnement ou de paramétrer leur fichier ''/etc/hosts''. Pour cela : * 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 ''interne'' et utilisant le reseau 172.18.100.0/24. * Supprimez le docker //apache// puis recréez un nouveau docker utilisant le réseau ''interne'' (option '' network'' ou ''net'' selon la version de docker) et en attribuant l'adresses ''172.18.100.10'' (grâce à l'option ''ip''). Ce dockr doit avoir le nom ''php-votrenom''. De plus, ce docker doit partager le volume ''/var/www/html/'' sur le répertoire ''/docker/apache/html'' de l'hôte. * Supprimez le docker //nginx// puis recréez le en ajoutant à son fichier //hosts// le docker apache sous son nom avec son adresse IP (option ''add-host''). * Ajoutez //nginx// au réseau interne (commande ''docker network connect ...''). * Vérifiez que //nginx// est bien dans le même réseau que le docker apache (avec un ''docker inspect''). La VM peut-elle contacter ces dockers ? Une autre VM le peut-elle ? * Vous devriez pouvoir configurer le docker ''nginx'' pour envoyer les requêtes destinées à ''/site'' vers le docker apache. ====IV. Installation d'une application==== Vous allez terminer l'installation de votre site web en installant une application php/mysql et donc un serveur de base de données mysql. Cette application : //tiny// est un mini //framework// en php. Récupérez le zip du projet sur votre VM [[https://github.com/panique/tiny]] ou {{ cloud:2016:master.zip |ici}}. ===IV.1 Installation de mysql=== Bien sur vous allez utilisez un docker mysql, le plus facile à paramétrer n'est pas le docker officiel de l'entreprise //Oracle// mais celui proposé par //Docker//. Vous pouvez consulter sa documentation sur le [[https://store.docker.com/|docker-store]]. Il permet via l'utilisation d'une série de variable d’environnement de : * choisir le mot de passe de l'administrateur de la base ou de lui demander d'en créer un aléatoire; * créer un utilisateur avec son mot de passe; * créer une table sur laquelle l'utilisateur aura tous les droits; * pré-remplir la table grâce à des fichiers .sql exécutés au premier démarrage (pour cela il faut attacher un volume au docker contenant les fichiers sql). Vous devez créer un serveur à l'adresse 172.18.100.20 avec une base //tiny//, un utilisateur //usertiny// dont le mot de passe est //passtiny//. La base doit être pré-remplie avec les fichiers du répertoire ''_installation'' de l'archive et le mot de passe de l'administrateur doit être tiré au hasard. Attention de bien noter le mot de passe de la base et à bien utiliser le même réseau ''interne'' que celui des autres. Pour tester la base vous pouvez éventuellement utiliser un autre docker //phpmyadmin/phpmyadmin// ou directement des requêtes SQL. ===IV.2 Installation de tiny=== Dans le volume partagé avec vos dockers apaches (c'est à dire avec ''/var/www/html'' de ces docker), vous devez déplacer le fichier ''index.php'' précédent vers ''test.php'' et déplacer les fichiers de tiny (sauf le repertoire ''_installation''). Il faudra configurer le site pour utiliser la bonne base de donnée, une url correcte ... Tout se trouve dans le fichier : ''/application/config/config.php''. Testez est corrigez l'installation. Le site doit ressembler à [[http://192.168.76.57/|celui-ci]]. Ici ce trouve qq erreur courante l'année dernière : * Si vous obtenez une erreur ''403 forbidden you don't have permission to access /tiny-master/ on this server'' allez [[cloud:tp_cloud_faq#erreur_403_forbidden_pour_tini-master|ici]] pour une explication. * Si vous obtenez une page vide allez [[cloud:tp_cloud_faq#l_application_tiny-master_affiche_une_page_vide|ici]] pour une explication. * Si le site ne fait pas d'erreur mais n'affiche aucune image, propose une présentation bizarre, il y a de grande chance que les liens internes soient mauvais. Voir les [[cloud:tp_cloud_faq#probleme_de_liens_internes_dans_l_application|questions souvent posée sur le TP cloud]] pour une explication. ====V. Docker compose==== Docker compose est un outils permettant de créer plusieurs dockers, de les configurer selon les méthodes vue précédemment et de les administrer. Il se base sur un fichier ''docker-compose.yml'' et sur l'ensemble des fichier et répertoire qui permettraient de créer les dockers nécessaires, faire leur image, contenir les volumes partagés ... Tout se fait par une commande : ''docker-compose up'' qui s'occupe de créer les images nécessaire, de lancer les dockers dans le bon ordre en gérant les liens entre eux et éventuellement de mettre à jour les docker si une partie fonctionne déjà. Cela semble idéal, mais, cette commande est en grande évolution et tout ce que vous ferez dépendra fortement de la version (écrite en haut du fichier ''docker-compose.yml''). Ici, il faut utiliser des commande pour la **version 2.1** et bien sur consulter la [[https://docs.docker.com/compose/compose-file/compose-file-v2/|bonne documentation]] ! Avant de commencer, installez compose comme écrit [[https://docs.docker.com/compose/|ici]] ===Travail à faire=== Vous devez refaire l'ensemble des dockers précédents via docker compose en créant un répertoire contenant toute l’arborescence de fichiers nécessaire ainsi que le fichier de description. Il s'agit essentiellement de rassembler les différents répertoires faits aux questions I à IV et de créer un fichier ''docker-compose.yml'' comportant les options correspondant aux instructions //run// que vous aviez effectuées. Pour cela, je vous invite à consulter l'exemple du cours (qui //n'est pas dans la bonne version//((La différence entre la version 1 du cours et la 2 que vous allez utiliser se voit surtout par l'utilisation de sections. Par exemple dans ''services'' on déclarent les dockers et dans ''networks'' on déclare les réseaux))) , ceux donnés dans [[https://docs.docker.com/compose/compose-file/compose-file-v2/#networks|la documentation]] ((notamment ceux concernant la création d'un réseau en plus des services/dockers et ceux proposant plusieurs docker (ou services) avec un lien entre eux)). Les options intéressantes sont : - ''image'' ou ''build'' pour décrire la création des images; - ''networks'' dans un docker pour choisir son réseau et ''ipv4_address'' pour choisir son IP; - ''volumes'', ''ports'', ''environments'' pour gérer les partages de ports, de volumes ou les variables d'environnement des dockers; - ''links'' pour qu'un docker puisse en contacter un autre; - dans la configuration d'un réseau, ''driver'' et ''ipam'' pour définir la plage d'adresse utilisée par le réseau. ===Options imposées=== Pour éviter des perturbations avec ce qui a été précédemment crée sur la machine : - le fichier docker-compose doit être dans le répertoire ''/home/ubuntu/compose/'' - les dockers doivent utiliser le réseau ''rescomp'' dont l'adresse est ''172.20.20.0/24''; - le docker //nginx// aura l'adresse 5 du réseau; - les dockers //apache// l'adresse 10 et 11; - le docker //mysql// l'adresse 20; - les volumes partagés ou les répertoires de construction doivent tous être sous répertoire de ''/home/ubuntu/compose/''. - le mot de passe de root sur //mysql// doit être ''mdproot'' et l'utilisateur de la base utilisé doit être ''tiny'' avec un mot de passe ''mdptiny''