Identification et résolution des goulots d'étranglement dans les playbooks Ansible lents
Ansible est un outil puissant pour automatiser l'infrastructure informatique, mais à mesure que les playbooks gagnent en complexité et en échelle, les performances peuvent devenir une préoccupation majeure. Les playbooks à exécution lente peuvent retarder les déploiements, affecter les flux de travail de développement et, en fin de compte, entraver la productivité. Heureusement, Ansible fournit plusieurs mécanismes pour identifier les goulots d'étranglement de performance et optimiser votre automatisation. Cet article vous guidera à travers des étapes pratiques pour profiler vos playbooks, identifier les tâches chronophages et mettre en œuvre des solutions efficaces pour une gestion d'infrastructure plus rapide et plus efficace.
Comprendre où votre playbook passe son temps est la première étape vers l'optimisation. Les coupables courants de playbooks lents incluent la conception de tâches inefficaces, la latence du réseau, des configurations de connexion sous-optimales et une collecte excessive d'informations (facts). En profilant et en analysant systématiquement l'exécution de votre playbook, vous pouvez résoudre ces problèmes et améliorer considérablement la vitesse et la fiabilité de votre automatisation.
Comprendre les métriques de performance d'Ansible
Avant de plonger dans des techniques d'optimisation spécifiques, il est crucial de comprendre comment mesurer et interpréter les performances d'Ansible. Ansible fournit des informations de synchronisation intégrées qui peuvent être inestimables pour le diagnostic.
Utilisation de l'indicateur --vvv (Très Verbeux)
L'indicateur --vvv lors de l'exécution d'un playbook fournit une sortie détaillée, y compris le temps pris pour chaque tâche. C'est souvent le moyen le plus rapide d'avoir une idée de l'endroit où se produisent les retards.
ansible-playbook my_playbook.yml --vvv
Recherchez les lignes indiquant la durée d'exécution des tâches. Les tâches qui prennent constamment beaucoup de temps sont des candidats de choix pour l'optimisation.
Contrôler la verbosité de la sortie
Bien que --vvv soit idéal pour le débogage, il peut produire une sortie écrasante pour les grandes exécutions. Vous pouvez contrôler la verbosité avec des indicateurs comme -v, -vv, -vvv ou -vvvv. Pour l'analyse des performances, -vvv est généralement suffisant.
Goulots d'étranglement courants et stratégies d'optimisation
Plusieurs facteurs peuvent contribuer à la lenteur des playbooks Ansible. Ici, nous allons explorer les goulots d'étranglement courants et proposer des stratégies exploitables pour les résoudre.
1. Collecte excessive d'informations (Fact Gathering)
Par défaut, Ansible collecte les informations système (facts) des hôtes gérés au début de chaque jeu (play). Bien qu'utile, cela peut prendre beaucoup de temps, en particulier sur un grand nombre d'hôtes ou sur des réseaux lents. Si votre playbook ne nécessite pas toutes les informations collectées, vous pouvez désactiver ou limiter la collecte d'informations.
Désactiver la collecte d'informations
Pour désactiver complètement la collecte d'informations pour un jeu, utilisez la directive gather_facts: no:
- name: Mon Playbook
hosts: webservers
gather_facts: no
tasks:
- name: Assurer l'installation d'Apache
apt: name=apache2 state=present
Limiter la collecte d'informations
Si vous avez besoin de certaines informations mais pas de toutes, vous pouvez spécifier quelles informations collecter à l'aide de gather_subset.
- name: Mon Playbook
hosts: webservers
gather_facts: yes
gather_subset:
- '!all'
- '!any'
- hardware
- network
tasks:
- name: Utiliser les informations réseau
debug: var=ansible_default_ipv4.address
Mise en cache des informations (Fact Caching)
Pour les environnements où les informations ne changent pas fréquemment, les mettre en cache peut accélérer considérablement les exécutions de playbooks ultérieures. Ansible prend en charge plusieurs plugins de mise en cache d'informations (par exemple, jsonfile, redis, memcached).
Pour activer la mise en cache des informations, configurez-la dans votre fichier ansible.cfg:
[defaults]
fact_caching = jsonfile
fact_caching_connection = /path/to/ansible/facts_cache
fact_caching_timeout = 86400 # Cache pour 24 heures
Ensuite, votre playbook utilisera automatiquement les informations mises en cache lorsqu'elles seront disponibles.
2. Exécution inefficace des tâches
Certaines tâches peuvent être intrinsèquement lentes, ou elles peuvent être exécutées de manière inefficace.
Exécution parallèle (Forking)
Le comportement par défaut d'Ansible est d'exécuter les tâches sur les hôtes séquentiellement au sein d'un jeu. Vous pouvez augmenter le nombre de processus parallèles (forks) qu'Ansible utilise pour gérer simultanément les hôtes. Ceci est contrôlé par le paramètre forks dans ansible.cfg ou via l'option de ligne de commande -f.
ansible.cfg:
[defaults]
forks = 10
Ligne de commande:
ansible-playbook my_playbook.yml -f 10
Astuce : Commencez avec un nombre modéré de forks (par exemple, 5-10) et augmentez-le progressivement, en surveillant la saturation des ressources système (CPU, mémoire, réseau) sur votre nœud de contrôle Ansible.
Idempotence et gestion de l'état
Assurez-vous que vos tâches sont idempotentes. Cela signifie que l'exécution d'une tâche plusieurs fois devrait avoir le même effet que son exécution une seule fois. Les modules Ansible sont généralement conçus pour être idempotents, mais les scripts ou commandes personnalisés pourraient ne pas l'être. Les vérifications inefficaces dans les tâches peuvent également ajouter une surcharge.
Par exemple, au lieu d'exécuter une commande qui vérifie si un service est en cours d'exécution puis le démarre, utilisez le module service dédié :
Inefficace :
- name: Démarrer le service (vérification inefficace)
command: systemctl start my_service.service || true
when: "'inactive' in service_status.stdout"
register: service_status
changed_when: false # Cette tâche ne change pas l'état
Efficace (en utilisant le module service) :
- name: Assurer le bon fonctionnement de my_service
service:
name: my_service
state: started
Utilisation de async et poll pour les opérations de longue durée
Pour les tâches qui peuvent prendre beaucoup de temps à se terminer (par exemple, les mises à niveau de packages, les migrations de bases de données), l'utilisation des directives async et poll d'Ansible peut empêcher votre playbook de se bloquer.
async: spécifie le temps maximum pendant lequel la tâche doit s'exécuter en arrière-plan.poll: spécifie à quelle fréquence Ansible doit vérifier l'état de la tâche asynchrone.
- name: Effectuer une opération de longue durée
command: /usr/local/bin/long_script.sh
async: 3600 # S'exécute pendant un maximum d'une heure
poll: 60 # Vérifie l'état toutes les 60 secondes
3. Optimisation de la connexion
La manière dont Ansible se connecte à vos nœuds gérés joue un rôle crucial dans les performances.
Multiplexage de connexion SSH
Le multiplexage SSH (ControlMaster) permet à plusieurs sessions SSH de partager une seule connexion réseau. Cela peut considérablement accélérer les connexions ultérieures au même hôte.
Activez-le dans votre ansible.cfg:
[ssh_connection]
control_master = auto
control_path = ~/.ansible/cp/ansible-%%r@%%h:%%p
control_persist = 600 # Garde la connexion de contrôle ouverte pendant 10 minutes
Tentatives et délai d'attente de connexion SSH
L'ajustement des paramètres de connexion SSH peut éviter des retards inutiles lorsque les hôtes sont temporairement indisponibles.
[ssh_connection]
sf_retries = 3
sf_delay = 1
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o ConnectionAttempts=5 -o ConnectTimeout=10
Utilisation du pipelining
Le pipelining permet à Ansible d'exécuter des commandes directement sur l'hôte distant sans créer une nouvelle session SSH pour chaque commande. Cela peut réduire considérablement la surcharge pour de nombreuses tâches.
Activez-le dans ansible.cfg:
[ssh_connection]
pipelining = True
Avertissement : Le pipelining peut ne pas fonctionner avec tous les modules ou sur tous les systèmes d'exploitation. Testez minutieusement.
4. Optimisation de la structure et de la logique du playbook
Parfois, la manière dont un playbook est écrit peut être la source de la lenteur.
Utilisation de delegate_to et run_once
Si une tâche ne doit être effectuée que sur un seul hôte mais affecte plusieurs autres (par exemple, redémarrer un équilibreur de charge), utilisez delegate_to et run_once pour l'exécuter efficacement.
- name: Redémarrer l'équilibreur de charge
service: name=haproxy state=restarted
delegate_to: lb_server_1
run_once: true
Utilisation stratégique des rôles et des inclusions
Bien que les rôles et les inclusions aident à l'organisation, des inclusions profondément imbriquées ou mal structurées peuvent ajouter une légère surcharge. Assurez-vous que vos dépendances de rôle et votre logique d'inclusion sont claires.
Mot-clé serial
Le mot-clé serial limite le nombre d'hôtes sur lesquels les actions peuvent être effectuées simultanément au sein d'un jeu. Bien qu'il soit souvent utilisé pour des déploiements contrôlés, il peut également constituer un goulot d'étranglement s'il est réglé trop bas pour les performances souhaitées.
- name: Déployer l'application sur un sous-ensemble de serveurs
hosts: appservers
serial: 2 # S'exécute sur 2 hôtes à la fois seulement
tasks:
- name: Mettre à jour le code de l'application
copy: src=app/ dest=/opt/app/
Si vous ne limitez pas intentionnellement le parallélisme, assurez-vous que serial n'est pas défini ou est défini sur un nombre suffisamment élevé.
Outils et techniques de profilage
Au-delà de la sortie verbeuse d'Ansible lui-même, un profilage dédié peut offrir des informations plus approfondies.
ansible-playbook --syntax-check
Cette commande vérifie les erreurs de syntaxe de votre playbook mais ne l'exécute pas. C'est un moyen rapide de valider la structure de votre playbook avant une exécution complète.
Journalisation des événements Ansible
Ansible peut enregistrer ses événements d'exécution dans un fichier, qui peut ensuite être analysé. Ceci est particulièrement utile pour les playbooks de longue durée ou pour l'audit.
Configurez la journalisation des événements dans ansible.cfg:
[defaults]
log_path = /var/log/ansible.log
Plugins de rappel personnalisés
Pour un profilage avancé, vous pouvez écrire des plugins de rappel personnalisés pour capturer des métriques spécifiques ou créer des rapports personnalisés sur l'exécution des playbooks.
Résumé et prochaines étapes
L'optimisation des playbooks Ansible est un processus continu qui implique la compréhension des pièges de performance courants et l'application des solutions appropriées. En tirant parti des fonctionnalités intégrées d'Ansible telles que la sortie verbeuse, la mise en cache des informations, les paramètres de connexion et les directives d'exécution des tâches (async, run_once), vous pouvez réduire considérablement les temps d'exécution des playbooks.
Points clés à retenir :
* Profiler d'abord : Identifiez toujours les goulots d'étranglement à l'aide de la sortie verbeuse ou de la journalisation avant de tenter des optimisations.
* Gérer les informations judicieusement : Désactivez, limitez ou mettez en cache les informations en fonction des besoins de votre playbook.
* Optimiser les connexions : Activez le multiplexage SSH et le pipelining lorsque cela est possible.
* Écrire des tâches idempotentes : Utilisez des modules Ansible dédiés plutôt que des commandes brutes pour de meilleures performances et une meilleure fiabilité.
* Tirer parti du parallélisme : Ajustez forks et serial de manière appropriée.
Commencez par résoudre les plus gros consommateurs de temps évidents, testez vos modifications et affinez itérativement vos playbooks pour une efficacité maximale. L'examen et l'optimisation réguliers de votre automatisation garantiront qu'elle reste un atout précieux pour la gestion de votre infrastructure.