Loupe

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 :

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:

1.1.PNG

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 :

2.PNG

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 :)

Ces billets pourraient aussi vous intéresser

Vous nous direz ?!

Commentaires

comments powered by Disqus