我正在尝试重新启动VirtualBox上运行CentOS 7
的服务器。我用这个任务:
- name: Restart server
command: /sbin/reboot
async: 0
poll: 0
ignore_errors: true
服务器重启,但我收到此错误:
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
我做错了什么?我该如何解决这个问题?
答案 0 :(得分:38)
您可能没有做任何真正的错误,只是/ sbin / reboot正在关闭服务器这么快以致服务器在Ansible自身关闭之前拆除了Ansible使用的SSH连接它。因此,Ansible报告错误,因为它看到SSH连接因意外原因而失败。
您可能想要做的就是从使用/sbin/reboot
切换到使用/sbin/shutdown
。 shutdown命令允许您传递时间,当与-r
开关结合使用时,它将执行重新启动而不是实际关闭。所以你可能想尝试这样的任务:
- name: Restart server
command: /sbin/shutdown -r +1
async: 0
poll: 0
ignore_errors: true
这会延迟服务器重启1分钟,但这样做会让Ansible有足够的时间来关闭SSH连接本身,从而避免你当前得到的错误。
答案 1 :(得分:12)
重启任务后,你应该有local_action
任务等待远程主机完成重启,否则ssh连接将被终止,剧本也是如此。
- 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/
答案 2 :(得分:9)
- 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
答案 3 :(得分:7)
另一种解决方案:
- 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
即时创造""新服务将在延迟10秒(systemctl reboot
)后启动--on-active=10
。
delay=30
中的wait_for
添加额外的20秒以确保主机实际上已重新启动。
答案 4 :(得分:6)
以上解决方案均无法为我提供可靠的服务。
发出/sbin/reboot
崩溃游戏(SSH连接在ansible完成任务之前关闭,它甚至在ignore_errors: true
时崩溃)并且/usr/bin/systemd-run --on-active=2 /usr/bin/systemctl reboot
在2秒后不会重启,但之后在20秒到1分钟之间的随机时间,所以延迟有时是不够的,这是不可预测的。
此外,我不想等待几分钟,而云服务器可以在几秒钟内重启。
所以这是我的解决方案:
- 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
这就是shell: ( sleep 3 && /sbin/reboot & )
这一行。
在shell脚本中使用( command & )
在后台运行程序并将其分离:命令立即成功,但在shell被销毁后仍然存在。
Ansible立即得到响应,服务器在3秒后重新启动。
答案 5 :(得分:5)
Ansible正在迅速发展,旧答案对我不起作用。
我发现了两个问题:
最好运行:nohup bash -c "sleep 2s && shutdown -r now" &
这将启动一个包含sleep
&&的shell。 shutdown
,但不会因为上一个&
而等待shell结束。睡眠将为Ansible任务提供一些时间在重启之前结束,nohup
将保证在任务结束时bash不会被杀死。
wait_for
模块无法可靠地等待SSH服务。 它检测到端口打开,可能是由systemd打开的,但是当下一个任务运行时,SSH仍然没有准备好。
如果您使用的是Ansible 2.3+,则wait_for_connection可靠地运行。
根据我的经验(我使用的是Ansible 2.4),最好的'重启和等待'如下:
- 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
我从https://github.com/keithchambers/microservices-playground/blob/master/playbooks/upgrade-packages.yml
获得了nohup命令我将此消息编辑为:
答案 6 :(得分:3)
又一个(结合其他答案)版本:
---
- 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
答案 7 :(得分:1)
在重启时,所有ssh连接都将关闭。这就是Ansible任务失败的原因。由于Anssh 1.9.x的ignore_errors: true
或failed_when: false
添加不再起作用,因为ssh连接的处理已经改变,现在关闭连接是一个致命错误,在播放期间无法捕获。
我想出如何做的唯一方法是运行本地shell任务,然后启动一个单独的ssh连接,然后可能会失败。
- name: Rebooting
delegate_to: localhost
shell: ssh -S "none" {{ inventory_hostname }} sudo /usr/sbin/reboot"
failed_when: false
changed_when: true
答案 8 :(得分:1)
我正在使用Ansible 2.5.3。 下面的代码很容易使用,
- name: Rebooting host
shell: 'shutdown -r +1 "Reboot triggered by Ansible"'
- wait_for_connection:
delay: 90
timeout: 300
您可以立即重启,如果您的机器需要一段时间停机,请插入延迟:
- 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
然后轮询以尽快让剧本返回:
- name: Wait for the server to finish rebooting
wait_for_connection:
delay: 15
sleep: 15
timeout: 300
这将使重新启动后的剧本尽快返回。
答案 9 :(得分:1)
以下解决方案对我来说很完美:
- 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
睡眠是必需的,因为ansible只需几秒钟即可结束连接。 关于这个问题的优秀文章写在这里: https://www.jeffgeerling.com/blog/2018/reboot-and-wait-reboot-complete-ansible-playbook
答案 10 :(得分:1)
如果您使用的Ansible版本> = 2.7,则可以按照here
所述使用reboot
模块
reboot
模块本身的简介:
重新启动计算机,等待其关闭,重新启动并响应命令。
您可以通过一种简单的方式定义一个简单的任务,如下所示:
- name: reboot server
reboot:
但是您可以添加诸如test_command
之类的参数来测试服务器是否准备好执行进一步的任务
- name: reboot server
reboot:
test_command: whoami
希望这会有所帮助!