Stratégie d’exécution et optimisation
Objectifs du chapitre et prérequis
Le chapitre précédent a été consacré à l’installation de MediaWiki et à la réduction au maximum de l’indisponibilité. Une autre méthode est de faire en sorte que les playbooks Ansible soient lancés le plus rapidement possible.
Pour cela, vous aborderez la notion de stratégie d’exécution (parallélisation, sérialisation, débogage). Une dernière partie sera consacrée à la mise en place de l’extension Mitogen.
Stratégie d’exécution
1. Contexte
Lors du lancement d’un playbook, certaines machines seront plus lentes à exécuter leurs travaux tandis que d’autres iront plus vite. Une bonne façon de gagner du temps est d’augmenter le nombre d’opérations en parallèle.
2. Gestion du nombre de tâches lancées en parallèle
Ansible pose une limitation sur le nombre de tâches lancées en simultané. Par défaut, cette valeur est à 5. Le changement de cette valeur peut se faire soit :
-
en exportant la variable ANSIBLE_FORKS ;
-
en modifiant la valeur du champ forks dans le fichier de configuration d’Ansible au niveau de la section defaults.
Ci-dessous un exemple de déclaration pour passer à 10 lancements en parallèle depuis le fichier de configuration :
[defaults]
# Dont use cowsay please
nocows=1
# 10 tasks at a time
forks=10
Il est également possible de spécifier cette valeur depuis la ligne de commande avec l’option --fork <FORK_COUNT> (ou -f pour la version courte).
3. Stratégie d’exécution : free
Le lancement en parallèle sur une tâche a été abordé. En revanche, les opérations se lancent toujours de la même manière : elles se lancent en série et chacune doit attendre que toutes les machines finissent leur mise à jour pour passer à la tâche suivante.
Dans le vocable d’Ansible, on parle de stratégie d’exécution. Par défaut, on utilise la stratégie linear. Le problème avec cette stratégie...
Débogage avec Ansible
1. Contexte
Vous avez vu comment réduire le temps de lancement d’un playbook avec la stratégie free. En réalité, le mécanisme des stratégies sous Ansible est très générique. Il existe notamment une autre stratégie bien pratique pour l’aide à la mise au point : debug. Dans ce qui va suivre, vous verrez comment détecter et régler un problème lors de l’exécution d’un playbook contenant une erreur.
L’activation de cette stratégie se fait de la même manière que pour la précédente :
-
soit par la configuration d’Ansible (champ strategy=debug).
-
soit par la variable d’environnement ANSIBLE_STRATEGY=debug.
-
ou enfin, par le champ strategy au niveau du playbook.
Cette dernière façon de faire ne doit être utilisée que dans le cadre de la mise au point. Surtout ne pas oublier de la supprimer une fois la mise au point terminée.
Pour prendre quelques exemples d’utilisation du débogueur, utilisez un playbook qui réalise deux opérations tombant en erreur :
-
Un appel au module shell avec une commande renvoyant une erreur (ls /does/not/exist).
-
Un appel au module shell avec une variable non définie undefined.
Ci-dessous le playbook correspondant. Sauvegardez ce fichier sous le nom simple-error.yml :
- hosts: localhost
tasks:
- shell: ls /does/not/exist
- shell: echo {{undefined}}
Activation du débogueur
Afin d’activer le débogueur, passez par la variable d’environnement...
Étude du fonctionnement d’Ansible
1. Contexte
La principale qualité d’Ansible est de ne réclamer aucun agent sur les machines à administrer en dehors de la présence d’un interpréteur Python. Mais même dans le cas où une machine n’aurait pas d’interpréteur, il sera tout de même possible de déposer des fichiers ou de lancer des commandes simples. Il devient ainsi possible de lancer l’installation d’un interpréteur Python avant de démarrer l’utilisation de modules permettant le lancement d’opérations plus complexes.
Mais cet avantage peut également se transformer en défaut, surtout lorsque les playbooks à lancer embarquent un grand nombre d’opérations.
2. Playbook de test
Afin de mieux s’en rendre compte, un playbook de test va être créé. Ce dernier aura en charge la création de répertoires sur la machine courante à l’aide d’une boucle.
La boucle se fera grâce à l’instruction loop suivie de l’appel à la fonction range. Cette dernière prend en paramètre le nombre d’itérations à réaliser (50 par exemple). Cet appel sera envoyé au filtre list pour permettre à Ansible d’itérer. Ci-après l’instruction correspondante : {{ range(50) | list }}.
La création du répertoire se fera à l’aide du module file suivi des options suivantes :
-
Le champ path suivi du chemin à créer (/tmp/test/{{ item }}).
-
Le champ state suivi de l’état attendu...
Présentation de Mitogen
1. Contexte
Dans le chapitre précédent, le fonctionnement bas niveau d’Ansible a été abordé. Il ressort de ces observations que chaque opération réclame énormément d’actions :
-
Création de répertoires.
-
Création de fichiers temporaires.
-
Lancement de commandes avant, pendant et après l’exécution des actions.
Sur des playbooks simples, cet état de fait n’a pas beaucoup d’importance. En revanche, lorsque les choses se compliquent, ces temps peuvent rapidement exploser. Il n’est pas rare d’avoir des temps d’exécution qui peuvent dépasser plusieurs dizaines de minutes.
Autre problème : en cas de disque plein (ou de saturation des inœuds sur un disque), Ansible ne sera pas en mesure d’intervenir sur la machine en panne.
2. Présentation de Mitogen
Mitogen est une librairie Python développée et maintenue par David Wilson. Cette dernière permet de mettre au point des programmes Python auto-répliquants et distribués.
Les machines distantes n’ont besoin d’aucun prérequis en dehors de ceux d’Ansible : une connexion fonctionnelle (SSH ou autre) et un interpréteur Python. Le but de cette librairie n’est pas d’offrir un mécanisme générique d’exécution de type RPC (Remote Procedure Call), mais d’être un bus de communication pour des logiciels comme Ansible et également Salt ou Fabric.
3. Principe de fonctionnement de Mitogen
Mitogen dispose des mêmes prérequis qu’Ansible mais procède de manière...