instalar - ¿Cómo reiniciar CentOS 7 con Ansible?
instalar ansible en centos 7 (11)
Estoy intentando reiniciar el servidor que ejecuta CentOS 7
en VirtualBox. Yo uso esta tarea:
- name: Restart server
command: /sbin/reboot
async: 0
poll: 0
ignore_errors: true
El servidor se reinicia, pero me sale este error:
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
¿Qué estoy haciendo mal? ¿Cómo puedo arreglar esto?
Ansible se está desarrollando rápidamente y las respuestas anteriores no funcionaron para mí.
Encontré dos problemas:
- La forma recomendada de reiniciar puede matar la conexión SSH antes de que Ansible finalice la tarea.
Es mejor ejecutar: nohup bash -c "sleep 2s && shutdown -r now" &
Esto lanzará un shell con el shutdown
sleep
&&, pero no esperará a que el shell finalice debido al último &
. El tiempo de espera le dará algo de tiempo para que la tarea Ansible finalice antes del reinicio y nohup
garantizará que no se elimine el bash cuando finalice la tarea.
- El módulo
wait_for
no está esperando confiablemente el servicio SSH.
Detecta el puerto abierto, probablemente abierto por systemd, pero cuando se ejecuta la siguiente tarea, SSH aún no está listo.
Si está utilizando Ansible 2.3+, wait_for_connection funciona de manera confiable.
El mejor ''reiniciar y esperar'' en mi experiencia (estoy usando Ansible 2.4) es el siguiente:
- name: Reboot the machine
shell: nohup bash -c "sleep 2s && shutdown -r now" &
- name: Wait for machine to come back
wait_for_connection:
timeout: 240
delay: 20
Tengo el comando nohup de: https://github.com/keithchambers/microservices-playground/blob/master/playbooks/upgrade-packages.yml
Edité este mensaje para:
- agregue la sugerencia de portabilidad de krad, usando shutdown -r ahora en lugar de reiniciar
- añadir un retraso. Es necesario evitar Ansible para ejecutar el siguiente paso si el reinicio es lento
- aumentar el tiempo de espera, 120s era muy poco para algunos BIOS lento.
Después de la tarea de reinicio, debe tener una tarea local_action
que espere a que el host remoto termine de reiniciarse; de lo contrario, la conexión ssh se terminará y también el libro de jugadas.
- 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
También escribí una publicación en el blog sobre el logro de una solución similar: https://oguya.github.io/linux/2015/02/22/ansible-reboot-servers/
En el momento de reiniciar todas las conexiones ssh están cerradas. Es por eso que la tarea Ansible falla. Los ignore_errors: true
o failed_when: false
additions ya no funcionan a partir de Ansible 1.9.x porque el manejo de las conexiones ssh ha cambiado y una conexión cerrada ahora es un error fatal que no puede detectarse durante el juego.
La única forma en que descubrí cómo hacerlo es ejecutar una tarea de shell local que luego inicia una conexión ssh separada, que luego puede fallar.
- name: Rebooting
delegate_to: localhost
shell: ssh -S "none" {{ inventory_hostname }} sudo /usr/sbin/reboot"
failed_when: false
changed_when: true
Es probable que no esté haciendo nada realmente incorrecto, es solo que / sbin / reboot está cerrando el servidor tan rápidamente que el servidor está rompiendo la conexión SSH utilizada por Ansible antes de que el propio Ansible pueda cerrarlo. Como resultado, Ansible está informando un error porque ve que la conexión SSH falla por una razón inesperada.
Lo que podría querer hacer para evitar esto es cambiar de usar /sbin/reboot
a usar /sbin/shutdown
lugar. El comando de apagado le permite pasar un tiempo, y cuando se combina con el -r
, se reiniciará en lugar de apagarse realmente. Así que quizás quieras probar una tarea como esta:
- name: Restart server
command: /sbin/shutdown -r +1
async: 0
poll: 0
ignore_errors: true
Esto demorará el reinicio del servidor durante 1 minuto, pero al hacerlo, debería darle a Ansible el tiempo suficiente para cerrar la conexión SSH, evitando así el error que está recibiendo actualmente.
Estoy usando Ansible 2.5.3. A continuación el código funciona con facilidad,
- name: Rebooting host
shell: ''shutdown -r +1 "Reboot triggered by Ansible"''
- wait_for_connection:
delay: 90
timeout: 300
Puede reiniciar inmediatamente, luego inserte una demora si su máquina tarda un poco en apagarse:
- name: Rebooting host
shell: ''shutdown -r now "Reboot triggered by Ansible"''
async: 1
poll: 1
ignore_errors: true
# Wait 120 seconds to make sure the machine won''t connect immediately in the next section.
- name: Delay for the host to go down
local_action: shell /bin/sleep 120
Luego haga una encuesta para que el libro de jugadas regrese lo antes posible:
- name: Wait for the server to finish rebooting
wait_for_connection:
delay: 15
sleep: 15
timeout: 300
Esto hará que el libro de jugadas regrese tan pronto como sea posible después del reinicio.
La siguiente solución funciona perfecto para mí:
- name: Restart machine
shell: "sleep 5 && sudo shutdown -r now"
async: 1
poll: 0
- name: wait for ssh again available.
wait_for_connection:
connect_timeout: 20
sleep: 5
delay: 5
timeout: 300
El sueño es necesario porque ansible requiere pocos segundos para finalizar la conexión. La publicación excelente sobre este problema se escribió aquí: https://www.jeffgeerling.com/blog/2018/reboot-and-wait-reboot-complete-ansible-playbook
Ninguna de las soluciones anteriores funcionó de manera confiable para mí.
Al emitir un /sbin/reboot
bloquea la reproducción (la conexión SSH se cierra antes de que se pueda completar la tarea, se bloquea incluso con ignore_errors: true
) y /usr/bin/systemd-run --on-active=2 /usr/bin/systemctl reboot
no se reiniciará después de 2 segundos, sino después de un tiempo aleatorio entre 20 segundos y un minuto, por lo que el retraso en algún momento no es suficiente y esto no es predecible.
Además, no quiero esperar minutos mientras que un servidor en la nube se puede reiniciar en pocos segundos.
Así que aquí está mi solución:
- 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
Esa es la línea de shell: ( sleep 3 && /sbin/reboot & )
que hace el truco.
El uso de ( command & )
en el script de shell ejecuta un programa en segundo plano y lo separa: el comando se ejecuta de inmediato, pero persiste después de que se destruye el shell.
Ansible obtiene su respuesta de inmediato y el servidor se reinicia 3 segundos después.
Otra solución:
- 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 un nuevo servicio "al vuelo" que iniciará el systemctl reboot
después de 10 segundos de retraso ( --on-active=10
). delay=30
en wait_for
para agregar 20 segundos adicionales para asegurarse de que el host realmente comenzó a reiniciar.
Otra versión más (combinada de otras respuestas):
---
- 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
Si está usando la versión Ansible> = 2.7, puede usar el módulo de reboot
como se describe aquí
La sinopsis del propio módulo de reboot
:
Reinicie una máquina, espere a que baje, vuelva a subir y responda a los comandos.
De una manera sencilla, puede definir una tarea simple como esta:
- name: reboot server reboot:
Pero puede agregar algunos parámetros como test_command
para probar si su servidor está listo para realizar más tareas
- name: reboot server reboot: test_command: whoami
¡Espero que esto ayude!
- 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