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?
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.
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/
- 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
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=30
wait_for
pour ajouter 20 secondes supplémentaires pour être sûr que l'hôte a réellement commencé à redémarrer.
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.
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.
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
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
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.
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