Avr 13 2021

Rendez Ansible 6X Plus Rapide avec ces 3 Astuces

Publié par à 10:10 sous Ansible

Ansible est généralement lent car il se connecte à l’hôte distant pour chaque tâche qu’il exécute. Faisons quelques tests sur un petit rôle qui récupère la dernière version de kubectl (client Kubernetes) depuis une URL, et installe le binaire.
Voyons 3 façons simples d’accélérer Ansible et d’obtenir des meilleurs temps d’exécution.

- name: Récupération de la dernière version
   uri:
     url: "{{kubectl_url}}/stable.txt"
     return_content: yes
     status_code: 200
   register: kubectl_latest_version
 

 - name: Téléchargement du binaire kubectl
   get_url:
     url: "{{kubectl_url}}/v{{ kubectl_version |
       default(kubectl_latest_version.content | 
       regex_replace('^v', '')) }}/bin/{{kubectl_os}}/{{kubectl_arch}}/kubectl"
     dest: "/usr/local/bin"
     mode: '755'
     owner: "{{ kubectl_owner }}"
     group: "{{ kubectl_group }}"


Temps d’exécution avec les paramètres par défaut: 32,2s

Accélérer Ansible


Cache des Facts Ansible

Récupérer les facts est la première tâche qu’Ansible exécute lorsqu’il se connecte à un hôte et le moins que l’on puisse dire est que c’est lent. Très lent. La performance est aussi un problème lorsqu’on écrit un playbook que l’on teste maintes fois.

Heureusement, il est possible de faire des ajustements pour économiser du temps en ajoutant ces quelques lignes dans ansible.cfg:

# implémentation du cache et paramétrage des facts 
# pour une performance améliorée

gathering = smart
gather_subset = !hardware,!facter,!ohai

fact_caching_connection = /tmp/ansible_fact_cache
fact_caching = jsonfile

# expire le cache après 2 heures
fact_caching_timeout = 7200

Selon le fichier exemple ansible.cfg disponible en ligne, smart gathering « récupère par défaut, mais seulement si ce n’est pas déjà fait ».

Les facts hardware sont les plus longs à collecter, mais vous pourriez en avoir besoin surtout si vos rôles reposent sur les interfaces réseau. Vous pourriez recevoir une erreur « ansible_eth0 is undefined » par exemple.
Facter et ohai sont liés aux clients Puppet et Chef.

Et le plus efficace est le cache bien sûr qui stocke les informations dans un fichier JSON. Mais ca pourrait aussi l’être en mémoire, ou même dans une base partagée Redis.

On peut aussi désactiver les facts dans un playbook si on n’en a pas besoin. C’est un gain potentiellement significatif mais qui ne peut pas être utilisé souvent, la plupart des playbooks ont besoin des facts.

- name: mon_playbook
    hosts: *
    gather_facts: no
    tasks:


Temps d’exécution: 19,2s


Accélérer SSH avec le Pipelining

Activer le pipelining réduit le nombre d’opérations SSH requises pour exécuter un module sur le serveur distant. Ceci améliore la performance mais il faut d’abord désactiver ‘requiretty’ dans /etc/sudoers sur tous les hôtes gérés. Raison pour laquelle le pipelining est désactivé par défaut. Ajoutez dans ansible.cfg:

[ssh_connection]
pipelining = True

Si requiretty est paramétré, sudo ne fonctionnera que si l’utilisateur est loggué sur un tty réel.  Dans ce cas, sudo ne se lancera que dans une session de login et non dans un script cron ou cgi-bin. En revanche, ce paramètre est désactivé par défaut d’après la page de man, sur Debian et Ubuntu en tout cas.
On peut donc envisager d’utiliser le pipelining dans ce cas. Vérifiez la page de man de votre distribution Linux.


Temps d’exécution: 11,6s

Delegate_to localhost

La plupart des améliorations dépendent de la façon dont vous écrivez vos tâches Ansible. Dans ce rôle, vous pourriez vous connecter à l’URL depuis n’importe quel hôte – localhost? – et économiser une connexion SSH.
C’est le but de delegate_to qui est souvent pointé sur localhost. La première tâche devient:

- name: get kubectl last version
   delegate_to: localhost
   become: false
   uri:
     url: "{{kubectl_url}}/stable.txt"
     return_content: yes
     status_code: 200
   register: kubectl_latest_version


C’est une optimisation non négligeable que vous pouvez utiliser dès que la tâche peut s’exécuter n’importe où.

Il est préférable d’ajouter become: false ou vous pourriez avoir ce message d’erreur si Ansible essaye de faire un sudo root sur votre machine locale:

fatal: [backup]: FAILED! => {"changed": false, "module_stderr": "sudo: a password is required\n", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}


Temps d’exécution: 4,7s


Le temps d’exécution est le temps moyen de 10 exécutions à la suite, et les tests ont été réalisés sur un lien VPN loin d’être optimum.

Bien sûr les résultats ne sont pas linéaires, tous les playbooks ne s’exécuteront pas 6 fois plus rapidement mais cela donne une idée. Le cache permet d’économiser quelques secondes au lancement du playbook alors que la délégation à localhost est seulement applicable à quelques cas. Mais n’empêche.

Il existe d’autres améliorations possibles pour accélérer Ansible comme les tâches async pour lancer une tâche et passer immédiatement à la suite. Mais votre meilleur atout est d’exécuter Ansible sur une machine aussi proche que possible des hôtes ciblées.


No responses yet

Comments RSS

Leave a Reply