Le Raspberry Pi Zéro W (que je vais appeler rpi0w) est un modèle minimaliste du célèbre mini-ordinateur Raspberry Pi. La version minimaliste se distingue par son nombre plus faible de ports (pas d’USB-A ni de port ethernet, par exemple), sa taille plus réduite ainsi qu’une puissance diminuée par rapport à son grand frère.
Je vais expliquer ici comment le configurer pour qu’il se connecte directement au réseau wifi afin qu’on puisse s’y connecter en SSH dès qu’il est démarré.
Dans cet article, je vais configurer une répartition de charge qui va dispatcher le trafic vers 3 serveurs web nginx. Ces 4 serveurs sont tous hébergés sur des conteneurs docker.
Environnement
Ubuntu 19.10
Docker version 19.03.2
Attention : Toutes les commandes docker lancées ici le sont en tant qu’utilisateur root. Faites attention à ce que vous faites !
Situation cible
Le schéma ci-dessous indique la configuration cible.
Serveurs web nginx
La première étape consiste à créer un fichier index.html différent dans votre répertoire de travail, pour chaque serveur web, afin de pouvoir les identifier facilement lors des tests.
docker container run : Permet de lancer le conteneur. --rm : indique à docker de supprimer le conteneur ainsi que son système de fichiers. --name : donne un nom au conteneur. Si cette option n’est pas indiquée, un nom aléatoire sera donné. -v : indique les volumes à monter dans le conteneur. Dans ce cas-là, je monte en lecture (option ro à la fin) le répertoire www1, www2 ou www3 de mon hôte local à l’emplacement /usr/share/nginx/html du conteneur. Ce répertoire est le répertoire par défaut permettant de stocker les fichiers HTML servis par nginx. Il est important de mettre le chemin absolu pour identifier les répertoires locaux. -d : permet de détacher le conteneur du terminal actuel. Pour se connecter au conteneur par la suite, on utilise la commande docker container exec -it <nom_du_conteneur> /bin/bash. -p : mappe le port du host local sur le port du conteneur. nginx : indique quel modèle de conteneur utiliser.
Vérifications
Une fois que les 3 conteneurs sont lancés, on peut vérifier qu’ils sont bien lancés :
~fox/Documents/reverse-proxy $ docker container ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3daa11c28579 nginx "nginx -g 'daemon of…" 4 hours ago Up 4 hours 0.0.0.0:8083->80/tcp nginx3
0cc187ff28b4 nginx "nginx -g 'daemon of…" 4 hours ago Up 4 hours 0.0.0.0:8082->80/tcp nginx2
9239a53b4480 nginx "nginx -g 'daemon of…" 4 hours ago Up 4 hours 0.0.0.0:8081->80/tcp nginx1
La répartition de charge du trafic est également effectuée par un conteneur docker nginx. Pour les serveurs web, le fichier de configuration par défaut était suffisant, mais ce n’est pas le cas pour le loadbalancer. Il va donc falloir créer un fichier de configuration spécifique, et le rendre accessible au conteneur. En effet, ce n’est pas conseillé de modifier la configuration directement dans le conteneur, car celle-ci serait perdue en cas de redémarrage de celui-ci.
Fichier de configuration nginx
Les lignes importantes à modifier/ajouter sont les lignes 6 à 10 et 16 à 20.
Les premières permettent d’indiquer les serveurs destination de la répartition de charge. si aucune option n’est ajoutée avant la liste des serveurs, ils vont être choisis en mode round robin, donc les uns après les autres dans la liste. Il est possible une répartition selon le nombre de connexion (option least_conn;) ou encore un hash IP en fonction de l’adresse IP source utilisée (option ip_hash;). Il est également possible d’assigner un poids à chaque serveur, en indiquant l’option weight=x sur la même ligne que la déclaration du serveur.
Remarque : Pour récupérer l’adresse IP de chaque conteneur docker nginx, on peut utiliser la commande suivante :
Une fois que le fichier de configuration est correctement crée, on peut lancer le conteneur.
~/Documents/reverse-proxy $ docker container run --rm \
--name rp \
-v /home/fox/Documents/reverse-proxy/rp/nginx.conf:/etc/nginx/nginx.conf:ro
-d \
-p 80:80 \
nginx
Les options utilisées ici sont les mêmes que pour le lancement des serveurs web, à l’exception près qu’on ne mappe plus un répertoire sur un répertoire, mais un fichier sur un autre fichier.
Informations sur les conteneurs
Nom du conteneur
Adresse IP
Port en écoute
host
172.17.0.1
N.A.
nginx1
172.17.0.2
8081
nginx2
172.17.0.2
8082
nginx3
172.17.0.2
8083
rp
172.17.0.2
80
Vérifications
Une fois que le loadbalancer est lancé, on peut a nouveau vérifier que tous nos conteneurs fonctionnent bien.
~fox/Documents/reverse-proxy $ docker container ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fe66cd87549f nginx "nginx -g 'daemon of…" 3 hours ago Up 3 hours 0.0.0.0:80->80/tcp rp
3daa11c28579 nginx "nginx -g 'daemon of…" 4 hours ago Up 4 hours 0.0.0.0:8083->80/tcp nginx3
0cc187ff28b4 nginx "nginx -g 'daemon of…" 4 hours ago Up 4 hours 0.0.0.0:8082->80/tcp nginx2
9239a53b4480 nginx "nginx -g 'daemon of…" 4 hours ago Up 4 hours 0.0.0.0:8081->80/tcp nginx1
Maintenant, en se rendant à l’URL http://127.0.0.1, on peut observer qu’à chaque actualisation, on tombe sur un autre serveur web.
Conclusion
La prochaine étape est de mettre en place un monitoring de ces conteneurs. On génèrera du trafic vers le répartiteur de charge afin de vérifier que celui-ci répartit bien le trafic de manière équitable entre les serveurs (ou d’une autre manière, en fonction de la configuration).
De part mes études ou mon travail, j’utilise de temps en temps des machines virtuelles. Il m’est arrivé de devoir accéder à une carte SD branchée au PC hôte depuis la machine virtuelle, mais ce sera l’objet d’un autre article. Je vais donc vous expliquer comment faire, avec VMWare Workstation.