GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo esperar a que se reinicie el servidor usando Ansible?

Actualización de 2018

A partir de la versión 2.3, Ansible ahora viene con el wait_for_connection módulo, que se puede utilizar exactamente para este propósito.

#
## Reboot
#

- name: (reboot) Reboot triggered
  command: /sbin/shutdown -r +1 "Ansible-triggered Reboot"
  async: 0
  poll: 0

- name: (reboot) Wait for server to restart
  wait_for_connection:
    delay: 75

El apagado -r +1 evita que se devuelva un código de retorno de 1 y que ansible falle en la tarea. El apagado se ejecuta como una tarea asíncrona, por lo que debemos retrasar el wait_for_connection tarea por lo menos 60 segundos. 75 nos da un búfer para esos casos de copos de nieve.

wait_for_connection:espera hasta que el sistema remoto sea accesible/utilizable


Lo más confiable que tengo con 1.9.4 es (esto está actualizado, la versión original está en la parte inferior):

- name: Example ansible play that requires reboot
  sudo: yes
  gather_facts: no
  hosts:
    - myhosts
  tasks:
    - name: example task that requires reboot
      yum: name=* state=latest
      notify: reboot sequence
  handlers:
    - name: reboot sequence
      changed_when: "true"
      debug: msg='trigger machine reboot sequence'
      notify:
        - get current time
        - reboot system
        - waiting for server to come back
        - verify a reboot was actually initiated
    - name: get current time
      command: /bin/date +%s
      register: before_reboot
      sudo: false
    - name: reboot system
      shell: sleep 2 && shutdown -r now "Ansible package updates triggered"
      async: 1
      poll: 0
      ignore_errors: true
    - name: waiting for server to come back
      local_action: wait_for host={{ inventory_hostname }} state=started delay=30 timeout=220
      sudo: false
    - name: verify a reboot was actually initiated
      # machine should have started after it has been rebooted
      shell: (( `date +%s` - `awk -F . '{print $1}' /proc/uptime` > {{ before_reboot.stdout }} ))
      sudo: false

Tenga en cuenta el async opción. 1.8 y 2.0 pueden vivir con 0 pero 1.9 lo quiere 1 . Lo anterior también verifica si la máquina realmente se ha reiniciado. Esto es bueno porque una vez tuve un error tipográfico que falló al reiniciar y no hay indicación de la falla.

El gran problema es esperar a que la máquina esté encendida. Esta versión solo permanece allí durante 330 segundos y nunca intenta acceder al host antes. Algunas otras respuestas sugieren usar el puerto 22. Esto es bueno si ambos son ciertos:

  • tienes acceso directo a las máquinas
  • se puede acceder a su máquina inmediatamente después de que el puerto 22 esté abierto

Estos no siempre son ciertos, así que decidí perder 5 minutos de tiempo de cálculo. Espero que ansible amplíe el módulo wait_for para comprobar el estado del host y evitar perder el tiempo.

por cierto, la respuesta que sugiere usar controladores es buena. +1 para controladores de mi parte (y actualicé la respuesta para usar controladores).

Aquí está la versión original, pero no es tan buena ni tan confiable:

- name: Reboot
  sudo: yes
  gather_facts: no
  hosts:
    - OSEv3:children
  tasks:
    - name: get current uptime
      shell: cat /proc/uptime | awk -F . '{print $1}'
      register: uptime
      sudo: false
    - name: reboot system
      shell: sleep 2 && shutdown -r now "Ansible package updates triggered"
      async: 1
      poll: 0
      ignore_errors: true
    - name: waiting for server to come back
      local_action: wait_for host={{ inventory_hostname }} state=started delay=30 timeout=300
      sudo: false
    - name: verify a reboot was actually initiated
      # uptime after reboot should be smaller than before reboot
      shell: (( `cat /proc/uptime | awk -F . '{print $1}'` < {{ uptime.stdout }} ))
      sudo: false

Ansible>=2.7 (lanzado en octubre de 2018)

Use el módulo de reinicio incorporado:

- name: Wait for server to restart
  reboot:
    reboot_timeout: 3600

Ansible <2.7

Reiniciar como tarea

- name: restart server
  shell: 'sleep 1 && shutdown -r now "Reboot triggered by Ansible" && sleep 1'
  async: 1
  poll: 0
  become: true

Esto ejecuta el comando de shell como una tarea asincrónica, por lo que Ansible no esperará a que finalice el comando. Normalmente async param da el tiempo máximo para la tarea pero como poll se establece en 0, Ansible nunca sondeará si el comando ha finalizado; hará que este comando sea "disparar y olvidar". Duerme antes y después de shutdown son para evitar que se interrumpa la conexión SSH durante el reinicio mientras Ansible aún está conectado a su host remoto.

Esperar como tarea

Podrías simplemente usar:

- name: Wait for server to restart
  local_action:
    module: wait_for
      host={{ inventory_hostname }}
      port=22
      delay=10
    become: false

..pero quizás prefieras usar {{ ansible_ssh_host }} variable como nombre de host y/o {{ ansible_ssh_port }} como host y puerto SSH si usa entradas como:

hostname         ansible_ssh_host=some.other.name.com ansible_ssh_port=2222 

..en su inventario (Ansible hosts archivo).

Esto ejecutará la tarea wait_for en la máquina que ejecuta Ansible. Esta tarea esperará a que el puerto 22 se abra en su host remoto, comenzando después de 10 segundos de retraso.

Reiniciar y esperar como controladores

Pero sugiero usar ambos como controladores, no como tareas.

Hay 2 razones principales para hacer esto:

  • reutilización de código:puede usar un controlador para muchas tareas. Ejemplo: desencadenar el reinicio del servidor después de cambiar la zona horaria y después de cambiar el kernel,

  • desencadenar solo una vez:si usa un controlador para algunas tareas, y más de 1 de ellos hará algún cambio => desencadenar el controlador, entonces lo que hace el controlador sucederá solo una vez. Ejemplo: si tiene un controlador de reinicio de httpd adjunto al cambio de configuración de httpd y la actualización del certificado SSL, en caso de que tanto la configuración como el certificado SSL cambien, httpd se reiniciará solo una vez.

Obtenga más información sobre los controladores aquí.

Reiniciando y esperando el reinicio como controladores:

  handlers:

    - name: Restart server
      command: 'sleep 1 && shutdown -r now "Reboot triggered by Ansible" && sleep 1'
      async: 1
      poll: 0
      ignore_errors: true
      become: true

    - name: Wait for server to restart
      local_action:
        module: wait_for
          host={{ inventory_hostname }}
          port=22
          delay=10
        become: false

..y utilícelo en su tarea en una secuencia, como esta, aquí junto con el reinicio del controlador del servidor:

  tasks:
    - name: Set hostname
        hostname: name=somename
        notify:
          - Restart server
          - Wait for server to restart

Tenga en cuenta que los controladores se ejecutan en el orden en que están definidos, no en el orden en que aparecen en notify !


Debe cambiar la tarea wait_for para que se ejecute como local_action y especificar el host que está esperando. Por ejemplo:

- name: Wait for server to restart
  local_action:
    module: wait_for
      host=192.168.50.4
      port=22
      delay=1
      timeout=300

Linux
  1. Cómo uso Ansible y Anacron para la automatización

  2. Cómo conectarse a SFTP usando FileZilla para la transferencia segura de archivos

  3. Cómo usar Ansible para instalar y configurar Redis 6 en Ubuntu 20.04

  4. ¿Cómo enviar Ssh a un servidor usando otro servidor?

  5. Comando de Linux para esperar a que un servidor SSH esté activo

Cómo automatizar reinicios del sistema usando el módulo de reinicio de Ansible

Cómo instalar Ansible en Ubuntu 20.04

¿Cómo reiniciar el servidor desde whm?

Cómo reiniciar los servicios del servidor utilizando Plesk Services Monitor

Reiniciar/Reiniciar servidor en Plesk

Cómo instalar el servidor Ansible en Ubuntu 18.04