Utilisation de Docker
En plus de la machine virtuelle nous allons utiliser docker pour séparer les différententes applications. Le but de ce TP est d'installer 4 conteneurs :
- un docker
nginx
en tant que proxy inverse, il assurera la répartition des requêtes http sur les différents conteneurs; - deux dockers
apache
pour avoir un premier site web/php et de l'équilibrage de charge entre les deux. - un docker mysql pour stocker les données du site web.
Création de l'instance de travail
Vous devez créer une machine virtuelle, mais cette fois sans utiliser de volume. Créez une instance :
- avec la flavor
xsmall
- choisissez la source
boot from image
- et l'image ubuntu 16.04
I. Installation de docker
Vous devez installer docker sur votre VM, il y a 2 version de docker utilisable sur ubuntu : docker.io un paquet directement instalable via apt-get
et docker-engine qui demande de suivre une procédure décrite ici. docker-engine contient en plus de docker les utilitaire pour faire de l'orchestration que vous utiliserez dans les TPs suivants.
- Installez docker-engine.
Docker n'est pas encore fonctionnel dans cet environnement, car il a besoin d'accéder au réseau et il faut le configurer pour utiliser le proxy de l'université. Cette configuration n'est pas simple car elle doit modifier le service docker de la machine et dépend donc du gestionnaire de service. Elle n'est nécessaire que dans des réseaux utilisant un proxy comme celui des machines virtuelles de notre université. Elle n'est pas nécessaire si docker est installé sur une machine ayant directement accès au réseau (comme votre PC). La configuration est expliquée ici. Vous pouvez suivres bêtement les instructions suivantes (qui ne seront pas expliquées car hors du champ de ce TP).
- Créez un répertoire pour stocker les configurations du service docker
mkdir -p /etc/systemd/system/docker.service.d
- Créez un fichier de configuration
/etc/systemd/system/docker.service.d/http-proxy.conf
contenant :
[Service] Environment="HTTP_PROXY=http://proxy.univ-lyon1.fr:3128/"
- relancer le gestionnaire de service
systemctl daemon-reload
- Vérifier que la modification est prise en compte
systemctl show docker # la liste des options doit contenir un élément Environment="HTTP_PROXY=http://proxy.univ-lyon1.fr:3128/"
- Relancer le service
docker
systemctl restart docker
- Vous pouvez normalement utiliser docker par exemple en recherchant un docker contenant un serveur sql:
docker search mysql
II. 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 list des dockers fournissant
nginx
, (commandedocker 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 docker hub. 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 stable et la dernière version alpine-stable ? <hi #f3f3f3>Regardez les Dockerfiles</hi>
- Téléchargez l'image de la dernière version stable (
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 esttest
et faites en sorte que la machine virtuelle renvoie le port 80 et le port 443 sur ce docker (commandesdocker run -d …
oudocker create
puisdocker 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 contenantcoucou
. - Sortez du docker et essayer de retrouver le fichier sur la VM. Pour cela,
- Avec docker.io vous pouvez utiliser
docker inspect
pour voir où sont stockées les données du docker. Je vous recommande de vérifier le contenu des variables :LowerDir, MergedDir, UpperDir
etWorkDir
. Comparez ces 3 répertoires et essayez de comprendre d'où vienne l'essentiel des fichiers du docker, où se trouve les modifications et dans quel répertoire sont exécuté les processus du docker. - Avec docker-engine vous pouver rechercher le fichier
toto
dans le système de fichier des docker :
find /var/lib/docker/ -name “toto”
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.
- Copiez le répertoire
/etc/nginx
du dockertest
dans le répertoire/docker/nginx/config
de la VM (commandedocker cp …
) - Supprimez le docker
test
(commandedocker rm …
) - Recréez un docker dont le nom est
nginx
, le hostname estnginx
, qui partage les mêmes ports que le précédant et dont le répertoire/etc/nginx
correspond au répertoire/docker/nginx/config/
de la VM. - 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 (commandedocker 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 fichier partagés car beaucoup d'erreurs sont faites durant le partage).
Vous trouverez ici une explication de l'erreur la plus courante.
Lorsque tout fonctionne, vous pouvez passer à la section suivante.
III. Installation d'un docker apache
Il existe des dockers apache tout fait, mais il sont basés sur des versions minimalistes et il est alors difficile
de rajouter des modules. Vous allez donc utiliser un docker ubuntu (vivid). Pour cela vous allez utiliser une
seconde façon de créer une image docker, le faire à partir 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
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
, php5-ldap
, php-auth
, php5-mysql
et php5-common
.
- 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
- 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 le réseau des machines virtuelle est derrière un firewall, vous devez donc utiliser un tunel ssh, ou un client locale à la VM comme
telnet
2). - 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. - Testez le site avec un fichier php contenant :
<?php phpinfo(); ?>
phpinfo
affiche entre autre les variables du serveur (tableau$_SERVER
). Quel est l'adresse du serveur ? Le chemin utilisé ? L'adresse du client ?
IV. Utilisation du réseau
<hi #99d9ea>Vous devez rendre un rapport expliquant votre travail durant ce TP avant mardi 1/11/16 23h42 UTC. Pour chaque questions, votre rapport doit mentionner les commandes utilisées pour faire les configurations, les fichiers modifiés et les résultats obtenus. </hi>
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
.
- Vous devez tout d'abord créer un réseau utilisateur via la commande
docker network create …
. Attention, il faut utiliser l'optionsubnet
pour définir le réseau. Créer un réseau de nominterne
et utilisant le reseau 172.18.100.0/24. - Supprimez le docker apache puis recréez 2 nouveaux dockers utilisant le réseau
interne
(option–network
ou–net
selon la version de docker) et en attribuant 2 adresses (option- -ip
) :- un docker appelé apache1 utilisant l'adresse 172.18.100.10;
- un docker appelé apache0 utilisant l'adresse 172.18.100.11;
Ces 2 dockers doivent partager le volume /var/www/html/
sur le repertoire /docker/apache/html
de l'hôte.
- Supprimez le docker nginx puis recréez le en ajoutant à son fichier hosts les dockers apache avec leurs adresses (option
–add-host
). - Ajoutez nginx au réseau interne (commande
docker network connect …
). - Verifiez que nginx puisse contacter les deux dockers apache (avec un ping). La VM peut-elle contacter ces dockers ? Une autre VM le peut-elle ?
- Vous devriez pouvoir configurer le docker pour utiliser le serveur
http://apache1/
afin d'envoyer les requètes pour l'adresse/site1
(respectivementhttp://apache2/
pour/site2
).
V. Comment travailler depuis chez vous ?
Cette série de questions n'a pas vraiment de rapport avec le TP mais vous donnera les bases pour travailler vos TPs depuis chez vous. Pour être en conditions réelles, si vous en avez la possibilité (et pour cette série uniquement) utilisez un partage de connexion de votre téléphone.
Pour travailler vous devez pouvoir :
- contacter une page web interne comme http://cloud-info.univ-lyon1.fr;
- vous connecter sur des machines distantes pour exécuter des programmes;
- vous connecter à des serveurs distants protégés par le firewall de l'université (oracle, serveur ssh des VM, …).
Utilisation du "vpn" proposé aux étudiants
Ce n'est pas vraiment un vpn, mais un simple site avec des applications en javascript pour faire des connexions de base. Je ne pense pas qu'il permettra de tout faire, mais il vaut mieux le connaître. Il est à l'adresse https://vpn.univ-lyon1.fr/.
* utilisez-le pour ouvrir le site web de votre VM.
* utilisez le pour ouvrir une session ssh sur votre VM.
Cette partie supposait que le VPN des étudiants contient des services utiles, ce qui ne semble pas le cas.
Utilisation d'un tunnel ssh
Tous ce que vous voulez faire peut être fait grâce à des tunnels ssh. C'est donc une technique à maitriser même si ce n'est pas la plus pratique.
Voir ici une explication de ce qu'est un tunnel et comment ils se mettent en place (voir aussi là). Pour vous connectez de l'extérieur, vous pouvez utiliser la machine linux linuxetu.univ-lyon1.fr
qui est une simple passerelle.
- Utilisez
linuxetu
pour vous connecter à l'université. - Utilisez 2 connexions ssh de votre machine sur
linuxetu
puis delinuxetu
sur votre VM. Attention, pour se connecter à la VM il faut utiliser une clef ssh, or cette clef n'est pas surlinuxetu
. Il faut donc utiliser l'agent ssh et la capacité de transférer l'agent via une connexion. Commandessh-add
pour ajouter une clef à l'agent et option-A
lors de la connexion à ssh pour transférer l'agent. - Mettez en place un tunnel de votre machine de travail vers
linuxetu
entre le port local 19222 et le port ssh de votre VM. Il doit vous permettre d'ouvrir plusieurs connexions ssh de votre machine de travail vers votre VM directement. Dans votre rapport, en plus de la commande pour ouvrir le tunnel et tester les connexions, dites bien à quoi correspondent les valeurs des options et lesquelles doivent correspondre entre elles. - Utilisez de plus ce tunnel pour copier un petit fichier de votre machine de travail vers la VM. Attention, scp est assez sensible, il faut que l'option du port utilisé
-P
soit placée juste après la commandescp
, il est aussi possible d'utilsier des outil graphique pour la copie (voir le premier TP).
Cela ne permet pas d'aller sur des pages web facilement, mais vous pouvez utiliser un proxy en plus d'un tunnel pour naviguer sur internet en passant par le réseau de l'université.
- Mettez en place un tunnel entre votre machine et le serveur
proxy.univ-lyon1.fr
port 3128. Configurez votre navigateur pour utiliser le proxy via le tunnel. Dans votre rapport mettez bien la commande pour mettre en place le proxy et les configurations du navigateur.
<hi #ed1c24>Attention</hi>, il faut penser à supprimer la configuration du proxy lorsque vous supprimer le tunnel ou que vous changer de réseau. Sinon, votre navigateur ne fonctionne plus.
[Si vous êtes en avance] Utilisation d'un tunnel dynamique et d'un proxyfieur
La méthode précédente permet de faire a peut près tous, mais elle est parfois laborieuse. En effet, il faut un tunnel par application et il faut modifier les configurations des logiciels clients. L'utilisation du proxy est plus souple, mais elle est limitée aux protocoles du web car en général les proxy ne laissent passer que ce type de flux. Ssh permet aussi de mettre en place des tunnels dynamiques socks5
c'est à dire un proxy au niveau de la connexion TCP. Grâce à ce type de tunnels on peut utiliser la connexion ssh pour transporter n'importe quoi. Pour que cela fonctionne, il faut que le logiciel client soit capable de faire l'opération de discussion avec le proxy socks. C'est pour cela qu'on a besoin d'un proxyfieur c'est à dire un logiciel qui permet de transformer n'importe quelle application en client d'un proxy socks. Ici nous allons utiliser proxychains4
- Sur votre machine de travail installez proxychains4
- sur le fichier
/etc/proxychains.conf
remplacer le point d'entrée du proxy
# defaults set to "tor" socks4 127.0.0.1 9050
par le point d'entrée d'un tunnel dynamique ssh (ici j'utilise 9022 ce qui est totalement arbitraire). socks5 127.0.0.1 9022
- Créer ce tunnel avec l'option
-D
de ssh
ssh -D 9022 p???????@linuxetu.univ-lyon1.fr
A partir de ce moment, une application lancée précédée de la commande proxychains4
utilise le proxy. Les autres ne l'utilisent pas. Par exemple :
> proxychains4 scp toto.gz ubuntu@192.168.246.87: # copie le fichier local toto.gz sur le compte ubuntu du serveur 192.168.246.87 accessible # depuis linuxetu (c'est sans doute une VM) elle passe par le tunnel et fonctionne depuis n'importe quel endroit. > scp toto.gz ubuntu@192.168.246.87: # copie le même fichier sur le compte ubuntu du serveur 192.168.246.87 accessible # depuis la machine où vous travaillez (ce qui ne fonctionnera sans doute pas chez vous).
VI. Equilibrage de charge
Nous allons configurer nginx
pour répartir des requêtes sur les 2 dockers apache. La documentation de l'équilibrage de charge de nginx est ici
- En modifiant la configuration de votre docker nginx (fichiers
nginx:/etc/nginx/conf.d/default.conf
etnginx:/etc/nginx/nginx.conf
) renvoyez les requêtes vers la racine du site/
sur les deux dockers apache1 et apache2 en alternant le serveur effectivement contacté. <hi #ed1c24>Attention</hi>, la partieupstream
doit allez dans le fichiernginx.conf
, la partielocation
dansdefault.conf
. - Testez la répartition de charge en ajoutant dans les deux serveurs apache le fichier
test.php
contenant :
<?php echo "<pre>".print_r($_SERVER, true)."</pre>"; ?>
- Quelle(s) variable(s) permet(tent) de savoir le docker qui est finalement contacté ?
Dans votre rapport vous joindrez le fichier nginx:/etc/nginx/conf.d/default.conf
et nginx:/etc/nginx/nginx.conf
VII. Installation d'une application
Vous devez installer une petite application tiny. C'est un mini framework en php. Il utilise une base de donnée mysql (que vous mettrez, bien sûr, dans un docker à part).
- Récupérez le zip du projet sur votre VM https://github.com/panique/tiny ou ici et installez le dans le répertoire des serveurs apache. Le projet doit faire une erreur lors de la connexion à la base de donnée car cette dernière n'existe pas encore.
- Télécharger l'image mysql (la dernière) et lancer un docker qui :
- est dans le réseau interne
- utilise l'adresse 172.18.100.3
- s'appelle mysql (nom du docker et hostname)
- utilise votre numéro étudiant comme mot de passe root (regarder sur la description du docker mysql dans le docker hub pour apprendre comment on fait)
- Recréez les dockers apache1 et apache2 pour qu'ils connaissent l'adresse de la base de donnée sous le nom
mysql
en utilisant l'option–add-host
à la création (n'oubliez pas de les relancer). Modifiez le fichier de configurationtiny/application/config/config.php
pour lui donner les bonnes valeurs pour la base de données. - Vous devez remplir la base de données grâce au 3 scripts qui sont dans le répertoire
_installation
du projet. Pour cela il faut utiliser la commande (exécutez cette commande sur la VM après avoir installé le paquetmysql-client
) :
mysql -u root -p -h adr_ip_de_mysql < nom_du_fichier_script.sql
- Testez le site :
- Si vous obtenez une erreur
403 forbidden you don't have permission to access /tiny-master/ on this server
allez ici pour une explication. - Si vous obtenez une page vide allez ici pour une explication.
- Si vous obtenez une page qui commence par
Everything in this box is loaded from application/views/_templates/header.php !
passez à la question suivante.
- Le site ne fonctionne pas vraiment. En fait toutes les urls sont fausses car elles utilisent l'adresse du docker et non pas celles du site. Cela est dû à l'utilisation de la variable
$_SERVER['HTTP_HOST']
dans la construction de l'url du domain3). Pour corriger le problème, il faut demander à nginx de modifier cette valeur pour qu'elle soit exacte. Pour cela utiliser les optionsproxy_set_header
expliquées ici.
Le site doit être [un peu] plus joli, et surtout les urls doivent fonctionner. Testez l'application song en ajoutant une chanson. Cela doit fonctionner malgré l'équilibrage de charge.
- Dessinez le shema de fonctionnement final du service, mentionnant la VM et les 4 dockers (où arrivent les requètes de l'extérieur, qui est connecté avec qui …).
- Pourquoi n'utilise-t-on qu'un seul docker mysql ? Que faudrait-il faire pour en utiliser plusieurs avec de l'équilibrage de charge ?
#ServerName .*
dans le fichier /etc/apache2/sites-enabled/000-default.conf
telnet
, il faut taper la commande telnet adresse_du_site 80
puis une fois la connexion étable taper GET /
tiny/application/config/config.php