it-swarm.com.de

Wie starte ich CentOS 7 mit Ansible neu?

Ich versuche, den Server mit CentOS 7 auf VirtualBox neu zu starten. Ich benutze diese Aufgabe:

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

Der Server wird neu gestartet, aber ich erhalte folgende Fehlermeldung:

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

Was mache ich falsch? Wie kann ich das beheben?

27
Domen Blenkuš

Sie machen wahrscheinlich nichts wirklich Falsches, es ist nur so, dass/sbin/reboot den Server so schnell heruntergefahren hat, dass der Server die von Ansible verwendete SSH-Verbindung abbricht, bevor Ansible ihn selbst schließen kann. Daher meldet Ansible einen Fehler, da die SSH-Verbindung aus einem unerwarteten Grund ausfällt.

Um dies zu umgehen, sollten Sie stattdessen von /sbin/reboot zu /sbin/shutdown wechseln. Mit dem Befehl shutdown können Sie eine Zeit vergehen und in Kombination mit dem -r-Schalter einen Neustart durchführen, anstatt tatsächlich herunterzufahren. Vielleicht möchten Sie eine Aufgabe wie diese versuchen:

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

Dadurch wird der Neustart des Servers um 1 Minute verzögert. Auf diese Weise sollte Ansible jedoch genug Zeit haben, um die SSH-Verbindung selbst zu schließen. Dadurch wird der Fehler vermieden, den Sie gerade erhalten.

38
Bruce P

Nach der Neustartaufgabe sollten Sie eine local_action-Aufgabe haben, die darauf wartet, dass der Remote-Host den Neustart beendet. Andernfalls wird die SSH-Verbindung beendet, und auch das 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

Ich habe auch einen Blogbeitrag über eine ähnliche Lösung geschrieben: https://oguya.github.io/linux/2015/02/22/ansible-reboot-servers/

12
James Oguya
- 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
Syed Saad Ahmed

Eine andere Lösung:

- 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 erstellt "on the fly" einen neuen Dienst, der systemctl reboot nach einer Verzögerung von 10 Sekunden (--on-active=10) .delay=30 in wait_for startet, um zusätzliche 20 Sekunden hinzuzufügen, um sicherzustellen, dass Host tatsächlich einen Neustart gestartet hat.

7
Marcin Skarbek

Keine der oben genannten Lösungen hat für mich zuverlässig funktioniert.

Das Ausgeben eines /sbin/reboot stürzt das Spiel ab (die SSH-Verbindung wird geschlossen, bevor ansible die Aufgabe abgeschlossen hat, stürzt sogar mit ignore_errors: true ab) und /usr/bin/systemd-run --on-active=2 /usr/bin/systemctl reboot wird nicht nach 2 Sekunden neu gestartet, sondern nach einer zufälligen Zeitspanne zwischen 20 Sekunden und einer Minute, also die Verzögerung ist manchmal nicht ausreichend und das ist nicht vorhersehbar.

Ich möchte auch nicht Minuten warten, bis ein Cloud-Server in wenigen Sekunden neu gestartet werden kann.

Also hier ist meine Lösung:

- 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

Das ist die Shell: ( sleep 3 && /sbin/reboot & )-Linie, die den Trick macht.

Wenn Sie ( command & ) im Shell-Skript verwenden, wird ein Programm im Hintergrund ausgeführt und getrennt. Der Befehl ist sofort erfolgreich, bleibt jedoch bestehen, nachdem die Shell zerstört wurde.

Ansible erhält seine Antwort sofort und der Server startet 3 Sekunden später neu.

6
cronvel

Ansible entwickelt sich schnell und die älteren Antworten funktionierten nicht für mich.

Ich habe zwei Probleme gefunden: 

  • Die empfohlene Art des Neustarts kann die SSH-Verbindung beenden, bevor Ansible die Aufgabe beendet.

Es ist besser zu laufen: Nohup bash -c "sleep 2s && shutdown -r now" &

Dies startet eine Shell mit der sleep && shutdown, wartet jedoch nicht auf das Ende der Shell aufgrund des letzten &. Der Ruhezustand gibt dem Ansible-Task etwas Zeit, um vor dem Neustart zu enden, und Nohup garantiert, dass die bash nicht beendet wird, wenn der Task beendet wird.

  • Das wait_for-Modul wartet nicht zuverlässig auf den SSH-Dienst. 

Es erkennt, dass der Port offen ist, wahrscheinlich von systemd geöffnet, aber wenn die nächste Task ausgeführt wird, ist SSH noch nicht bereit.

Wenn Sie Ansible 2.3+ verwenden, funktioniert wait_for_connection zuverlässig.

Das beste "Neustarten und Warten" in meiner Erfahrung (ich verwende Ansible 2.4) ist das Folgende:

- 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

Ich habe den Befehl Nohup von: https://github.com/keithchambers/microservices-playground/blob/master/playbooks/upgrade-packages.yml

Ich habe diese Nachricht folgendermaßen bearbeitet:

  • fügen Sie den Portabilitätsvorschlag von krad hinzu. Verwenden Sie jetzt shutdown -r anstelle eines Neustarts 
  • fügen Sie eine Verzögerung hinzu. Es ist erforderlich, um zu vermeiden, dass Ansible den nächsten Schritt ausführt, wenn der Neustart langsam ist
  • das Timeout erhöhen, 120s war zu wenig für ein langsames BIOS.
5
Telegrapher

Noch eine (aus anderen Antworten kombinierte) Version:

---
- 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
Andrzej Rehmann

Ich verwende Ansible 2.5.3 . Der folgende Code funktioniert mit Leichtigkeit,

- name: Rebooting Host
  Shell: 'shutdown -r +1 "Reboot triggered by Ansible"'

- wait_for_connection:
    delay: 90
    timeout: 300

Sie können sofort einen Neustart durchführen und dann eine Verzögerung einfügen, wenn der Computer eine Weile benötigt, um herunterzufahren:

    - 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

Dann befragen Sie das Spielbuch so schnell wie möglich zurück:

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

Dadurch wird das Playbook nach dem Neustart so schnell wie möglich wieder angezeigt.

1
Ashwin

Folgende Lösung funktioniert für mich perfekt:

- 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

Der Schlafmodus ist erforderlich, da Ansible nur wenige Sekunden benötigt, um die Verbindung abzuschließen. Ein hervorragender Beitrag zu diesem Problem wurde hier geschrieben: https://www.jeffgeerling.com/blog/2018/reboot-and-wait- reboot-complete-ansible-playbook

1

wenn Sie die Ansible-Version> = 2.7 verwenden, können Sie das reboot-Modul wie beschrieben verwenden hier

Die Zusammenfassung des reboot-Moduls selbst:

Starten Sie eine Maschine neu, warten Sie, bis sie heruntergefahren ist, kehren Sie zurück und reagieren Sie auf Befehle.

Auf einfache Weise können Sie eine einfache Aufgabe wie folgt definieren:

    - name: reboot server
      reboot:

Sie können jedoch einige Parameter wie test_command hinzufügen, um zu testen, ob Ihr Server bereit ist, weitere Aufgaben auszuführen

    - name: reboot server
      reboot:
        test_command: whoami

Hoffe das hilft!

1
kxu

Beim Neustart sind alle SSH-Verbindungen geschlossen. Deshalb schlägt die Ansible-Aufgabe fehl. Die Zusätze ignore_errors: true oder failed_when: false funktionieren ab Ansible 1.9.x nicht mehr, da sich die Handhabung von ssh-Verbindungen geändert hat und eine geschlossene Verbindung jetzt ein schwerwiegender Fehler ist, der während des Spiels nicht abgefangen werden kann.

Die einzige Möglichkeit, wie ich es herausfinden konnte, ist die Ausführung einer lokalen Shell-Task, die dann eine separate SSH-Verbindung startet, die dann fehlschlagen kann.

- name: Rebooting
  delegate_to: localhost
  Shell: ssh -S "none" {{ inventory_hostname }} Sudo /usr/sbin/reboot"
  failed_when: false
  changed_when: true
1
udondan