Votre infrastructure de test avec Vagrant

Qu’est ce que Vagrant ? Un outil pour simplifier le déploiement de VM. Dans mon cas Vagrant gère les VMs avec virtualBox.

Ce que je trouve génial pour faire son infrastructure de test c’est que l’on peut définir toute son infrastructure de test en 1 fichier (Vagrantfile) et pour simplifier la vie il y a deux règles de base, un dossier /vagrant qui est synchronisé avec le dossier où on va exécuter notre $ vagrant up.

Je vais juste vous montrer un Vagrantfile qui créé une infrastructure de test pour « jouer » avec Ansible. Dans cette infrastructure je veux plusieurs linux si possible la configuration ssh avec ma clef publique dans le ~vagrant/.ssh/authorized_keys.

# -*- mode: ruby -*-
# vi: set ft=ruby :

# README
#
# Getting Started:
# 1. vagrant plugin install vagrant-hostmanager
# 2. vagrant up
# 3. vagrant ssh
#
# This should put you at the control host
#  with access, by name, to other vms
Vagrant.configure(2) do |config|
  config.hostmanager.enabled = true
  config.vm.box = "ubuntu/groovy64"

  config.vm.define "control", primary: true do |h|
    h.vm.hostname = 'control'
    h.vm.network "private_network", ip: "192.168.135.10"
    h.vm.provision :shell, :inline => <<'EOF'
if [ ! -f "/home/vagrant/.ssh/id_rsa" ]; then
  ssh-keygen -t rsa -N "" -f /home/vagrant/.ssh/id_rsa
fi
cp /home/vagrant/.ssh/id_rsa.pub /vagrant/control.pub

cat << 'SSHEOF' > /home/vagrant/.ssh/config
Host *
  StrictHostKeyChecking no
  UserKnownHostsFile=/dev/null
SSHEOF

chown -R vagrant:vagrant /home/vagrant/.ssh/
EOF
  end

  config.vm.define "lb01" do |h|
    h.vm.box = "centos/7"
    h.vm.hostname = 'lb01'
    h.vm.box_url = "centos/7"
    h.vm.network "private_network", ip: "192.168.135.101"
    h.vm.provision :shell, inline: 'cat /vagrant/control.pub >> /home/vagrant/.ssh/authorized_keys'
  end

  config.vm.define "app01" do |h|
    h.vm.hostname = 'app01'
    h.vm.network "private_network", ip: "192.168.135.111"
    h.vm.provision :shell, inline: 'cat /vagrant/control.pub >> /home/vagrant/.ssh/authorized_keys'
  end

  config.vm.define "app02" do |h|
    h.vm.hostname = 'app02'
    h.vm.network "private_network", ip: "192.168.135.112"
    h.vm.provision :shell, inline: 'cat /vagrant/control.pub >> /home/vagrant/.ssh/authorized_keys'
  end

  config.vm.define "db01" do |h|
    config.vm.box = "bento/amazonlinux-2"
    h.vm.hostname = 'db01'
    h.vm.network "private_network", ip: "192.168.135.121"
    h.vm.provision :shell, inline: 'cat /vagrant/control.pub >> /home/vagrant/.ssh/authorized_keys'
  end
end

Voila donc je viens de créer un textbed avec 4 VMs.

Explication de tout ça

Une box ?

Une image d’Os sous Vagrant est une box. Elles sont disponible sur ce site https://app.vagrantup.com/ comme pour le hub de docker il y a des images « officiel » et des images « communauté »:

Dans le Vagrantfile la variable qui definis la box à utiliser est config.vm.box.

Dans le Vagrantfile on commence par des variables globlales. Celles avant le premier config.vm.define. Par défaut l’os sera Ubuntu Groovy. Comme toute les variables elle peut etre rédéfinis dans la section sous config.vm.define.

config.vm.box = "ubuntu/groovy64"
  • control , app01 et app02 utilise la box globale

Pour les deux VMs suivante config.vm.box a été redéfinis au niveau de config.vm.

  • lb01 utilise la box « centos/7 »
  • db01utilise la box « bentoo/amazonlinux-2 »

Ok c’est bon on a choisi nos Os.

Hostname et réseau

Pour ce qui connaisse bien virtualBox une petite visite sur l’interface graphique de ce dernier. Pour le « DNS » c’est top pas besoin de configurer quoi que ce soit il suffit de définir le h.vm.hostname. Pour le réseau on a définis un reseau qu’on appel private_network et on met des ips fixe aux vm. Toutes nos VM sont sur le réseaux private_network and add a unique Ip. Par défaut le NAT nous permer d’acceder d’installer nos packages.

    h.vm.hostname = 'control'
h.vm.network "private_network", ip: "192.168.135.10"

Le réseau, et DNS ready.

Simple is beautiful

Comme je l’ai dit la configuration ci dessus est faites pour jouer avec ansible. J’ai donc besoin d’un post install pour gérer les clefs ssh. Il suffit de faire les clefs dans le compte de l’utilisateur vagrant et de copier sa clef publique dans le /home/vagrant/.ssh/authorized_keys

/home/vagrant/.ssh/authorized_keys

Pour faire simple que de mieux que d’executer un post install script en shell. Vagrant a donc une variable qui permet de faire ca.

    h.vm.provision :shell, :inline => <<'EOF'
if [ ! -f "/home/vagrant/.ssh/id_rsa" ]; then
ssh-keygen -t rsa -N "" -f /home/vagrant/.ssh/id_rsa
fi
cp /home/vagrant/.ssh/id_rsa.pub /vagrant/control.pub

cat << 'SSHEOF' > /home/vagrant/.ssh/config
Host *
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null
SSHEOF

chown -R vagrant:vagrant /home/vagrant/.ssh/
EOF

Notre post-install permet de faire nos clefs ssh et met a jour le fichier authorized_key Ce qui permet de ne pas taper de mot de passe. L’utilisateur Vagrant est déja dans le su et n’a pas besoin de taper de mot de passe quand il fait exécuter une tache comme root.

Multi VM

Le Vegrantfile peut gérer plusieurs VM comme le notre. On peut redéfinir dans chaque section de config.vm.define toute les variables globale.

Let’s start the « cloud »

Pour commencer, faire ou choisir le dossier à partir duquel on veut travailler, c’est ce dossier qui sera partagé avec vos VMs dant le /vagrant de ces dernières. On copy dans ce dossier notre Vagrantfile, pour créer les VMs il sufffit de suivre les 3 premières commandes listé dans le Vagrantfile (dans CE Vagrantfile).

$ vagrant plugin install vagrant-hostmanager
$ vagrant up
$ vagrant ssh

le vagrant-hostmanager est requis pour géré le /etc/hosts (pratique pour ne pas avoir a faire de configuration DNS). Le up fait toute les étapes requis pour installé et configurer notre cloud.

La commande « vragrant ssh » permet de se connecter à la première VM listé dans le Vagrantfile, et on peut aussi utiliser : « vagrant ssh <hostname> » pour se connecter directement à la VM <hostname>. Gràce a vagrant ssh notre cloud peut etre sur un réseau virtual sans avoir besoin de faire une configuration avec une deuxième interface réseau.

Pour résumé vous pouvez faire votre testbed en quelques minutes sans savoir quoi que ce soit de ruby et juste mettre un post-install en bash. Voila de mon coté mon testbed est nickel facile a utiliser et sans trop de customisation compliqué à part un compte vagrant ajouter a sudo et un dossier de partage. Tout le reste c’est à peut près standard.

https://www.vagrantup.com/

Augmenter la taille d’un volume OpenStack (la vidéo)

Voila la vidéo de l’augmentation de la taille d’un de mes volumes OpenStack.

Monit & docker check

Dans ce poste fait une configuration pour monitorer le statut de mes containers. Mes scripts pour générer la configuration sont faits pour une configuration à partir d’un dossier contenant un docker-compose.yml.

Ce n’est pas beau comme setting mais Monit ne supporte pas le passage de paramètres à ses scripts. On va générer 1 script de check par container et un fichier de configuration par container, ça peut faire beaucoup de fichiers mais cela va être facile à nettoyer si besoin.

La configuration de Monit pour executer le monitoring de <container_name>

Le fichier : /etc/monit/conf.d/docker_<container_name> est le fichier de configuration.

check program <container_name> with path /opt/monit/bin/docker_check_<container_name>.sh
if status != 0 then alert

La le script a exécuter pour vérifier le statut du container /opt/monit/bin/docker_check_.sh voici le fichier :

sudo docker top container_<container_name>;
exit 0;

J’ai fait un petit repo sur gihub avec deux scripts pour faire votre configuration.

https://github.com/needsone/monit-my-docker

Réduire la taille de ses images en force

Voilà la problématique mes client.e.s ne compressent pas les images avant de les mettre sur leur site WordPress. Du coup au bout de quelque temps ils viennent me voir en se plaignant que leur site est trop lent. Une photo d’iphone est lourde.

Le problème c’est le download de tout ça et l’upload qui doit remettre tous les fichiers aux bons endroits avec le même nom. Du coup j’ai fait un setup pour gérer ça. J’ai un accès ssh à mes fichiers.

Pour gérer tout ça j’ai installé imagemagick https://imagemagick.org/

  1. faire un miroir du dossier upload dans votre dossier d’installation WordPress vous trouverez : wp-content/uploads c’est dans ce dossier que WP met tous les fichiers médias. Pour faire ce miroir j’utilise rsync en limitant la synchronisation aux fichiers png, Jjpg et jpeg.
cd my_working_folder
rsync -e ssh -acv --include="*/" --include="*.jpeg" \
--include="*.jpg" --include="*.png" --exclude="*" \
login@ssh-ftp-server:site-folder/wp-content/uploads ./
  1. Je fais ensuite tourner deux commandes sur les fichiers avec imagemagick. Ici on réduit la taille des fichiers au maximum 1024px sur le coté le plus long et réduit la qualité à 85%.
magick mogrify -resize $size *
magick mogrify -strip -quality $quality *

Je me suis fais un petit scipt pour faciliter un peu les choses que je vous laisse faire un find pour éxecuter ça la ou il faut :

cd my_working_folder
find . -type d -exec ~/bin/img-optimization.sh ./ "{}" \;

3. On re-upload avec rysnc

cd my_working_folder
rsync -e ssh -acv --include="*/" --include="*.jpeg"\
 -include="*.jpg" --include="*.png"\
 --exclude="*" ./ login@ssh-ftp-server:site-folder/wp-content/uploads

J »ai fait un repo avec deux de mes scripts :

https://github.com/needsone/pict4wp/

Vi

Vous pouvez télécharger ce pdf l’imprimer et vous avez la documentation complete de Vi.

Aller à la barre d’outils