如何使用 Ansible 重启 CentOS 7?
How to reboot CentOS 7 with Ansible?
我正在尝试在 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
我做错了什么?我该如何解决这个问题?
您可能并没有做错任何事情,只是 /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 连接本身,从而避免您当前遇到的错误。
重启任务后,你应该有一个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
我还写了一篇关于实现类似解决方案的博客post:https://oguya.github.io/linux/2015/02/22/ansible-reboot-servers/
在重新启动时,所有 ssh 连接都将关闭。这就是 Ansible 任务失败的原因。 ignore_errors: true
或 failed_when: false
添加项从 Ansible 1 开始不再起作用。9.x 因为 ssh 连接的处理方式已经改变,关闭的连接现在是一个致命错误,在游戏过程中无法捕获.
我想出的唯一方法是 运行 一个本地 shell 任务,然后启动一个单独的 ssh 连接,然后可能会失败。
- name: Rebooting
delegate_to: localhost
shell: ssh -S "none" {{ inventory_hostname }} sudo /usr/sbin/reboot"
failed_when: false
changed_when: true
另一个解决方案:
- 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
创建 "on the fly" 新服务,它将在 systemctl reboot
延迟 10 秒 (--on-active=10
) 后启动。
delay=30
在 wait_for
中添加额外的 20 秒以确保主机真正开始重新启动。
None 以上解决方案对我来说很可靠。
发出 /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 秒后重启。
- 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
另一个(结合其他答案)版本:
---
- 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
Ansible 正在快速发展,旧的答案对我不起作用。
我发现了两个问题:
- 推荐的重启方式可能会在 Ansible 完成任务之前终止 SSH 连接。
不如运行:nohup bash -c "sleep 2s && shutdown -r now" &
这将启动带有 sleep
&& shutdown
的 shell,但由于最后一个 &
而不会等待 shell 结束.睡眠将为 Ansible 任务在重启前结束提供一些时间,并且 nohup
将保证 bash 在任务结束时不会被杀死。
wait_for
模块无法可靠地等待 SSH 服务。
它检测到端口打开,可能是systemd打开的,但是当下一个任务是运行时,SSH仍然没有准备好。
如果您使用的是 Ansible 2.3+,wait_for_connection 工作可靠。
根据我的经验(我使用的是 Ansible 2.4),最好的 'reboot and wait' 如下:
- 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
我从以下位置获得了 nohup 命令:https://github.com/keithchambers/microservices-playground/blob/master/playbooks/upgrade-packages.yml
我将此消息编辑为:
- 添加 krad 的可移植性建议,现在使用 shutdown -r 而不是 reboot
- 添加延迟。需要避免Ansible在重启慢的情况下执行下一步
- 增加超时时间,120 秒对于一些慢速 BIOS 来说太短了。
我正在使用 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
然后尽快投票制作剧本return:
- name: Wait for the server to finish rebooting
wait_for_connection:
delay: 15
sleep: 15
timeout: 300
这将使 playbook 在重启后尽快 return。
以下解决方案非常适合我:
- 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 需要几秒钟的时间来结束连接。
关于这个问题的优秀 post 写在这里:
https://www.jeffgeerling.com/blog/2018/reboot-and-wait-reboot-complete-ansible-playbook
如果您使用的 Ansible 版本 >=2.7,您可以使用 reboot
模块,如 here
所述
reboot
模块本身的概要:
Reboot a machine, wait for it to go down, come back up, and respond to commands.
简单来说,你可以这样定义一个简单的任务:
- name: reboot server
reboot:
但是你可以添加一些参数,比如 test_command
来测试你的服务器是否准备好接受进一步的任务
- name: reboot server
reboot:
test_command: whoami
希望对您有所帮助!
我正在尝试在 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
我做错了什么?我该如何解决这个问题?
您可能并没有做错任何事情,只是 /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 连接本身,从而避免您当前遇到的错误。
重启任务后,你应该有一个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
我还写了一篇关于实现类似解决方案的博客post:https://oguya.github.io/linux/2015/02/22/ansible-reboot-servers/
在重新启动时,所有 ssh 连接都将关闭。这就是 Ansible 任务失败的原因。 ignore_errors: true
或 failed_when: false
添加项从 Ansible 1 开始不再起作用。9.x 因为 ssh 连接的处理方式已经改变,关闭的连接现在是一个致命错误,在游戏过程中无法捕获.
我想出的唯一方法是 运行 一个本地 shell 任务,然后启动一个单独的 ssh 连接,然后可能会失败。
- name: Rebooting
delegate_to: localhost
shell: ssh -S "none" {{ inventory_hostname }} sudo /usr/sbin/reboot"
failed_when: false
changed_when: true
另一个解决方案:
- 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
创建 "on the fly" 新服务,它将在 systemctl reboot
延迟 10 秒 (--on-active=10
) 后启动。
delay=30
在 wait_for
中添加额外的 20 秒以确保主机真正开始重新启动。
None 以上解决方案对我来说很可靠。
发出 /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 秒后重启。
- 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
另一个(结合其他答案)版本:
---
- 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
Ansible 正在快速发展,旧的答案对我不起作用。
我发现了两个问题:
- 推荐的重启方式可能会在 Ansible 完成任务之前终止 SSH 连接。
不如运行:nohup bash -c "sleep 2s && shutdown -r now" &
这将启动带有 sleep
&& shutdown
的 shell,但由于最后一个 &
而不会等待 shell 结束.睡眠将为 Ansible 任务在重启前结束提供一些时间,并且 nohup
将保证 bash 在任务结束时不会被杀死。
wait_for
模块无法可靠地等待 SSH 服务。
它检测到端口打开,可能是systemd打开的,但是当下一个任务是运行时,SSH仍然没有准备好。
如果您使用的是 Ansible 2.3+,wait_for_connection 工作可靠。
根据我的经验(我使用的是 Ansible 2.4),最好的 'reboot and wait' 如下:
- 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
我从以下位置获得了 nohup 命令:https://github.com/keithchambers/microservices-playground/blob/master/playbooks/upgrade-packages.yml
我将此消息编辑为:
- 添加 krad 的可移植性建议,现在使用 shutdown -r 而不是 reboot
- 添加延迟。需要避免Ansible在重启慢的情况下执行下一步
- 增加超时时间,120 秒对于一些慢速 BIOS 来说太短了。
我正在使用 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
然后尽快投票制作剧本return:
- name: Wait for the server to finish rebooting
wait_for_connection:
delay: 15
sleep: 15
timeout: 300
这将使 playbook 在重启后尽快 return。
以下解决方案非常适合我:
- 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 需要几秒钟的时间来结束连接。 关于这个问题的优秀 post 写在这里: https://www.jeffgeerling.com/blog/2018/reboot-and-wait-reboot-complete-ansible-playbook
如果您使用的 Ansible 版本 >=2.7,您可以使用 reboot
模块,如 here
reboot
模块本身的概要:
Reboot a machine, wait for it to go down, come back up, and respond to commands.
简单来说,你可以这样定义一个简单的任务:
- name: reboot server
reboot:
但是你可以添加一些参数,比如 test_command
来测试你的服务器是否准备好接受进一步的任务
- name: reboot server
reboot:
test_command: whoami
希望对您有所帮助!