TP sysres IMA5sc 2018/2019 G3

De Wiki d'activités IMA
Révision datée du 19 novembre 2018 à 21:20 par Aduqueno (discussion | contributions) (Seconde séance)

Première séance

Création des fichiers disque des conteneurs

On crée un fichier de 10 Gio = 10 240 * 1 Mio dont tous les octets sont égales à 0.


dd if=/dev/zero of=/home/pifou/containers/container1 bs=1024k count=10240


Création du système de fichiers

On associe un système de fichiers de type ext4 à notre fichier.


mkfs.ext4 /home/pifou/containers/container1


Montage du système de fichiers

On commence par créer les répertoires qui contiendront les rootfs montés. Dans un premier temps, on monte le système de fichiers précédemment créé dans /mnt/container1.


mkdir /mnt/container1

mkdir /mnt/container2

mkdir /mnt/container3

mount -t ext4 -o loop /home/pifou/containers/container1 /mnt/container1


Déploiement de l'arborescence Debian

Avant tout, on renseigne le proxy de l'école dans la variable d’environnement correspondante afin qu'on puisse télécharger les paquetages sur le miroir devuan extérieur à l'école.



Ensuite on utilise l'outil deboostrap dans /mnt/container1 pour créer un système Debian de base.


debootstrap --include=vim,nano,apache2 stable /mnt/container1


Puis on renseigne le fichier fstab de notre container1, il s'agit du fichier qui indique comment les systèmes de fichiers doivent être montés.


echo "proc /proc proc defaults 0 0" >> /mnt/container1/etc/fstab


Enfin, on peut démonter la partition


umount /mnt/container1


Une fois que nous avons déployé tout ce dont nous avons besoin au sein du container1 il ne reste plus qu'à dupliquer ce fichier deux fois, et on aura trois partitions utilisables pour nos conteneurs.


cp /home/pifou/containers/container1 /home/pifou/containers/container2

cp /home/pifou/containers/container1 /home/pifou/containers/container3


Ensuite on peut monter les trois systèmes de fichiers.


mount -t ext4 -o loop /home/pifou/containers/container1 /mnt/container1

mount -t ext4 -o loop /home/pifou/containers/container2 /mnt/container2

mount -t ext4 -o loop /home/pifou/containers/container3 /mnt/container3


Configuration des interfaces réseau

Pour l'instant, on a tout ce qu'il faut pour lancer les conteneurs, seulement ils seraient bien inutiles s'ils ne pouvaient aucunement communiquer entre eux ou avec le système hôte. C'est pourquoi on va créer dans le système hôte 4 interfaces virtuelles pour les 3 conteneurs (un conteneur aura deux interfaces virtuelles dont l'une sera dans le bridge donnant accès à internet, il s’agira de notre conteneur qui agira comme serveur mandataire inverse). On va donc créer un commutateur virtuel dans lequel on mettra les trois interfaces virtuelles vif1, vif2 et vif3 de nos trois conteneurs.

Création du bridge


ip link add monpetitpont type bridge


Création des 4 interfaces virtuelles


ip link add vif1 type veth peer name eth0@vif1

ip link add vif2 type veth peer name eth0@vif2

ip link add vif3 type veth peer name eth0@vif3

ip link add vif4 type veth peer name eth1@vif4


Connexion des interfaces virtuelles aux commutateurs virtuels

vif1 vif2 et vif3 sont mises dans monpetitpont, tandis que vif4 est mise dans bridge


ip link set vif1 master monpetitpont

ip link set vif2 master monpetitpont

ip link set vif3 master monpetitpont

ip link set vif4 master bridge


Il ne faut pas omettre d'activer les interfaces, sans quoi la communication serait impossible.


ip link set vif1 up

ip link set vif2 up

ip link set vif3 up

ip link set vif4 up


On pense à ajouter une adresse IP au commutateur virtuel, même si ce n'est pas obligatoire.


ip a add dev monpetitpont 192.168.1.1/24

ip link set monpetitpont down

ip link set monpetitpont up


Lancement et configuration réseau des 3 conteneurs

Lancement des conteneurs

Pour ce faire, on va utiliser l’utilitaire unshare permettant de lancer des programmes avec des espaces de noms différents de ceux du parent.


unshare -n -u -p -f -m chroot /mnt/container1 /bin/sh -c "mount /proc ; /bin/bash"


On avait créé dans la partie précédente des paires d'interfaces virtuelles connectées entre elles. Les vif ont été reliés à monpetitpont, il faut maintenant connecter les autres parties aux conteneurs pour qu'ils puissent communiquer entre eux bien qu'ils aient des des espaces de noms différents. Tout ceci aura pour effet de faire apparaître une interface nommée eth0 pour chaque conteneur et une interface eth1 pour le dernier conteneur.


ip link set eth0@vif1 netns /proc/<PID_unshare_c1>/ns/net name eth0

ip link set eth0@vif2 netns /proc/<PID_unshare_c2>/ns/net name eth0

ip link set eth0@vif3 netns /proc/<PID_unshare_c3>/ns/net name eth0

ip link set eth1@vif4 netns /proc/<PID_unshare_c3>/ns/net name eth1


Les différents PID sont récupérés simplement grâce à la commande suivante.


ps aux | grep unshare


On est maintenant en mesure d'attribuer des IPs pour nos conteneurs.


ip addr add 192.168.1.2/24 dev eth0

ip addr add 192.168.1.3/24 dev eth0

ip addr add 192.168.1.4/24 dev eth0


A nouveau, il est nécessaire d'activer les interfaces eth0 de nos 3 conteneurs.


ip link set eth0 up


Nous devons mettre une adresse ip à l'interface eth1 du container3 qui se trouve dans le bridge. Pour se faire, il faut trouver une adresse ip dans le réseau 172.26.145.0/24 (on ping pour voir si une adresse est libre)


ip addr add 172.26.145.150/24 dev eth1


Nous sommes maintenant en mesure de pinger les conteneurs entre-eux mais également les machines de la salle avec le conteneur 3 et son interface eth1 dont l'autre morceau est connecté au bridge de la machine.

Seconde séance

Nous allons créer des sous-domaines du domaine plil.space mis à notre disposition chez Gandi.

Tout d'abord nous créons une entrée de type "A" avec comme nom "durotduq.plil.space" et qui pointe vers 172.26.145.150. Ensuite, nous ajoutons deux entrées CNAME "durotduq1" et "durotduq2" avec comme valeur "durotduq". Bien qu'au final tous ces sous-domaines dirigent vers 172.26.145.150, le reverse proxy sera quand même en mesure de distinguer les requêtes entrantes et de les dispatcher vers les services concernés selon le sous-domaine.

10h15 => Serveurs Web unshare OK

Sur le conteneur mandataire inverse, on applique la configuration suivante dans le fichier /etc/apache2/sites-enabled/000-default.conf.

<VirtualHost *:80>
ServerName durotduq1.plil.space ServerAdmin webmaster@localhost
ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined
ProxyPass / http://192.168.1.101/ ProxyPassReverse / http://192.168.1.101/ ProxyRequests Off
</VirtualHost>
<VirtualHost *:80>
ServerName durotduq2.plil.space ServerAdmin webmaster@localhost
ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined
ProxyPass / http://192.168.1.102/ ProxyPassReverse / http://192.168.1.102/ ProxyRequests Off
</VirtualHost>

192.168.1.102 et 192.168.1.101 étant les adresses IP des conteneurs 1 et 2 dans monpetitpont. S'agissant d'adresses privées, elles sont donc non accessibles depuis l'extérieur et par conséquent toute connexion se fera par le biais du serveur mandataire inverse.

Réalisation avec Docker

Notre architecture de conteneurs from scratch fonctionne mais elle a l'inconvénient d'être relativement longue à installer et peu pratique. De plus, sans un minimum de scripting, les configurations ne peuvent être pérennisées. Ainsi, nous devions tout refaire à la main à chaque fois.

Dans la pratique, on préférera utiliser Docker comme système de gestion de conteneurs, car il permet d’une manière simple de manipuler et gérer les conteneurs. Il permet également que les configurations soient durables et offre la possibilité de gérer différentes version pour une même image et même de les distribuer.

Nous allons donc réaliser exactement la même architecture mais cette fois-ci à l'aide de Docker. Nous partirons sur la base d'une image Debian.

Lancement d'un conteneur Docker à partir de l'image debian

docker run -it debian /bin/bash

Export du proxy

export http_proxy=http://proxy.polytech-lille.fr:3218

Mise à jour de la liste des paquetages en local puis installation des paquetages vim, nano et apache2

apt-get update && apt-get install vim nano apache2

Maintenant, nous pouvons faire un commit des fichiers de ce conteneur, de cette manière, nous aurons une nouvelle image sur laquelle on pourra instancier des conteneurs.

Pour pouvoir réaliser ce commit, il faut connaitre l'identifiant du conteneur :

docker ps
docker commit 7e456 myapache2

A cet instant, nous avons une image myapache2 basée sur Debian avec les paquetages listés précédemment. La présence de cette image se vérifier avec la commande suivante.

docker images

Maintenant que nous sommes en mesure de lancer 3 conteneurs identiques contenant un serveur web Apache 2, nous créons un réseau Docker pour interconnecter les conteneurs. Sans précision de l'option --driver, il s'agit par défaut d'un bridge, ce que nous voulons.

docker network create pontpont

Nous pouvons à présent lancer les 3 conteneurs en spécifiant leur réseau d'attache et sans oublier d'exposer le port 80 du conteneur reverse proxy en le rendant accessible depuis le port 80 de la machine. Il faudra donc veiller à changer l'entrée DNS de type A avec l'IP de la zabeth (172.26.145.37).

docker run --net pontpont -i -t myapache2 /bin/bash
docker run --net pontpont -i -t myapache2 /bin/bash
docker run --net pontpont -p 80:80 -i -t myapache2 /bin/bash

La suite est très similaire à ce qui a été fait en première partie.

On repère les IPs des conteneurs 1 et 2 pour pouvoir adapter la configuration d'Apache 2 et on change la valeur de l'entrée DNS de type A durotduq.plil.space avec l'IP de la zabeth.

Le résultat final est bien évidemment identique, la solution moins formatrice certes mais plus pratique et utilisée en production.

12h10 => Serveurs Web docker OK