如何使用Ansible重新启动CentOS 7?

时间:2015-04-29 22:21:07

标签: centos ansible centos7

我正在尝试重新启动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

我做错了什么?我该如何解决这个问题?

11 个答案:

答案 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=10delay=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正在迅速发展,旧答案对我不起作用。

我发现了两个问题:

  • 推荐的重启方式可能会在Ansible完成任务之前终止SSH连接。

最好运行: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命令

我将此消息编辑为:

  • 添加krad的可移植性建议,使用shutdown -r now而不是reboot
  • 添加延迟。如果重启很慢,则需要避免Ansible执行下一步
  • 增加超时,120s对于某些慢速BIOS来说太少了。

答案 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: truefailed_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

希望这会有所帮助!