我试图重新启动服务器,然后等待,使用:
- 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
答案 0 :(得分:52)
使用新的reboot模块。
- name: restart server
shell: 'sleep 1 && shutdown -r now "Reboot triggered by Ansible" && sleep 1'
async: 1
poll: 0
become: true
这将shell命令作为asynchronous task运行,因此Ansible不会等待命令的结束。通常async
param为任务提供了最长的时间,但是当poll
设置为0时,Ansible将永远不会轮询该命令是否已完成 - 它将使该命令成为"触发并忘记&#34 ;。在shutdown
之前和之后休眠是为了防止在Ansible仍然连接到远程主机时重启期间断开SSH连接。
你可以使用:
- name: Wait for server to restart
local_action:
module: wait_for
host={{ inventory_hostname }}
port=22
delay=10
become: false
..但如果使用以下条目,您可能更喜欢使用{{ ansible_ssh_host }}
变量作为主机名和/或{{ ansible_ssh_port }}
作为SSH主机和端口:
hostname ansible_ssh_host=some.other.name.com ansible_ssh_port=2222
..在您的广告资源中(Ansible hosts
文件)。
这将运行wait_for任务on the machine running Ansible。此任务将等待端口22在远程主机上打开,延迟10秒后开始。
但我建议将这两者用作处理程序,而不是任务。
这有两个主要原因:
代码重用 - 您可以为许多任务使用处理程序。 示例:触发服务器重启after changing the timezone并在更改内核后
只触发一次 - 如果您为一些任务使用处理程序,并且其中超过1个将进行一些更改=>触发处理程序,然后处理程序执行的操作只会发生一次。 示例:如果你有一个httpd重启处理程序附加到httpd配置更改和SSL证书更新,那么如果配置和SSL证书更改httpd将只重启一次。
详细了解处理程序here。
重新启动并等待重新启动作为处理程序:
handlers:
- name: Restart server
command: 'sleep 1 && shutdown -r now "Reboot triggered by Ansible" && sleep 1'
async: 1
poll: 0
ignore_errors: true
become: true
- name: Wait for server to restart
local_action:
module: wait_for
host={{ inventory_hostname }}
port=22
delay=10
become: false
..并按顺序在你的任务中使用它,就像这样,这里配合重启服务器处理程序:
tasks:
- name: Set hostname
hostname: name=somename
notify:
- Restart server
- Wait for server to restart
请注意 handlers are run in the order they are defined, not the order they are listed in notify
!
答案 1 :(得分:33)
您应该将wait_for任务更改为local_action,并指定您正在等待的主机。例如:
- name: Wait for server to restart
local_action:
module: wait_for
host=192.168.50.4
port=22
delay=1
timeout=300
答案 2 :(得分:10)
我最可靠的是1.9.4得到了(这是更新的,原始版本在底部):
- name: Example ansible play that requires reboot
sudo: yes
gather_facts: no
hosts:
- myhosts
tasks:
- name: example task that requires reboot
yum: name=* state=latest
notify: reboot sequence
handlers:
- name: reboot sequence
changed_when: "true"
debug: msg='trigger machine reboot sequence'
notify:
- get current time
- reboot system
- waiting for server to come back
- verify a reboot was actually initiated
- name: get current time
command: /bin/date +%s
register: before_reboot
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=220
sudo: false
- name: verify a reboot was actually initiated
# machine should have started after it has been rebooted
shell: (( `date +%s` - `awk -F . '{print $1}' /proc/uptime` > {{ before_reboot.stdout }} ))
sudo: false
请注意async
选项。 1.8和2.0可能与0
一起生效,但1.9想要它1
。以上还检查机器是否实际重启。这很好,因为一旦我输入错误导致重启失败并且没有失败的迹象。
最大的问题是等待机器升级。这个版本只是在那里坐了330秒,从来没有尝试过早点访问主机。其他一些答案建议使用端口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
答案 3 :(得分:8)
从2.3开始,Ansible现在附带wait_for_connection
模块,可用于此目的。
#
## 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
shutdown -r +1可以防止返回1的返回码,并且ansible使任务失败。关闭作为异步任务运行,因此我们必须将wait_for_connection
任务延迟至少60秒。 75为我们提供了雪花盒的缓冲区。
wait_for_connection - Waits until remote system is reachable/usable
答案 4 :(得分:6)
我想评论Shahar帖子,他使用硬编码的主机地址更好的是让它变量来引用当前主机ansible正在配置{{inventory_hostname}},所以他的代码将是这样的:
- name: Wait for server to restart
local_action:
module: wait_for
host={{ inventory_hostname }}
port=22
delay=1
timeout=300
答案 5 :(得分:5)
对于较新版本的Ansible(在我的情况下为1.9.1),轮询和异步参数设置为0有时是不够的(可能取决于设置的分布是什么?)。正如https://github.com/ansible/ansible/issues/10616中所解释的,一个解决方法是:
- name: Reboot
shell: sleep 2 && shutdown -r now "Ansible updates triggered"
async: 1
poll: 0
ignore_errors: true
然后,等待重新启动完成,如本页的许多答案中所述。
答案 6 :(得分:4)
通过反复试验+大量阅读这是最终使用2.0版Ansible的工作方式:
$ 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:
答案 7 :(得分:0)
- wait_for:
port: 22
host: "{{ inventory_hostname }}"
delegate_to: 127.0.0.1
答案 8 :(得分:0)
如果您还没有远程服务器的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
这是我添加到ansible-swap playbook末尾的两项任务(在新的Digital Ocean水滴上安装4GB交换。
答案 9 :(得分:0)
我创建了一个reboot_server ansible角色,该角色可以通过以下方式从其他角色中动态调用:
- 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
这最初是设计用于Ubuntu OS的。
答案 10 :(得分:0)
关于此,我没有看到太多可见性,但是最近的更改(https://github.com/ansible/ansible/pull/43857)添加了“ ignore_unreachable”关键字。这使您可以执行以下操作:
- name: restart server
shell: reboot
ignore_unreachable: true
- name: wait for server to come back
wait_for_connection:
timeout: 120
- name: the next action
...