2013-07-30 9 views
9

Vorrei utilizzare Ansible per eseguire contemporaneamente un lavoro semplice su più nodi remoti. Il lavoro effettivo comporta l'apertura di alcuni file di registro e il post-elaborazione dei risultati sul mio host locale (che ha software non disponibile sui nodi remoti).Come posso guidare Ansible in modo programmatico e simultaneo?

Gli strumenti ansibili della riga di comando non sembrano particolarmente adatti a questo caso d'uso perché mescolano insieme la formattazione generata da ansible con l'output del comando eseguito in remoto. L'API Python sembra che dovrebbe essere in grado di farlo, poiché espone l'output non modificato (a parte qualche potenziale manomissione Unicode che non dovrebbe essere rilevante qui).

Una versione semplificata del programma Python mi è venuta in mente assomiglia a questo:

from sys import argv 
import ansible.runner 
runner = ansible.runner.Runner(
    pattern='*', forks=10, 
    module_name="command", 
    module_args=(
     """ 
     sleep 10 
     """), 
    inventory=ansible.inventory.Inventory(argv[1]), 
) 
results = runner.run() 

Qui, sleep 10 si trova in per il registro effettivo di comando grep - l'idea è solo per simulare un comando che non è andando a completare immediatamente.

Tuttavia, eseguendo ciò, osservo che la quantità di tempo impiegata sembra proporzionale al numero di host nel mio inventario. Ecco i risultati temporali per le rimanenze con 2, 5 e 9 hosts rispettivamente:

[email protected]:/tmp$ time python howlong.py two-hosts.inventory 
real 0m24.285s 
user 0m0.216s 
sys  0m0.120s 
[email protected]:/tmp$ time python howlong.py five-hosts.inventory                     
real 0m55.120s 
user 0m0.224s 
sys  0m0.160s 
[email protected]:/tmp$ time python howlong.py nine-hosts.inventory 
real 1m57.272s 
user 0m0.360s 
sys  0m0.284s 
[email protected]:/tmp$ 

Alcune altre osservazioni casuali:

  • ansible all --forks=10 -i five-hosts.inventory -m command -a "sleep 10" presenta lo stesso comportamento
  • ansible all -c local --forks=10 -i five-hosts.inventory -m command -a "sleep 10" sembra eseguire cose contemporaneamente (ma funziona solo per le connessioni solo locali, ovviamente)
  • ansible all -c paramiko --forks=10 -i five-hosts.inventory -m command -a "sleep 10" sembra eseguire simultaneamente le cose

Forse questo suggerisce che il problema è con il trasporto ssh e non ha nulla a che fare con l'utilizzo di ansible tramite l'API Python anziché dalla riga di comando.

Cosa c'è che non va qui che impedisce al trasporto predefinito di prendere solo circa dieci secondi indipendentemente dal numero di host nel mio inventario?

risposta

5

Alcune indagini rivelano che ansible sta cercando gli host nel mio inventario in ~/.ssh/known_hosts. La mia configurazione ha HashKnownHosts abilitato. ansible non è mai in grado di trovare le voci dell'host che sta cercando perché non capisce il formato di hash degli host conosciuti.

Ogni volta che il trasporto ssh di ansible non riesce a trovare la voce di host conosciuta, acquisisce un blocco globale per la durata dell'esecuzione del modulo. Il risultato di questa confluenza è che tutte le esecuzioni sono effettivamente serializzate.

Una soluzione temporanea consiste nel rinunciare alla sicurezza e al controllo della chiave dell'host disattivato inserendo host_key_checking = False in ~/.ansible.cfg. Un'altra soluzione è usare il trasporto paramiko (ma questo è incredibilmente lento, forse decine o centinaia di volte più lento del trasporto ssh, per qualche motivo). Un altro modo per aggirare è lasciare che alcune voci non trattate vengano aggiunte al file known_hosts per trovare il trasporto ssh di ansible.

3

Dato che HashKnownHosts è abilitato, è necessario eseguire l'aggiornamento all'ultima versione di Ansible. La versione 1.3 ha aggiunto il supporto per l'hash known_hosts, vedere the bug tracker e changelog.Questo dovrebbe risolvere il tuo problema senza compromettere la sicurezza (soluzione temporanea con host_key_checking=False) o sacrificare la velocità (la tua soluzione alternativa con paramiko).

+1

Questa è la mia segnalazione di bug dopo aver scoperto la causa del problema qui. :) –

+0

Oh, non sapevo che questo è stato segnalato da voi (il problema GH è stato aperto da mpdehaan e corretto da jimi-c). Grazie per averlo portato all'attenzione degli sviluppatori! :) –

0

Con Ansible 2.0 API Python, ho spento StrictHostKeyChecking con

import ansible.constants 

ansible.constants.HOST_KEY_CHECKING = False 

sono riuscito ad accelerare considerevolmente Ansible impostando la seguente sui computer gestiti. I sshd più recenti hanno il default al contrario, penso, quindi potrebbe non essere necessario nel tuo caso.

/etc/ssh/sshd_config 
---- 
UseDNS no 
Problemi correlati