Linux 如何使用Ansible等待服务器重启?

Linux 如何使用Ansible等待服务器重启?,linux,deployment,ssh,ansible,ansible-playbook,Linux,Deployment,Ssh,Ansible,Ansible Playbook,我正在尝试重新启动服务器,然后使用以下命令等待: - name: Restart server shell: reboot - name: Wait for server to restart wait_for: port=22 delay=1 timeout=300 但我得到了这个错误: TASK: [iptables | Wait for server to restart] ********************************* fatal

我正在尝试重新启动服务器,然后使用以下命令等待:

- name: Restart server
  shell: reboot

- name: Wait for server to restart
  wait_for:
    port=22
    delay=1
    timeout=300
但我得到了这个错误:

TASK: [iptables | Wait for server to restart] ********************************* 
fatal: [example.com] => failed to transfer file to /root/.ansible/tmp/ansible-tmp-1401138291.69-222045017562709/wait_for:
sftp> put /tmp/tmpApPR8k /root/.ansible/tmp/ansible-tmp-1401138291.69-222045017562709/wait_for

Connected to example.com.
Connection closed

您应该更改wait_for task的运行方式,并指定正在等待的主机。例如:

- name: Wait for server to restart
  local_action:
    module: wait_for
      host=192.168.50.4
      port=22
      delay=1
      timeout=300

我想对Shahar post发表评论,他使用硬编码的主机地址更好的方法是使用一个变量来引用当前主机ansible正在配置{{inventory_hostname},因此他的代码如下:

- name: Wait for server to restart
  local_action:
    module: wait_for
     host={{ inventory_hostname }}
     port=22
     delay=1
     timeout=300
Ansible>=2.7(于2018年10月发布) 使用新模块:

-name:等待服务器重新启动
重新启动:
重新启动超时:3600
Ansible<2.7 作为任务重新启动
-名称:重新启动服务器
shell:'sleep 1&&shutdown-r now“由Ansible触发的重新启动”&&sleep 1'
异步:1
投票:0
变成:真的
这将作为一个命令运行shell命令,因此Ansible不会等待命令结束。通常,
async
param提供任务的最长时间,但由于
poll
设置为0,如果命令已完成,Ansible将永远不会轮询-它将使此命令成为“激发并忘记”。关闭前后的休眠是为了防止在Ansible仍连接到远程主机时,在重新启动期间中断SSH连接

作为任务等待 您可以使用:

-name:等待服务器重新启动
地方行动:
模块:等待
主机={{inventory_hostname}
端口=22
延迟=10
变成:假
…但是如果您使用以下条目,您可能更喜欢使用
{{ansible\u ssh\u host}
变量作为主机名和/或
{{ansible\u ssh\u port}
作为ssh主机和端口:

hostname         ansible_ssh_host=some.other.name.com ansible_ssh_port=2222 
..在您的清单中(Ansible
hosts
文件)

这将运行任务。此任务将等待远程主机上的端口22打开,延迟10秒后启动

重新启动并作为处理程序等待 但我建议将这两种方法都用作处理程序,而不是任务

这样做有两个主要原因:

  • 代码重用-您可以对许多任务使用处理程序示例:触发服务器重启并在更改内核后

  • 只触发一次-如果您对一些任务使用处理程序,并且其中超过1个任务将进行一些更改=>触发处理程序,那么处理程序所做的事情将只发生一次示例:如果您在httpd配置更改和SSL证书更新中附加了httpd重新启动处理程序,那么在配置和SSL证书更改的情况下,httpd将只重新启动一次

阅读更多关于处理程序的信息

正在作为处理程序重新启动并等待重新启动:

处理程序:
-名称:重新启动服务器
命令:'sleep 1&&shutdown-r now“由Ansible触发的重新启动”&&sleep 1'
异步:1
投票:0
忽略错误:true
变成:真的
-名称:等待服务器重新启动
地方行动:
模块:等待
主机={{inventory_hostname}
端口=22
延迟=10
变成:假
..并在任务中按顺序使用它,如下所示,同时重新启动服务器处理程序:

任务:
-名称:设置主机名
主机名:name=somename
通知:
-重新启动服务器
-等待服务器重新启动

请注意

对于较新版本的Ansible(即我的例子中的1.9.1),轮询和异步参数设置为0有时是不够的(可能取决于Ansible设置的发行版)。如一个解决方案中所述:

- wait_for:
    port: 22
    host: "{{ inventory_hostname }}"
  delegate_to: 127.0.0.1
- name: Reboot
  shell: sleep 2 && shutdown -r now "Ansible updates triggered"
  async: 1
  poll: 0
  ignore_errors: true

然后,等待重新启动完成,如本页的许多答案所述。

通过反复试验+大量阅读,这就是我使用Ansible 2.0版本的最终效果:

$ ansible --version
ansible 2.0.0 (devel 974b69d236) last updated 2015/09/01 13:37:26 (GMT -400)
  lib/ansible/modules/core: (detached HEAD bbcfb1092a) last updated 2015/09/01 13:37:29 (GMT -400)
  lib/ansible/modules/extras: (detached HEAD b8803306d1) last updated 2015/09/01 13:37:29 (GMT -400)
  config file = /Users/sammingolelli/projects/git_repos/devops/ansible/playbooks/test-2/ansible.cfg
  configured module search path = None
我的禁用SELinux并在需要时重新启动节点的解决方案:

---
- name: disable SELinux
  selinux: state=disabled
  register: st

- name: reboot if SELinux changed
  shell: shutdown -r now "Ansible updates triggered"
  async: 0
  poll: 0
  ignore_errors: true
  when: st.changed

- name: waiting for server to reboot
  wait_for: host="{{ ansible_ssh_host | default(inventory_hostname) }}" port={{ ansible_ssh_port | default(22) }} search_regex=OpenSSH delay=30 timeout=120
  connection: local
  sudo: false
  when: st.changed

# vim:ft=ansible:

我对1.9.4 got的最可靠的理解是(这是更新的,原始版本在底部):

注意
async
选项。1.8和2.0可能与
0兼容,但1.9希望
1
。上面还检查机器是否已实际重新启动。这很好,因为有一次我的打字错误导致重启失败,并且并没有失败的迹象

最大的问题是等待机器启动。这个版本只在那个里停留了330秒,从来并没有尝试更早地访问主机。其他一些答案建议使用端口22。如果这两个都是真的,这是好的:

  • 您可以直接访问这些机器
  • 端口22打开后,可以立即访问您的机器
这些并不总是正确的,所以我决定浪费5分钟的计算时间。。我希望ansible扩展wait_for模块来实际检查主机状态,以避免浪费时间

顺便说一句,建议使用处理程序的答案很好+1用于我的处理程序(我更新了答案以使用处理程序)

这是原始版本,但不太好,也不太可靠:

- name: Reboot
  sudo: yes
  gather_facts: no
  hosts:
    - OSEv3:children
  tasks:
    - name: get current uptime
      shell: cat /proc/uptime | awk -F . '{print $1}'
      register: uptime
      sudo: false
    - name: reboot system
      shell: sleep 2 && shutdown -r now "Ansible package updates triggered"
      async: 1
      poll: 0
      ignore_errors: true
    - name: waiting for server to come back
      local_action: wait_for host={{ inventory_hostname }} state=started delay=30 timeout=300
      sudo: false
    - name: verify a reboot was actually initiated
      # uptime after reboot should be smaller than before reboot
      shell: (( `cat /proc/uptime | awk -F . '{print $1}'` < {{ uptime.stdout }} ))
      sudo: false
-名称:重新启动
苏多:是的
收集事实:不
主持人:
-OSEv3:儿童
任务:
-名称:获取当前正常运行时间
shell:cat/proc/uptime | awk-F{打印$1}'
注册:正常运行时间
sudo:错
-名称:重新启动系统
shell:sleep 2&&shutdown-r现在“Ansible包更新已触发”
异步:1
投票:0
忽略错误:true
-名称:正在等待服务器返回
本地操作:等待主机={{inventory\u hostname}}状态=启动延迟=30超时=300
sudo:错
-名称:验证是否实际启动了重新启动
#重新启动后的正常运行时间应小于重新启动前的正常运行时间
shell:(`cat/proc/uptime | awk-F.{print$1}`<{{uptime.stdout}}))
sudo:错

如果您尚未为远程服务器设置DNS,您可以传递IP地址而不是可变主机名:

- name: Restart server
  command: shutdown -r now

- name: Wait for server to restart successfully
  local_action:
    module: wait_for
      host={{ ansible_default_ipv4.address }}
      port=22
      delay=1
      timeout=120
这是我在本学期末增加的两项任务(在新的数字海洋水滴上安装4GB交换)。

2018更新 从2.3开始,Ansible现在提供- name: Restart server command: shutdown -r now - name: Wait for server to restart successfully local_action: module: wait_for host={{ ansible_default_ipv4.address }} port=22 delay=1 timeout=120
#
## Reboot
#

- name: (reboot) Reboot triggered
  command: /sbin/shutdown -r +1 "Ansible-triggered Reboot"
  async: 0
  poll: 0

- name: (reboot) Wait for server to restart
  wait_for_connection:
    delay: 75
- name: Reboot server if needed
  include_role:
    name: reboot_server
  vars:
    reboot_force: false
- name: Check if server restart is necessary
  stat:
    path: /var/run/reboot-required
  register: reboot_required

- name: Debug reboot_required
  debug: var=reboot_required

- name: Restart if it is needed
  shell: |
    sleep 2 && /sbin/shutdown -r now "Reboot triggered by Ansible"
  async: 1
  poll: 0
  ignore_errors: true
  when: reboot_required.stat.exists == true
  register: reboot
  become: true

- name: Force Restart
  shell: |
    sleep 2 && /sbin/shutdown -r now "Reboot triggered by Ansible"
  async: 1
  poll: 0
  ignore_errors: true
  when: reboot_force|default(false)|bool
  register: forced_reboot
  become: true

# # Debug reboot execution
# - name: Debug reboot var
#   debug: var=reboot

# - name: Debug forced_reboot var
#   debug: var=forced_reboot

# Don't assume the inventory_hostname is resolvable and delay 10 seconds at start
- name: Wait 300 seconds for port 22 to become open and contain "OpenSSH"
  wait_for:
    port: 22
    host: '{{ (ansible_ssh_host|default(ansible_host))|default(inventory_hostname) }}'
    search_regex: OpenSSH
    delay: 10
  connection: local
  when: reboot.changed or forced_reboot.changed
- name: restart server
  shell: reboot
  ignore_unreachable: true

- name: wait for server to come back
  wait_for_connection: 
      timeout: 120

- name: the next action
  ...