Comment redémarrer CentOS 7 avec Ansible?

j'essaie de redémarrer le serveurCentOS 7 sur VirtualBox. J'utilise cette tâche:

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

le Serveur est redémarré, mais j'ai cette erreur:

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'est-ce que je fais de mal? Comment je peux arranger ça?

25
demandé sur Domen Blenkuš 2015-04-30 01:21:07

10 réponses

vous ne faites probablement rien de vraiment mal, c'est juste que /sbin/reboot coupe le serveur si rapidement que le serveur détruit la connexion SSH utilisée par Ansible avant Qu'Ansible lui-même ne puisse la fermer. En conséquence, Ansible signale une erreur parce qu'il voit la connexion SSH faillir pour une raison inattendue.

Ce que vous pouvez faire pour contourner ce problème est de passer de l'utilisation de /sbin/reboot à l'aide de /sbin/shutdown à la place. La commande shutdown vous permet de passer un le temps, et quand combiné avec le -r switch it va effectuer un redémarrage plutôt que de s'arrêter. Vous pourriez donc essayer une tâche comme celle-ci:

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

cela retardera le redémarrage du serveur d'une minute, mais ce faisant, cela devrait donner suffisamment de temps au serveur pour fermer la connexion SSH elle-même, évitant ainsi l'erreur que vous obtenez actuellement.

35
répondu Bruce P 2017-12-13 19:03:26

après la tâche de redémarrage, vous devriez avoir un local_action tâche qui attend la fin du redémarrage de l'hôte distant, sinon la connexion ssh sera terminée, tout comme le 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
https://oguya.github.io/linux/2015/02/22/ansible-reboot-servers/

12
répondu James Oguya 2015-04-30 07:23:52
- 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
10
répondu Syed Saad Ahmed 2017-04-03 11:18:38

une autre solution:

- 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 crée "à la volée" nouveau service qui va démarrer --on-active=10). delay=30wait_for pour ajouter 20 secondes supplémentaires pour être sûr que l'hôte a réellement commencé à redémarrer.

7
répondu Marcin Skarbek 2016-05-04 06:07:11

aucune des solutions ci-dessus n'a fonctionné de façon fiable pour moi.

Emission d'un /sbin/reboot bloque le jeu (la connexion SSH est fermée avant que la tâche ne soit terminée, elle se bloque même avec ignore_errors: true et /usr/bin/systemd-run --on-active=2 /usr/bin/systemctl reboot ne redémarre pas après 2 secondes, mais après un certain temps entre 20 secondes et une minute, de sorte que le retard est parfois pas suffisant et ce n'est pas prévisible.

aussi je ne veux pas attendre des minutes alors qu'un serveur cloud peut redémarrer en quelques minutes deuxième.

alors voici ma solution:

- 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

C'est le shell: ( sleep 3 && /sbin/reboot & ) ligne qui fait l'affaire.

en utilisant ( command & ) dans shell script exécute un programme en arrière-plan et le détache: la commande réussit immédiatement mais persiste après la destruction du shell.

Ansible reçoit sa réponse immédiatement et le serveur redémarre 3 secondes plus tard.

6
répondu cronvel 2017-03-31 19:56:02

Ansible se développe rapidement et les réponses plus anciennes ne fonctionnaient pas pour moi.

j'ai trouvé deux questions:

  • la méthode recommandée de redémarrage peut tuer la connexion SSH avant que L'interface ne finisse la tâche.

Il est préférable de l'exécuter: nohup bash -c "sleep 2s && shutdown -r now" &

ceci lancera un shell avec le , mais n'attendra pas que le shell se termine à cause du dernier &. Le sommeil donnera un peu de temps pour la fin de la tâche possible avant le redémarrage et l' nohup garantira que bash ne sera pas tué quand la tâche sera terminée.

  • wait_for module n'attend pas de façon fiable le service SSH.

il détecte le port ouvert, probablement ouvert par systemd, mais quand la prochaine tâche est exécutée, SSH n'est toujours pas prêt.

si vous utilisez Ansible 2.3+, wait_for_connection fonctionne de manière fiable.

le meilleur 'redémarrage et attente' de mon expérience (j'utilise Ansible 2.4) est le code suivant:

- 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

j'ai reçu la commande nohup de: https://github.com/keithchambers/microservices-playground/blob/master/playbooks/upgrade-packages.yml

j'ai édité ce message:

  • ajouter la suggestion de portabilité de krad, en utilisant shutdown-r maintenant au lieu de redémarrer
  • ajouter un délai. Il est nécessaire d'éviter Ansible d'exécuter l'étape suivante si le redémarrage est lent
  • augmenter le temps d'arrêt, 120 a été trop peu pour des BIOS lents.
5
répondu Telegrapher 2018-04-03 13:00:09

encore une autre version (combinée à d'autres réponses):

---
- 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
3
répondu Hoto 2017-06-21 09:42:36

au moment du redémarrage, toutes les connexions ssh sont fermées. C'est pour ça que la tâche impossible échoue. ignore_errors: true ou failed_when: false les additions ne fonctionnent plus depuis la possibilité 1.9.x parce que la gestion des connexions ssh a changé et qu'une connexion fermée est maintenant une erreur fatale qui ne peut pas être détectée pendant le jeu.

le seul moyen que j'ai trouvé pour le faire est d'exécuter une tâche shell locale qui démarre alors une connexion SSH séparée, qui peut alors échouer.

- name: Rebooting
  delegate_to: localhost
  shell: ssh -S "none" {{ inventory_hostname }} sudo /usr/sbin/reboot"
  failed_when: false
  changed_when: true
1
répondu udondan 2015-04-30 08:24:30

j'utilise Ansible 2.5.3. Le code ci-dessous fonctionne facilement,

- name: Rebooting host
  shell: 'shutdown -r +1 "Reboot triggered by Ansible"'

- wait_for_connection:
    delay: 90
    timeout: 300

Vous pouvez redémarrer immédiatement, puis insérer un retard si votre machine met du temps à descendre:

    - 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

puis pollez pour faire revenir le playbook le plus tôt possible:

    - name: Wait for the server to finish rebooting
      wait_for_connection:
        delay: 15
        sleep: 15
        timeout: 300

ceci fera le retour du playbook dès que possible après le redémarrage.

1
répondu Ashwin 2018-06-13 04:02:08

solution Suivante fonctionne pour moi parfait:

- 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

Le sommeil est nécessaire parce que la possibilité nécessite quelques secondes pour boucler la connexion. Excelent post à propos de ce problème a été écrit ici: https://www.jeffgeerling.com/blog/2018/reboot-and-wait-reboot-complete-ansible-playbook

1
répondu Marcin Trojanowski 2018-06-20 12:10:04