Déployer un cluster Elastic et Kibana avec Vagrant
Cet article vous permettra de déployer, pour vos développements, un cluster Elastic et Kibana avec Vagrant.
Pour le déploiement, nous utiliserons Vagrant avec le provider VirtualBox.
Premiers pas
Avant de commencer le déploiement du cluster, vous aurez besoin :
- Vagrant : Lien vers la page de téléchargement.
- VirtualBox : Lien vers la page de téléchargement.
Préparation du projet
Création de l'environnement local
Dans votre ordinateur, créer le dossier du projet, par exemple vagrant-elastic
. Au sein de ce dossier, créer le fichier suivant :
- Vagrantfile
Le fichier Vagrantfile
contiendra l'ensemble des directives et de la configuration nécessaire au déploiement des machines virtuelles du cluster.
Nous aurons également besoin de plusieurs fichiers Bash pour l'installation d'Elastic et de Kibana. Ces fichiers seront présents dans le dossier manifests
situé à la racine du projet. Je vous invite maintenant à créer le dossier.
Nous séparons volontairement les fichiers de création des machines virtuelles des fichiers d'installation car ces derniers peuvent être réutilisés dans une instance GCP, un conteneur LXC...
Définition du Vagrantfile
Définition des machines virtuelles
Tout d'abord, nous allons définir les caractéristiques des machines virtuelles de notre cluster. Pour cela nous allons ouvrir le fichier Vagrantfile
.
Commençons par ajouter 2 lignes au début du fichier pour indiquer aux éditeurs de code le langage utiliser :
# -*- mode: ruby -*-
# vi: set ft=ruby :
Puis, nous allons définir un tableau qu contiendra les caractéristiques de chaque machine virtuelle :
vms = [
{
:type => "elastic",
:role => "master",
:hostname => "elastic-d11-master",
:private_ip => "192.168.0.10",
:ram => 2048,
:cpu => 2
},
{
:type => "elastic",
:role => "node",
:hostname => "elastic-d11-node-1",
:private_ip => "192.168.0.11",
:ram => 2048,
:cpu => 2
},
{
:type => "elastic",
:role => "node",
:hostname => "elastic-d11-node-2",
:private_ip => "192.168.0.12",
:ram => 2048,
:cpu => 2
},
{
:type => "kibana",
:role => "kibana",
:hostname => "elastic-d11-kibana",
:private_ip => "192.168.0.100",
:ram => 1024,
:cpu => 2
}
]
Ce tableau comporte 4 entrées, chacune de ces entrées est une machine virtuelle. Elles ont des caractéristiques différentes :
type
: La valeur nous permettra de définir le logiciel qui sera installé (Elastic ou Kibana)role
: Au sein de notre cluster Elastic, nous aurons des nœudsmaster
et des nœudsnode
. Les nœudsmaster
seront accessibles depuis l'extérieur. Pour notre article, nous aurons seulement 1 nœudmaster
.hostname
: Cette valeur correspondra au nom de la machine.private_ip
: Cette valeur correspondra à l'adresse IP privée de notre machine. Une interface réseau sera créée automatiquement pour les échanges entre nos machines virtuelles.ram
: Cette valeur permet de définir la quantité de mémoire vive allouée à chaque machine virtuelle.cpu
: Ici, nous définissons le nombre de vCPUs pour chacune de nos machines virtuelles.
Directives de déploiement du cluster
Maintenant que nous avons définis l'ensemble des machines virtuelles de notre cluster, nous allons créer les directives permettant leur déploiement. Cette opération sera réalisée dans le fichier Vagrantfile
.
À la fin du fichier, ajouter le bloc de configuration ci-dessous :
Vagrant.configure("2") do |config|
end
Le chiffre 2
correspond à la version qui sera utilisée entre la section do
et end
. Lien vers la documentation.
Dans la section do
et end
, nous allons créer une boucle each
:
Vagrant.configure("2") do |config|
vms.each do |machine|
end
end
Cette boucle va parcourir le tableau vms
que nous avons créé précédemment. Chaque entrée du tableau sera nommée machine
.
Dans la boucle, nous allons définir chaque machine virtuelle, pour ce faire, ajouter la section config.vm
:
Vagrant.configure("2") do |config|
vms.each do |machine|
config.vm.define machine[:hostname] do |node|
end
end
end
Chaque directive qui sera positionnée dans la section config.vm
permettra de modifier la configuration de la machine virtuelle. Lien vers la documentation.
En Ruby, le mot-clé machine[:hostname]
permet de récupérer le nom d'hôte que nous avons défini dans le hash
, dictionnaire clé unique - valeur vms
, plus d'informations.
Commençons par définir la box
, où l'image qui sera utilisée par nos VMs, le nom d'hôte puis l'adresse IP privée :
Vagrant.configure("2") do |config|
vms.each do |machine|
config.vm.define machine[:hostname] do |node|
node.vm.box = "debian/bullseye64"
node.vm.hostname = machine[:hostname]
node.vm.network "private_network", ip: machine[:private_ip]
end
end
end
Ici, nous utiliserons l'image debian/bullseye64
, soit une Debian 11. Vous pouvez sélectionner d'autres images que vous retrouverez sur le site Vagrant Boxes.
Ajoutons maintenant la directive port_forward
qui nous permettra d'ouvrir un port entre la machine virtuelle et la machine hôte. Ceci étant, nous allons conditionner la directive en fonction du rôle de la VM :
Vagrant.configure("2") do |config|
vms.each do |machine|
config.vm.define machine[:hostname] do |node|
node.vm.box = "debian/bullseye64"
node.vm.hostname = machine[:hostname]
node.vm.network "private_network", ip: machine[:private_ip]
if machine[:type] == "elastic" && machine[:role] == "master"
node.vm.network "forwarded_port", guest: 9200, host: 9200
end
if machine[:type] == "kibana"
node.vm.network "forwarded_port", guest: 5601, host: 5601
end
end
end
end
La première directive ouvrira le port 9200
sur la VM qui est du type elastic
et qui a le rôle master
. La deuxième directive ouvrira le port 5601
pour permettre l'accès à l'interface Kibana.
Ajoutons maintenant les spécificités du provider virtualbox
pour définir le nom de la VM, la vérification des guest additions
de VirtualBox, la quantité de mémoire, le nombre de vCPUs.
Les 2 paramètres --natdnshostresolver1
et --natdnsproxy1
permettent forcer l'utilisation du résolveur de noms de l'hôte.
Vagrant.configure("2") do |config|
vms.each do |machine|
config.vm.define machine[:hostname] do |node|
node.vm.box = "debian/bullseye64"
node.vm.hostname = machine[:hostname]
node.vm.network "private_network", ip: machine[:private_ip]
if machine[:type] == "elastic" && machine[:role] == "master"
node.vm.network "forwarded_port", guest: 9200, host: 9200
end
if machine[:type] == "kibana"
node.vm.network "forwarded_port", guest: 5601, host: 5601
end
node.vm.provider "virtualbox" do |v|
v.name = machine[:hostname]
v.check_guest_additions = false
v.memory = machine[:ram]
v.cpus = machine[:cpu]
v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
v.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
end
end
end
end
Pour plus d'informations sur le provider virtualbox
, je vous invite à consulter la documentation.
Terminons la partie Vagrantfile en ajoutant 3 scripts Bash pour l'installation après la section node.vm.provider
:
Vagrant.configure("2") do |config|
vms.each do |machine|
config.vm.define machine[:hostname] do |node|
node.vm.box = "debian/bullseye64"
node.vm.hostname = machine[:hostname]
node.vm.network "private_network", ip: machine[:private_ip]
if machine[:type] == "elastic" && machine[:role] == "master"
node.vm.network "forwarded_port", guest: 9200, host: 9200
end
if machine[:type] == "kibana"
node.vm.network "forwarded_port", guest: 5601, host: 5601
end
node.vm.provider "virtualbox" do |v|
v.name = machine[:hostname]
v.check_guest_additions = false
v.memory = machine[:ram]
v.cpus = machine[:cpu]
v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
v.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
end
node.vm.provision "shell", path: "./manifests/install-base.sh"
if machine[:type] == "elastic"
node.vm.provision "shell", path: "./manifests/install-elastic.sh"
end
if machine[:type] == "kibana"
node.vm.provision "shell", path: "./manifests/install-kibana.sh"
end
end
end
end
Un premier script permet l'installation des composants de base ainsi que JRE et JDK. Puis les 2 autres scripts installeront Elastic sur l'ensemble des machines de type elastic
et Kibana sur les machines de type kibana
.
Désormais, le fichier Vagrantfile
est complet. La suite de l'article consistera à créer les 3 scripts Bash permettant l'installation d'Elastic et de Kibana.
Définition des scripts d'installation
Dans chaque script, nous avons conditionné une partie des installations, dans le but de ne pas télécharger et installer des composants déjà présents. Il y a un donc un test permettant de vérifier la présence du composant, par exemple, pour tester si JRE est installé, nous exécutons la commande :
java --version > /dev/null 2>&1
Cette commande renvoie la sortie dans /dev/null
mais l'ajout de 2>&1
permet de rediriger la sortie STDERR
(2) vers STDOUT
(1). Pour plus d'informations, vous pouvez consulter cet article.
Après avoir exécuté la commande java --version > /dev/null 2>&1
. Nous assignons la sortie $?
à une variable :
JRE_IS_INSTALLED=$?
Puis nous réalisons un test :
if [[ $JRE_IS_INSTALLED -ne 0 ]]; then
echo ">>> Installing JRE"
else
echo ">>> JRE is already installed!"
fi
Installation des composants de base
Nous allons désormais travailler dans le dossier manifests
que nous avons créés au début de l'article. L'ensemble des paquets installés par ce premier script sont nécessaires pour notre cluster, que ce soit pour Elastic ou Kibana. Le fichier est nommé install-base.sh
et son contenu est le suivant :
#!/usr/bin/bash
sudo apt-get update -qq && sudo apt-get -y -qq upgrade
# Install Components
sudo apt-get -y -qq install gnupg2 curl apt-transport-https > /dev/null
# Install JRE
# Test if JRE is installed
java --version > /dev/null 2>&1
JRE_IS_INSTALLED=$?
if [[ $JRE_IS_INSTALLED -ne 0 ]]; then
echo ">>> Installing JRE"
sudo apt-get -qq -y install default-jre > /dev/null
else
echo ">>> JRE is already installed!"
fi
# Install JDK
# Test if JDK is installed
javac --version > /dev/null 2>&1
JDK_IS_INSTALLED=$?
if [[ JDK_IS_INSTALLED -ne 0 ]]; then
echo ">>> Installing JDK"
sudo apt-get -qq -y install default-jdk > /dev/null
else
echo ">>> JDK is already installed!"
fi
Tout d'abord, nous devons procéder à une mise à jour des fichiers dans les dépôts APT. Puis à la mise à jour des paquets déjà installés avant d'installer 3 paquets gnupg2
, curl
et apt-transport-https
.
Ensuite, nous testons la présence de JRE, l'environnement d'exécution Java et de la présence du JDK (Kit de développement Java). Dans le cas où les paquets ne sont pas présents, ils seront installés.
Installation d'Elastic
Pour l'installation d'Elastic, nous aurons un script plus complet découpé en 3 parties :
- Définition des variables
- Installation d'Elastic
- Configuration d'Elastic sur chaque nœud
Les variables définies sont les suivantes :
HOSTNAME=$(cat /etc/hostname)
ELASTIC_FILE=elasticsearch-7.16.2-amd64.deb
CLUSTER_NAME=elastic-d11-cluster
ELASTIC_PORT=9200
ELASTIC_MASTER_HOSTNAME="elastic-d11-master"
ELASTIC_NODE1_HOSTNAME="elastic-d11-node-1"
ELASTIC_NODE2_HOSTNAME="elastic-d11-node-2"
HOSTNAME
sera utilisé pour définir le nom du nœud dans la configuration d'ElasticELASTIC_FILE
permet de spécifier la version d'Elastic à télécharger. Cette variable est également utilisée pour télécharger le fichier SHA du binaire Debian et pour le tester si les fichiers d'installation ont été téléchargésCLUSTER_NAME
nomme notre cluster Elastic dans la configuration de l'ensemble des nœudsELASTIC_PORT
permet de spécifier le port d'écoute d'Elastic. Le port 9200 est la valeur par défaut.ELASTIC_MASTER_HOSTNAME
,ELASTIC_NODE1_HOSTNAME
etELASTIC_NODE2_HOSTNAME
permettront de configurer la liste de tous les nœuds du cluster ainsi que la liste des nœudsmaster
de notre cluster.
La 2ᵉ partie du script correspond à l'installation et au démarrage du service Elastic :
curl 127.0.0.1:9200 > /dev/null 2>&1
ELASTIC_STATUS=$?
if [[ $ELASTIC_STATUS -ne 0 ]]; then
echo ">>> Check if Elasticsearch is installed"
sudo systemctl status elasticsearch > /dev/null 2>&1
IS_ELASTIC_EXIST=$?
if [[ $IS_ELASTIC_EXIST -ne 0 ]]; then
echo ">>> Installing Elasticsearch"
if [ ! -f "$PWD/$ELASTIC_FILE" ]; then
echo ">>> Download file"
wget -q https://artifacts.elastic.co/downloads/elasticsearch/"$ELASTIC_FILE"
fi
if [ ! -f "$PWD/$ELASTIC_FILE.sha512" ]; then
echo ">>> Download sha file"
wget -q https://artifacts.elastic.co/downloads/elasticsearch/"$ELASTIC_FILE.sha512"
fi
shasum -a 512 -c "$ELASTIC_FILE.sha512" > /dev/null 2>&1
SHA_STATUS=$?
if [[ $SHA_STATUS -eq 0 ]]; then
sudo dpkg -i "$ELASTIC_FILE"
echo ">>> Autostart Elasticsearch at boot"
sudo systemctl daemon-reload && sudo systemctl enable elasticsearch
echo ">>> Starting Elasticsearch"
sudo systemctl start elasticsearch
fi
rm ./"$ELASTIC_FILE" ./"$ELASTIC_FILE.sha512"
else
echo ">>> Starting Elasticsearch"
sudo systemctl start elasticsearch
fi
else
echo ">>> Elasticsearch is already running"
fi
Tout commence par un curl sur le port 9200 de la machine virtuelle. Si le port ne répond pas, nous vérifions si Elastic est installé. Si une erreur est renvoyée dans la sortie, nous lançons l'installation d'Elastic. Mais avant de télécharger le fichier, nous allons vérifier sa présence. Dans le cas contraire, nous lançons le téléchargement. Nous réalisons la même opération pour le fichier SHA. Puis nous lançons la comparaison du paquet Debian téléchargé avec le checksum
publiée par Elastic.
Une fois validé, nous lançons l'installation d'Elastic, puis nous configurons le démarrage automatique du service avant de lancer le service Elasticsearch.
La dernière partie du script concerne la configuration d'Elasticsearch, la modification de la configuration est réalisée par la commande sed
:
if [[ $HOSTNAME -eq "elastic-d11-master" ]]; then
echo ">>> Configuring Elasticsearch Master"
sudo sed -i -e 's/^#network.host.*/network.host: [_local_, _eth0_, _eth1_]/g' /etc/elasticsearch/elasticsearch.yml
else
echo ">>> Configuring Elasticsearch Nodes"
sudo sed -i -e 's/^#network.host.*/network.host: [_local_, _eth0_]/g' /etc/elasticsearch/elasticsearch.yml
fi
echo ">>> Configuring Elasticsearch Master & Nodes"
sudo sed -i -e 's/^#node.name.*/node.name: '$HOSTNAME' /g' /etc/elasticsearch/elasticsearch.yml
sudo sed -i -e 's/^#cluster.name.*/cluster.name: '$CLUSTER_NAME'/g' /etc/elasticsearch/elasticsearch.yml
sudo sed -i -e 's/^#http.port.*/http.port: '$ELASTIC_PORT'/g' /etc/elasticsearch/elasticsearch.yml
sudo sed -i -e 's/^#discovery.seed_hosts.*/discovery.seed_hosts: ["'$ELASTIC_MASTER_HOSTNAME'", "'$ELASTIC_NODE1_HOSTNAME'", "'$ELASTIC_NODE2_HOSTNAME'"]/g' /etc/elasticsearch/elasticsearch.yml
sudo sed -i -e 's/^#cluster.initial_master_nodes.*/cluster.initial_master_nodes: ["'$ELASTIC_MASTER_HOSTNAME'"]/g' /etc/elasticsearch/elasticsearch.yml
echo ">>> Restarting Elasticsearch"
sudo systemctl restart elasticsearch
Nous commençons par configurer les interfaces réseaux qui seront utilisées par Elastic. Les interfaces réseaux ne sont pas identiques entre les différents types de nœud, car le nœud maître possède une interface réseau supplémentaire permettant de réaliser un port-forward sur la machine hôte.
Ensuite, la configuration est commune quel que soit le nœud, nous définissons le nom du nœud, le nom du cluster, le port d'écoute...
Nous terminons ensuite par le redémarrage du nœud dans le but de mettre à jour à la configuration.
Par défaut, la sécurité est désactivée, vous pouvez configurer la sécurité en vous aidant de la documentation Elastic. Cette partie ne sera pas traitée dans cet article.
Installation de Kibana
Le script d'installation de Kibana a une structure identique au script d'installation d'Elastic. Seule la configuration est différente, elle est décrite après le contenu du fichier :
#!/usr/bin/bash
KIBANA_FILE=kibana-7.16.2-amd64.deb
KIBANA_PORT=5601
KIBANA_HOST=0.0.0.0
KIBANA_HOSTNAME=elastic-d11-kibana
ELASTIC_HOST="http:\/\/192.168.0.10:9200"
curl 127.0.0.1:5601 > /dev/null 2>&1
KIBANA_STATUS=$?
if [[ $KIBANA_STATUS -ne 0 ]]; then
echo ">>> Check if Kibana is installed"
sudo systemctl status kibana > /dev/null 2>&1
IS_KIBANA_EXIST=$?
if [[ $IS_KIBANA_EXIST -ne 0 ]]; then
echo ">>> Installing Kibana"
if [ ! -f "$PWD/$KIBANA_FILE" ]; then
echo ">>> Download file"
wget -q https://artifacts.elastic.co/downloads/kibana/"$KIBANA_FILE"
fi
if [ ! -f "$PWD/$KIBANA_FILE.sha512" ]; then
echo ">>> Download sha file"
wget -q https://artifacts.elastic.co/downloads/kibana/"$KIBANA_FILE.sha512"
fi
shasum -a 512 -c "$KIBANA_FILE.sha512" > /dev/null 2>&1
SHA_STATUS=$?
if [[ $SHA_STATUS -eq 0 ]]; then
sudo dpkg -i "$KIBANA_FILE"
echo ">>> Autostart Kibana at boot"
sudo systemctl daemon-reload && sudo systemctl enable kibana
echo ">>> Starting Kibana"
sudo systemctl start kibana
fi
rm ./"$KIBANA_FILE" ./"$KIBANA_FILE.sha512"
else
echo ">>> Starting Kibana"
sudo systemctl start kibana
fi
else
echo ">>> Kibana is already running"
fi
echo ">>> Configuring Kibana"
sudo sed -i -e 's/^#server.port.*/server.port: '$KIBANA_PORT'/g' /etc/kibana/kibana.yml
sudo sed -i -e 's/^#server.host.*/server.host: "'$KIBANA_HOST'"/g' /etc/kibana/kibana.yml
sudo sed -i -e 's/^#server.name.*/server.name: "'$KIBANA_HOSTNAME'"/g' /etc/kibana/kibana.yml
sudo sed -i -e 's/^#elasticsearch.hosts.*/elasticsearch.hosts: "'$ELASTIC_HOST'"/g' /etc/kibana/kibana.yml
echo ">>> Restarting Kibana"
sudo systemctl restart kibana
La configuration de Kibana est plus simple comparée à Elastic. Nous commençons par définir le port d'écoute de l'interface graphique de Kibana, puis l'adresse IP du serveur ainsi que le nom de la machine.
Nous terminons par préciser à Kibana l'adresse IP de la machine master
du cluster Elastic.
Déploiement du cluster
Maintenant que nous avons terminé la définition du fichier Vagrantfile
et que nous avons scripté l'installation des paquets requis d'Elastic et de Kibana. Nous pouvons lancer le déploiement de notre cluster grâce à la commande :
vagrant up
Une fois les machines virtuelles créées, vous avez la possibilité de modifier les scripts à votre convenance et mettre à jour la configuration de vos machines virtuelles avec la commande :
vagrant up --provision
Lorsque Vagrant aura terminé de créer le cluster, vous pouvez tester en ouvrant le navigateur de votre machine hôte sur les adresses http://<votre-adresse-ip>:9200
et http://<votre-adresse-ip>:5601
.
Le résultat de la première adresse sera un objet JSON indiquant le nom du cluster, de la machine... et la seconde devrait vous afficher l'interface graphique de Kibana.
Destruction du cluster
Pour détruire le cluster, il est nécessaire de stopper l'ensemble des machines avec la commande
vagrant halt
Puis la commande pour détruire les machines virtuelles est :
vagrant destroy
Cette commande vous demandera une confirmation avant de procéder à la suppression.