Hay muchas razones por las cuales ansible puede colgar en la recopilación de datos, pero antes de continuar, aquí está la primera prueba que debe hacer en cualquier situación:
ansible -m ping <hostname>
Esta prueba solo se conecta al host y ejecuta suficiente código para devolver:
<hostname> | SUCCESS => {
"changed": false,
"ping": "pong"
}
Si esto funciona, puede descartar cualquier problema de configuración o conectividad, ya que demuestra que puede resolver el nombre de host de destino, abrir una conexión, autenticar y ejecutar un módulo ansible con el intérprete de Python remoto.
Ahora, aquí hay una lista (no exhaustiva) de cosas que pueden salir mal al comienzo de un libro de jugadas:
El comando ejecutado por ansible está esperando una entrada interactiva
Puedo recordar que esto sucedió en versiones anteriores de ansible, donde un comando esperaría una entrada interactiva que nunca llegaría, como una contraseña de sudo (cuando olvidó un -K
interruptor) o la aceptación de una nueva huella digital de host ssh (para un nuevo objetivo anfitrión).
Las versiones modernas de ansible manejan ambos casos con gracia y generan un error de inmediato para los casos de uso normales, por lo que a menos que esté haciendo cosas como llamar a ssh o sudo usted mismo, no debería tener este tipo de problema. E incluso si lo hicieras, sería después de reunir los hechos.
Conexión maestra ssh muerta
Hay algunas opciones muy interesantes que se pasan al cliente ssh, en el registro de depuración que se proporciona aquí:
ControlMaster=auto
ControlPersist=60s
ControlPath=/home/vagrant/.ansible/cp/ansible-ssh-%h-%p-%r
Estas opciones están documentadas en man ssh_config .
Por defecto, ansible intentará ser inteligente con respecto al uso de su conexión ssh. Para un host determinado, en lugar de crear una nueva conexión para todas y cada una de las tareas de la obra, la abrirá una vez y la mantendrá abierta para todo el libro de jugadas (e incluso para los libros de jugadas).
Eso es bueno, ya que establecer una nueva conexión es mucho más lento e intensivo en cómputo que usar una ya existente.
En la práctica, cada conexión ssh verificará la existencia de un socket en ~/.ansible/cp/some-host-specific-path
. La primera conexión no puede encontrarlo, por lo que se conecta normalmente y luego lo crea. Cada conexión subsiguiente utilizará este socket para pasar por la conexión ya establecida.
Incluso si la conexión establecida finalmente agota el tiempo de espera y se cierra después de no usarse durante el tiempo suficiente, el zócalo también se cierra y volvemos al punto de partida.
Hasta aquí todo bien.
Sin embargo, a veces, la conexión en realidad muere, pero el cliente ssh aún la considera establecida. Esto generalmente ocurre cuando ejecuta el libro de jugadas desde su computadora portátil y pierde su conexión WiFi (o cambia de WiFi a Ethernet, etc.)
Este último ejemplo es una situación terrible: puede enviar ssh a la máquina de destino con una configuración ssh predeterminada, pero mientras su conexión anterior todavía se considere activa, ansible ni siquiera intentará establecer una nueva.
En este punto, solo queremos deshacernos de este viejo socket, y la forma más sencilla de hacerlo es eliminarlo:
# Delete all the current sockets (may disrupt currently running playbooks)
rm -r ~/.ansible/cp
# Delete only the affected socket (requires to know which one it is)
rm ~/.ansible/cp/<replace-by-your-socket>
Esto es perfecto para una solución de una sola vez, pero si sucede con demasiada frecuencia, es posible que deba buscar una solución a más largo plazo. Aquí hay algunos consejos que pueden ayudar a alcanzar este objetivo:
- Inicie playbooks desde un servidor (con una conexión de red mucho más estable que la de su computadora portátil)
- Use la configuración ansible , o directamente la configuración del cliente ssh para deshabilitar la conexión compartida
- Use los mismos recursos, pero para ajustar los tiempos de espera, de modo que un bloqueo de conexión maestra realmente agote el tiempo de espera más rápido
Tenga en cuenta que al momento de escribir, algunas opciones han cambiado (por ejemplo, mi última ejecución me dio ControlPath=/home/toadjaune/.ansible/cp/871b533295
), pero la idea general sigue siendo válida.
La recopilación de datos realmente toma demasiado tiempo
Al comienzo de cada jugada, ansible recopila mucha información sobre el sistema objetivo y la pone en Hechos . Estas son variables que luego puede usar en su libro de jugadas, y generalmente son realmente útiles, pero a veces, obtener esta información puede ser muy largo (puntos de montaje defectuosos, discos con alta E / S, alta carga ...)
Dicho esto, no necesitas estrictamente hechos para ejecutar un libro de jugadas, y casi con certeza no todos, así que intentemos desactivar lo que no necesitamos. Varias opciones para eso:
Para fines de depuración, es realmente conveniente invocar el módulo de configuración directamente desde la línea de comandos:
ansible -m setup <hostname>
Este último comando debe colgar tan bien como su libro de jugadas y, finalmente, agotar el tiempo de espera (o tener éxito). Ahora, ejecutemos el módulo nuevamente, deshabilitando todo lo que podamos:
ansible -m setup -a gather_subset='!all' <hostname>
Si esto todavía se bloquea, siempre puede intentar deshabilitar totalmente el módulo en su juego, pero es muy probable que su problema esté en otro lugar.
Sin embargo, si funciona bien (y rápidamente), eche un vistazo a la documentación del módulo . Tienes dos opciones:
- Limite la recopilación de datos a un subconjunto, excluyendo lo que no necesita (vea los valores posibles para
gather_subset
)
gather_timeout
también puede ayudarlo a solucionar su problema, al permitirle más tiempo (aunque eso sería solucionar un error de tiempo de espera, no un bloqueo)
Otros asuntos
Obviamente, otras cosas pueden salir mal. Algunos consejos para ayudar a la depuración:
- Use el nivel de verbosidad máximo ansible (
-vvvv
), ya que le mostrará todos los comandos ejecutados
- Use
ping
y setup
módulos directamente desde la línea de comandos como se explicó anteriormente
- Intenta ssh manualmente si
ansible -m ping
no funciona
vagrant ssh
investigar durante el bloqueo para ver si hay algo útil enps
ynetstat
? Además, uno de los primeros sospechosos en hangs es DNS: compruebe si DNS se está resolviendo desde el interior de la máquina virtual.