2015-04-29 28 views
17

Sto tentando di riavviare il server che esegue CentOS 7 su VirtualBox. Io uso questo compito:Come riavviare CentOS 7 con Ansible?

- name: Restart server 
    command: /sbin/reboot 
    async: 0 
    poll: 0 
    ignore_errors: true 

Server viene riavviato, ma ottengo questo errore:

TASK: [common | Restart server] *********************************************** 
fatal: [rolcabox] => SSH Error: Shared connection to 127.0.0.1 closed. 
It is sometimes useful to re-run the command using -vvvv, which prints SSH debug output to help diagnose the issue. 

FATAL: all hosts have already failed -- aborting 

Che cosa sto facendo di sbagliato? Come posso risolvere questo?

+0

Sulla base della risposta fornita di Marcin Skarbek Ho preparato e pubblicato sul ruolo di Ansible Galaxy che cosa usa quel metodo. Il ruolo Reboot-And-Wait è possibile trovare [qui] (https://galaxy.ansible.com/it-praktyk/Reboot-And-Wait/). Grazie per l'utilizzo, i feedback sono i benvenuti. –

+0

A causa del rapido sviluppo di Ansible, le risposte più vecchie non funzionano più per me. Per favore dai un'occhiata alla mia risposta. – Telegrapher

risposta

22

Probabilmente non stai facendo nulla di veramente sbagliato, è solo che/sbin/reboot sta spegnendo il server così velocemente che il server sta abbattendo la connessione SSH usata da Ansible prima che Ansible stessa possa chiuderla. Di conseguenza, Ansible segnala un errore perché vede la connessione SSH non riuscita per un motivo imprevisto.

Cosa si potrebbe voler fare per aggirare questo è passare dall'uso di /sbin/reboot all'utilizzo di /sbin/shutdown invece. Il comando shutdown ti consente di passare un tempo e, quando combinato con lo switch -r, eseguirà un riavvio anziché spegnerlo. Così si potrebbe desiderare di provare un compito come questo:

- name: Restart server 
    command: /sbin/shutdown -r +1 
    async: 0 
    poll: 0 
    ignore_errors: true 

Questo ritarderà il riavvio del server per 1 minuto, ma in questo modo si dovrebbe dare Ansible abbastanza tempo per chiudere la connessione SSH stesso, evitando in tal modo l'errore che stai attualmente ricevendo.

+4

Grazie, funziona benissimo! C'era solo un piccolo problema: ho avuto l'errore '' 'Failed parse time: + 1m''', quindi ho dovuto sostituire' '' + 1m''' con '' '+ 1'''. –

+0

Nota: l'utilizzo del riavvio non è una buona idea se non si sa cosa si sta facendo.Va bene in molte distribuzioni di Linux, ma su altri Unix può bypassare molti script di spegnimento del sistema ed è molto difficile. Questo può portare a dbs incoerenti, quindi una pratica sbagliata. Meglio usare shutdown o init. – krad

9

Dopo l'attività di riavvio, è necessario disporre di un'attività local_action in attesa che l'host remoto termini il riavvio, altrimenti la connessione ssh verrà interrotta e così anche il playbook.


- name: Reboot server 
    command: /sbin/reboot 

- name: Wait for the server to finish rebooting 
    sudo: no 
    local_action: wait_for host="{{ inventory_hostname }}" search_regex=OpenSSH port=22 timeout=300 

Ho anche scritto un post sul blog circa il raggiungimento di una soluzione simile: https://oguya.github.io/linux/2015/02/22/ansible-reboot-servers/

1

in fase di reboot tutte le connessioni ssh sono chiusi. Ecco perché l'attività di Ansible fallisce. Le aggiunte ignore_errors: true o failed_when: false non funzionano più da Ansible 1.9.x perché la gestione delle connessioni ssh è cambiata e una connessione chiusa ora è un errore fatale che non può essere rilevato durante la riproduzione.

L'unico modo in cui ho capito come eseguire l'operazione è eseguire un'attività shell locale che quindi avvia una connessione ssh separata, che quindi potrebbe non riuscire.

- name: Rebooting 
    delegate_to: localhost 
    shell: ssh -S "none" {{ inventory_hostname }} sudo /usr/sbin/reboot" 
    failed_when: false 
    changed_when: true 
+0

Grazie per la spiegazione, ma il tuo approccio probabilmente richiede sudo senza password (o mi sono perso qualcosa?), Quindi non posso usarlo in produzione. –

+0

Sì, è corretto. – udondan

4

Un'altra soluzione:

- name: reboot host 
    command: /usr/bin/systemd-run --on-active=10 /usr/bin/systemctl reboot 
    async: 0 
    poll: 0 

- name: wait for host sshd 
    local_action: wait_for host="{{ inventory_hostname }}" search_regex=OpenSSH port=22 timeout=300 delay=30 

systemd-run crea "al volo" nuovo servizio che inizierà systemctl reboot dopo 10 secondi di ritardo (--on-active=10). delay=30 in wait_for per aggiungere 20 secondi in più per assicurarsi che l'host abbia effettivamente iniziato il riavvio.

+1

Davvero grazie, penso che la tua soluzione sia la migliore, con wait_for. –

5

Nessuna delle soluzioni di cui sopra ha funzionato in modo affidabile per me.

emissione di un /sbin/reboot si blocca il gioco (la connessione SSH viene chiusa prima ansible terminata l'operazione, si blocca anche con ignore_errors: true) e /usr/bin/systemd-run --on-active=2 /usr/bin/systemctl reboot non si riavvia dopo 2 secondi, ma dopo un periodo di tempo casuale tra 20 secondi ad un minuto , quindi il ritardo non è sufficiente e non è prevedibile.

Inoltre, non desidero attendere minuti mentre un server cloud può riavviarsi in pochi secondi.

Quindi, ecco la mia soluzione:

- name: Reboot the server for kernel update 
    shell: (sleep 3 && /sbin/reboot &) 
    async: 0 
    poll: 0 

- name: Wait for the server to reboot 
    local_action: wait_for host="{{ansible_host}}" delay=15 state=started port="{{ansible_port}}" connect_timeout=10 timeout=180 

Questa è la linea shell: (sleep 3 && /sbin/reboot &) che fa il trucco.

L'utilizzo di (command &) in script shell esegue un programma in background e lo scollega: il comando viene eseguito immediatamente ma persiste dopo che la shell è stata distrutta.

Ansible ottiene immediatamente la sua risposta e il server si riavvia 3 secondi dopo.

6
- name: restart server 
    shell: sleep 2 && shutdown -r now "Ansible updates triggered" 
    async: 1 
    poll: 0 
    become: true 
    ignore_errors: true 


- name: waiting for the server to come back 
    local_action: wait_for host=testcentos state=started delay=30 timeout=300 
    sudo: false 
+0

Questo funziona perfettamente per me, in particolare 'async: 1'. Ansible 2.3 aggiunge l'utile 'wait_for_connection delay = 20' –

1

Ancora un altro (combinato da altre risposte) versione:

--- 
- name: restart server 
    command: /usr/bin/systemd-run --on-active=5 --timer-property=AccuracySec=100ms /usr/bin/systemctl reboot 
    async: 0 
    poll: 0 
    ignore_errors: true 
    become: yes 

- name: wait for server {{ ansible_ssh_host | default(inventory_hostname) }} to come back online 
    wait_for: 
    port: 22 
    state: started 
    host: '{{ ansible_ssh_host | default(inventory_hostname) }}' 
    delay: 30 
    delegate_to: localhost 
1

Ansible si sta sviluppando velocemente e le risposte più anziani non funzionavano per me.

ho trovato due problemi:

  • Il modo consigliato di riavvio può uccidere la connessione SSH, prima Ansible termina l'operazione.

E 'meglio correre: nohup bash -c "sleep 2s && reboot" &

Verrà avviata una shell con il sleep & & reboot, ma non aspetterà il guscio di porre fine a causa della ultima &. Il sonno darà un po 'di tempo perché l'attività di Ansible termini prima del riavvio e il nohup garantirà che bash non viene ucciso quando l'attività termina.

  • Il modulo wait_for non attende in modo affidabile il servizio SSH.

Rileva la porta aperta, probabilmente aperta da systemd, ma quando viene eseguita l'attività successiva, SSH non è ancora pronto.

Se si utilizza Ansible 2.3+, wait_for_connection funziona in modo affidabile.

Il miglior 'reboot e attendere' nella mia esperienza (sto usando Ansible 2.4) è la seguente:

- name: Reboot the machine 
    shell: nohup bash -c "sleep 2s && reboot" & 

- name: Wait for machine to come back 
    wait_for_connection: 
    timeout: 120 

Ho il comando nohup da: https://github.com/keithchambers/microservices-playground/blob/master/playbooks/upgrade-packages.yml

+0

come per i miei commenti precedenti è davvero male da usare il riavvio – krad

+0

Suoni sensibili in un mondo non Linux. Non ho mai trovato un linux in cui il riavvio non avrebbe eseguito un riavvio corretto e organizzato. – Telegrapher

+0

Un altro vantaggio è che il comando shutdown può includere un timeout, senza necessità di utilizzare il sonno, essendo più pulito. Mi piace il tuo suggerimento di portabilità, ma lo proverò prima di cambiarlo qui, per ogni evenienza. La risposta che ho postato è la più semplice di tutte e funziona in modo affidabile nel frattempo. – Telegrapher

Problemi correlati