私はこれを使用してサーバーを再起動してから待機しようとしています:
- 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タスクを local_action として実行するように変更し、待機しているホストを指定する必要があります。例えば:
- name: Wait for server to restart
local_action:
module: wait_for
Host=192.168.50.4
port=22
delay=1
timeout=300
新しい reboot モジュールを使用します。
- name: restart server
Shell: 'sleep 1 && shutdown -r now "Reboot triggered by Ansible" && sleep 1'
async: 1
poll: 0
become: true
これにより、シェルコマンドが 非同期タスク として実行されるため、Ansibleはコマンドの終了を待機しません。通常、async
paramはタスクの最大時間を提供しますが、poll
が0に設定されているため、コマンドが終了した場合、Ansibleは決してポーリングしません。 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 タスクを実行します Ansibleを実行しているマシン上 。このタスクは、リモートホストでポート22が開くまで待機し、10秒遅れて開始します。
ただし、これらの両方をタスクではなくハンドラーとして使用することをお勧めします。
これを行う主な理由は2つあります。
コードの再利用-ハンドラを多くのタスクに使用できます。 例:トリガーサーバーの再起動 タイムゾーンの変更後 およびカーネルの変更後、
一度だけトリガーする-いくつかのタスクにハンドラーを使用し、それらの2つ以上が何らかの変更を行う=>ハンドラーをトリガーする場合、ハンドラーが行うことは一度だけ行われます。 例:httpdの設定変更とSSL証明書の更新にhttpd再起動ハンドラーが接続されている場合、設定とSSL証明書の両方が変更された場合、httpdが再起動されます1回だけ。
ハンドラーについて詳しく読む 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
私が持っている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分の計算時間を浪費することにしました。
ところで、ハンドラーを使用することを提案する答えは素晴らしいです。私からのハンドラーに対して+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
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が戻されないようにし、タスクを失敗させる可能性があります。シャットダウンは非同期タスクとして実行されるため、wait_for_connection
タスクは少なくとも60秒。 75は、これらのスノーフレークケース用のバッファーを提供します。
Shaharの投稿にコメントしたかったのですが、ハードコードされたホストアドレスを使用している方が、現在のホストansibleが{{inventory_hostname}}を構成していることを参照する変数を持っているため、彼のコードは次のようになります:
- name: Wait for server to restart
local_action:
module: wait_for
Host={{ inventory_hostname }}
port=22
delay=1
timeout=300
Ansibleの新しいバージョン(私の場合は1.9.1)では、pollおよびasyncパラメーターを0に設定するだけでは十分でない場合があります(どのディストリビューションがansibleにセットアップされているかによって異なります)。 https://github.com/ansible/ansible/issues/10616 で説明されているように、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:
私は、他のロールから動的に呼び出される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で動作するように設計されました。
これについてはあまり目立ちませんが、最近の変更( 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
...
リモートサーバーの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のスワップをインストールするため)の最後に追加した2つのタスクです。
- wait_for:
port: 22
Host: "{{ inventory_hostname }}"
delegate_to: 127.0.0.1