Créer un serveur de log avec Docker, Elastic Search, Kibana and Nginx : hébergement IaaS dans Azure [Part 1]
Dans mon précédent article, nous avons mis en place un serveur de log en utilisant Docker, Elastic Search, Kibana et Nginx. Dans cet article, nous allons nous concentrer sur l’hébergement ce dernier dans une machine virtuelle Azure.
Héberger une application “conteneurisé” dans Azure
Microsoft Azure propose plusieurs services permettant d’exécuter des applications avec des conteneurs Docker. Nous pouvons séparer ces offres en 3 types de service :
- CAAS (container as a service) : Azure container instances
- PaaS (platform as a service) : Azure Kubernetes service, Azure App Service, Azure Service Fabric,
- IaaS (infrastructure as a service) : Azure Virtual Machine
Dans cet article, nous allons utiliser la solution IaaS. L’hébergement IaaS nous permet d’avoir un control total sur notre infrastructure et nos conteneurs, c’est pourquoi nous allons nous intéresser à cette solution dans un premier temps. De plus, avec cette solution nous n’avons pas de dépendance forte avec Azure, nous pourrions parfaitement faire fonctionner notre serveur de log dans un machine virtuelle mis à disposition par un autre fournisseur de cloud.
Architecture Azure cible
Dans Azure, une machine virtuelle fonctionne au sein de réseau virtuel (vnet). Un groupe de sécurité (NSG pour network security group) peut être placé au niveau du réseau ou de la machine virtuelle et permet de gérer finement les flux entrant et sortant. Pour que notre serveur de log fonctionne, nous avons besoin d’ouvrir le port 80 de la machine virtuelle et deux outils doivent être installés sur cette dernière : Docker et Docker compose.
Overview de architecture cible:
Environnent de travail
Pour déployer notre serveur de log, nous avons besoin d’un script Shell (deploy.sh) dans lequel nous allons utiliser les commandes azure cli pour communiquer avec les API Azure. Nous possédons déjà un dossier « log_server » qui contient l’ensemble des fichiers Docker.
Capture d’écran de l’environnement de travail :
Script de déploiement
Dans l’idéal, le déploiement de notre serveur de log doit s’effectuer en un minimum d’étapes humaines. La logique de déploiement va donc être rédigée dans un seul script.
Le script de déploiement contient 3 étapes :
- Création de la machine virtuelle
- Installation des outils (Docker & Docker compose) sur la machine virtuelle
- Envoi du dossier “log_server” sur la machine virtuelle et exécution du serveur de log
Nous allons créer une fonction par étape (dans un souci de lisibilité et de simplicité, nous utiliserons des variables globales dans le script shell).
Variables
Le script va créer une machine virtuelle dans Azure, nous avons donc besoin d’un nom pour la machine, d’un emplacement géographique, d’un groupe de resource (conteneur logique dans Azure), d’un utilisateur SSH et d’un port d’entrée sur la vm.
Variables utilisées dans le script :
rgName='*****' vmName='****' vmUser='****' vmLocation='westeurope' vmOpenPort=80 #docker compose nginx opend port
Contenu du fichier .htpasswd
Dans l’article précèdent nous avons vu que le fichier .htpasswd doit contenir le login / password qui sera utilisé pour l’authentification basique. Les fichiers (Docker et le script de déploiement), vont être stockés à terme sur un contrôleur de code source, pour des raisons de sécurité évidente, nous ne voulons pas versionner des identifiants de connexion. Nous allons donc générer son contenu depuis le script dé déploiement et stocker un fichier .htpasswd vide sur le contrôleur de code source.
Nous pouvons stocker le couple login / mot de passe dans une variable du script et écrire le contenu de cette variable dans le fichier .htpasswd avec la commande « echo » :
passwordHash='tranise:$apr1$4t5rn1oy$G****************' echo $passwordHash > ./log_server/nginx/.htpasswd
1. Création de la machine virtuelle
Nous allons héberger notre serveur de log sur une machine virtuelle Linux (Ubuntu). La première étape du script consiste donc à créer cette machine. Pour cela, nous allons utiliser la commande az vm create *. Notre serveur de log doit être accessible sur le port 80, c’est pourquoi nous allons ouvrir ce port sur la machine en utilisant la commande az vm open-port.
Cette commande va créer l’ensemble des composants requis par notre machine virtuelle (un réseau virtuel, un compte de stockage et groupe de sécurité).
create_AzureVm(){ echo -- create the resource group az group create --name $rgName --location $vmLocation echo -- create the vm az vm create --resource-group $rgName --name $vmName --public-ip-address-dns-name $vmName --image UbuntuLTS --admin-username $vmUser --generate-ssh-keys echo -- open port $vmOpenPort on the vm az vm open-port --port $vmOpenPort --resource-group $rgName --name $vmName }
Nous utilisons l’option --generate-ssh-keys pour générer automatiquement les fichiers SSH (clefs privées et publiques) dans le répertoire ~/ssh.
2. Installation des outils Docker
Une fois la machine virtuelle créée, nous devons installer les outils Docker (Docker CE & Docker compose) sur cette dernière et démarrer le « deamon » docker. Pour ce faire, nous allons exécuter des scripts shell sur la machine distante en utilisant la commande az vm run-command. Cette commande nous permet de définir un script shell sur une ligne, qui sera uploadé puis exécuté sur la machine distante.
Code de la fonction qui installe les outils Docker :
install_DockerTools (){ echo install dependencies docker, docker compose and start docker service #install Docker az vm run-command invoke -g $rgName -n $vmName --command-id RunShellScript --scripts "curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - && sudo add-apt-repository 'deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable' && sudo apt-get update && apt-cache policy docker-ce && sudo apt-get install -y docker-ce" #install Docker Compose az vm run-command invoke -g $rgName -n $vmName --command-id RunShellScript --scripts "sudo curl -L https://github.com/docker/compose/releases/download/1.23.1/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose && sudo chmod +x /usr/local/bin/docker-compose" #start Docker service az vm run-command invoke -g $rgName -n $vmName --command-id RunShellScript --scripts "sudo service docker start" }
3. Exécuter le serveur de log
Les outils nécessaires au bon fonctionnement de notre serveur de log sont maintenant installés sur la machine. Nous allons dans un premier temps uploader le dossier « log_server » sur la machine distante avec l’outil SCP * (cet outils dernier permet de transférer des fichiers sur une machine distante en utilisant une connexion SSH). Dans un second temps, nous allons utiliser l’outil docker-compose pour exécuter notre serveur de log avec la commande az vm run-command.
Nous aurions pu utiliser deux autres méthodes pour transférer notre dossier :
- GIT
- Docker repository
Ces deux solutions fonctionnent parfaitement. Dans cet article j’ai choisi d’utiliser l’outil SCP car une seule ligne de script suffit pour effectuer le transfert.
Code de la fonction qui transfère les fichiers :
run_LogServer(){ echo copy 'log_server' folder content in the remote vm scp -o StrictHostKeyChecking=no -r ./log_server $vmUser@$vmName.$vmLocation.cloudapp.azure.com:/home/$vmUser/log_server echo run 'docker-compose' file az vm run-command invoke --debug -g $rgName -n $vmName --command-id RunShellScript --scripts "cd /home/"$vmUser"/log_server && sudo docker-compose up -d" }
Avec l’outil SCP, nous utilisons l’option –r pour copier récursivement le contenu du dossier spécifié.
Script complet
Dans le script suivant, nous utilisons les variables et fonctions énumérées précédemment :
#!/bin/bash rgName='logservertestrg' vmName='logservertra' vmUser='tranise' vmLocation='westeurope' vmOpendedPort=80 # read docker compose nginx host port #https://www.web2generators.com/apache-tools/htpasswd-generator passwordHash='tranise:$apr1$4t5rn1oy$G7uJ*********' echo write the basic auth credentials in nginx file echo $passwordHash > ./log_server/nginx/.htpasswd create_AzureVm(){ echo -- create the resource group az group create --name $rgName --location $vmLocation echo -- create the vm az vm create --resource-group $rgName --name $vmName --public-ip-address-dns-name $vmName --image UbuntuLTS --admin-username $vmUser --generate-ssh-keys echo -- open port $vmOpenPort on the vm az vm open-port --port $vmOpenPort --resource-group $rgName --name $vmName } install_DockerTools (){ echo install dependencies docker, docker compose and start docker service #install Docker az vm run-command invoke -g $rgName -n $vmName --command-id RunShellScript --scripts "curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - && sudo add-apt-repository 'deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable' && sudo apt-get update && apt-cache policy docker-ce && sudo apt-get install -y docker-ce" #install Docker Compose az vm run-command invoke -g $rgName -n $vmName --command-id RunShellScript --scripts "sudo curl -L https://github.com/docker/compose/releases/download/1.23.1/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose && sudo chmod +x /usr/local/bin/docker-compose" #start Docker service az vm run-command invoke -g $rgName -n $vmName --command-id RunShellScript --scripts "sudo service docker start" } run_LogServer(){ echo copy 'log_server' folder content in the remote vm scp -o StrictHostKeyChecking=no -r ./log_server $vmUser@$vmName.$vmLocation.cloudapp.azure.com:/home/$vmUser/log_server echo run 'docker-compose' file az vm run-command invoke --debug -g $rgName -n $vmName --command-id RunShellScript --scripts "cd /home/"$vmUser"/log_server && sudo docker-compose up -d" } create_AzureVm install_DockerTools run_LogServer echo log server available on $vmName.$vmLocation.cloudapp.azure.com
En exécutant ce script, nous sommes capables de faire fonctionner un serveur de log « conteneurisé » en quelques minutes. Cependant il reste une piste d’amélioration à explorer. Actuellement le serveur de log va stocker les fichiers générés par Elastic Search en local disque. Cette option n’est pas particulièrement pratique si nous voulons ajouter des nœuds à notre cluster Elastic Search. Dans le prochain article nous découvrirons comment améliorer notre architecture pour qu’elle stocke ses fichiers du partage de fichier Azure !
Le code est bien évidement disponible sur mon Github !
Happy coding :)
Commentaires