Ago 24 2021
Ansible 6X más Rápido con estos 3 Consejos
Ansible es generalmente lento porque se conecta al host remoto para cada tarea que realiza. Hagamos algunas pruebas en un rol pequeño que obtiene la última versión de kubectl (cliente de Kubernetes) de una URL e instala el binario.
Veamos 3 formas sencillas de acelerar Ansible y obtener mejores tiempos de ejecución.
- name: Recuperando la última versión
uri:
url: "{{kubectl_url}}/stable.txt"
return_content: yes
status_code: 200
register: kubectl_latest_version
- name: Descarga del binario de 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 }}"
Tiempo de ejecución con configuración predeterminada: 32,2s
Caché de Facts Ansible
Recuperar los facts es la primera tarea que Ansible realiza cuando se conecta a un host y lo menos que podemos decir es que es lento. Muy lento. El rendimiento también es un problema cuando se escribe un playbook que se prueba una y otra vez.
Afortunadamente, es posible hacer ajustes para ahorrar tiempo agregando estas pocas líneas en ansible.cfg:
# implementación de caché y configuración de facts
# para un mejor rendimiento
gathering = smart
gather_subset = !hardware,!facter,!ohai
fact_caching_connection = /tmp/ansible_fact_cache
fact_caching = jsonfile
# expira la caché después de 2 horas
fact_caching_timeout = 7200
Según el archivo de ejemplo ansible.cfg disponible en línea, smart gathering «recupera de forma predeterminada, pero solo si aún no lo ha hecho».
Los facts de hardware tardan más en recopilarse, pero es posible que los necesite, especialmente si sus funciones se basan en interfaces de red. Es posible que reciba un error «ansible_eth0 is undefined», por ejemplo.
Facter y ohai están relacionados con los clientes Puppet y Chef.
Y el más eficiente es el caché, por supuesto, que almacena la información en un archivo JSON. Pero también podría estar en la memoria, o en una base de datos compartida de Redis.
También puede desactivar los facts en un playbook si no los necesita. Esta es una recompensa potencialmente significativa, pero no se puede usar con frecuencia, la mayoría de los playbooks necesitan los facts.
- name: mon_playbook
hosts: *
gather_facts: no
tasks:
Duración: 19,2s
Acelerar SSH con Pipelining
Permitiendo el pipelining reduce el número de operaciones de SSH necesarios para ejecutar un módulo en el servidor remoto. Esto mejora el rendimiento, pero primero debe deshabilitar ‘requiretty’ en /etc/sudoers en todos los hosts administrados. Razón por la que el pipelining está deshabilitada de forma predeterminada. Agregue ansible.cfg:
[ssh_connection]
pipelining = True
Si se establece requiretty, sudo solo funcionará si el usuario está conectado a un tty real. En este caso, sudo solo se iniciará en una sesión de inicio de sesión y no en un script cron o cgi-bin. Sin embargo, esta configuración está deshabilitada de forma predeterminada de acuerdo con la página de manual, en Debian y Ubuntu de todos modos. Por lo tanto, podemos considerar el uso de pipelining en este caso. Consulte la página de manual de su distribución de Linux.
Duración: 11,6s
Delegate_to localhost
La mayoría de las mejoras dependen de cómo escriba sus trabajos de Ansible. En este rol, podría conectarse a la URL desde cualquier host: ¿localhost? – y guarde una conexión SSH. Este es el propósito de delegate_to, que a menudo se apunta a localhost. La primera tarea se convierte en:
- 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
Esta es una optimización considerable que puede utilizar siempre que la tarea se pueda ejecutar en cualquier lugar.
Es mejor agregar become: false o podría recibir este mensaje de error si Ansible intenta hacer sudo root en su máquina local:
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}
Duración: 4,7s
El tiempo de ejecución es el tiempo promedio de 10 ejecuciones consecutivas, y las pruebas se realizaron en un enlace VPN, lejos de ser óptimo.
Por supuesto que los resultados no son lineales, no todos los playbooks se ejecutarán 6 veces más rápido pero da una idea. El caché ahorra unos segundos al iniciar el playbook, mientras que la delegación a localhost solo se aplica en algunos casos.
Hay otras mejoras que se pueden realizar para acelerar Ansible, como las tareas asíncronas para iniciar una tarea y seguir adelante de inmediato. Pero lo mejor que puede hacer es ejecutar Ansible en una máquina lo más cerca posible de los hosts de destino.