Ci sono molte ragioni per cui ansible può essere appeso alla riunione dei fatti, ma prima di andare oltre, ecco il primo test che dovresti fare in una tale situazione:
ansible -m ping <hostname>
Questo test si collega all'host ed esegue il codice sufficiente per restituire:
<hostname> | SUCCESS => {
"changed": false,
"ping": "pong"
}
Se funziona, puoi praticamente escludere qualsiasi problema di installazione o connettività, poiché dimostra che potresti risolvere il nome host di destinazione, aprire una connessione, autenticare ed eseguire un modulo sensibile con l'interprete Python remoto.
Ora, ecco un elenco (non esaustivo) di cose che possono andare storte all'inizio di un playbook:
Il comando eseguito da ansible è in attesa di un input interattivo
Ricordo che ciò accadeva nelle versioni precedenti di Ansible, in cui un comando avrebbe atteso un input interattivo che non sarebbe mai arrivato, come una password sudo (quando si è dimenticato un -K
interruttore) o l'accettazione di una nuova impronta digitale dell'host ssh (per una nuova destinazione ospite).
Le versioni moderne di ansible gestiscono entrambi questi casi con garbo e generano immediatamente un errore per le normali modalità d'uso, quindi a meno che tu non stia facendo cose come chiamare ssh o sudo te stesso, non dovresti avere questo tipo di problema. E anche se lo facessi, sarebbe dopo la raccolta dei fatti.
Connessione master SSH morta
Ci sono alcune opzioni molto interessanti passate al client ssh, nel registro di debug fornito qui:
ControlMaster=auto
ControlPersist=60s
ControlPath=/home/vagrant/.ansible/cp/ansible-ssh-%h-%p-%r
Queste opzioni sono documentate in man ssh_config .
Per impostazione predefinita, ansible cercherà di essere intelligente per quanto riguarda l'uso della sua connessione ssh. Per un determinato host, invece di creare una nuova connessione per ogni singola attività del gioco, la aprirà una volta e la manterrà aperta per l'intero playbook (e persino attraverso i playbook).
Va bene, poiché stabilire una nuova connessione è molto più lento e richiede molto tempo rispetto all'utilizzo di una già esistente.
In pratica, ogni connessione ssh verificherà l'esistenza di un socket su ~/.ansible/cp/some-host-specific-path
. La prima connessione non riesce a trovarla, quindi si connette normalmente e quindi la crea. Ogni connessione successiva utilizzerà quindi questo socket per passare attraverso la connessione già stabilita.
Anche se la connessione stabilita alla fine si interrompe e si chiude dopo non essere stata utilizzata per un tempo sufficiente, anche il socket viene chiuso e torniamo al punto di partenza.
Fin qui tutto bene.
A volte, tuttavia, la connessione in realtà muore, ma il client ssh la considera ancora stabilita. Ciò si verifica in genere quando si esegue il playbook dal proprio laptop e si perde la connessione WiFi (o si passa da WiFi a Ethernet, ecc ...)
Quest'ultimo esempio è una situazione terribile: puoi inviare ssh al computer di destinazione con una configurazione ssh predefinita, ma fintanto che la tua connessione precedente sarà ancora considerata attiva, Ansible non proverà nemmeno a stabilirne una nuova.
A questo punto, vogliamo solo sbarazzarci di questo vecchio socket e il modo più semplice per farlo è rimuoverlo:
# 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>
Questo è perfetto per una correzione one-shot, ma se succede troppo spesso, potrebbe essere necessario cercare una correzione a lungo termine. Ecco alcuni suggerimenti che potrebbero aiutare a raggiungere questo obiettivo:
- Avvia i playbook da un server (con una connessione di rete molto più stabile di quella del tuo laptop)
- Utilizzare la configurazione ansible o direttamente la configurazione client ssh per disabilitare la condivisione della connessione
- Utilizzare le stesse risorse, ma per ottimizzare i timeout, in modo che un arresto anomalo della connessione principale scada effettivamente più rapidamente
Si prega di notare che al momento della stesura di questo documento, alcune opzioni sono cambiate (ad esempio, la mia ultima esecuzione mi ha dato ControlPath=/home/toadjaune/.ansible/cp/871b533295
), ma l'idea generale è ancora valida.
La raccolta dei fatti in realtà richiede troppo tempo
All'inizio di ogni gioco, Ansible raccoglie molte informazioni sul sistema di destinazione e le mette in fatti . Queste sono variabili che puoi quindi utilizzare nel tuo playbook e di solito sono davvero utili, ma a volte ottenere queste informazioni può essere molto lungo (punti di montaggio errati, dischi con I / O elevato, carico elevato ...)
Detto questo, non è strettamente necessario fatti per eseguire un playbook, e quasi certamente non tutti, quindi proviamo e quello che disabilita non abbiamo bisogno. Diverse opzioni per quello:
Ai fini del debug, è davvero utile richiamare il modulo di installazione direttamente dalla riga di comando:
ansible -m setup <hostname>
Quest'ultimo comando dovrebbe bloccarsi così come il tuo playbook ed eventualmente timeout (o esito positivo). Ora eseguiamo di nuovo il modulo, disabilitando tutto ciò che possiamo:
ansible -m setup -a gather_subset='!all' <hostname>
Se questo si blocca ancora, puoi sempre provare a disabilitare totalmente il modulo nel tuo gioco, ma è molto probabile che il tuo problema sia altrove.
Se, tuttavia, funziona correttamente (e rapidamente), dai un'occhiata alla documentazione del modulo . Hai due opzioni:
- Limitare la raccolta dei fatti a un sottoinsieme, escludendo ciò che non è necessario (vedere i valori possibili per
gather_subset
)
gather_timeout
può anche aiutarti a risolvere il problema, concedendo più tempo (anche se ciò significherebbe correggere un errore di timeout, non un blocco)
Altri problemi
Ovviamente, altre cose possono andare storte. Alcuni suggerimenti per aiutare il debug:
- Usa il livello di verbosità massimo ansible (
-vvvv
), poiché ti mostrerà ogni comando eseguito
- Utilizzare
ping
e setup
moduli direttamente dalla riga di comando come spiegato sopra
- Prova a ssh manualmente se
ansible -m ping
non funziona
vagrant ssh
indagare durante il blocco per vedere se c'è qualcosa di utile inps
enetstat
? Inoltre, uno dei primi sospetti negli hang è il DNS: controlla se il DNS si sta risolvendo dall'interno della macchina virtuale.