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接続を切断します。その結果、予期しない理由でSSH接続が失敗したため、Ansibleはエラーを報告しています。
これを回避するには、/sbin/reboot
を使用して/sbin/shutdown
代わりに。 shutdownコマンドを使用すると、時間を渡すことができます。また、-r
スイッチは、実際にシャットダウンするのではなく再起動を実行します。したがって、次のようなタスクを試してみてください。
- name: Restart server
command: /sbin/shutdown -r +1
async: 0
poll: 0
ignore_errors: true
これにより、サーバーの再起動が1分間遅延しますが、そうすることで、SSH接続自体を閉じるのに十分な時間をAnsibleに与え、現在発生しているエラーを回避できます。
再起動タスクの後、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/
- 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: 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
は、開始する「オンザフライ」の新しいサービスを作成しますsystemctl reboot
10秒の遅延後(--on-active=10
)。 delay=30
in wait_for
20秒を追加して、ホストが実際にリブートを開始したことを確認します。
上記のソリューションはどれも私にとって確実に機能しませんでした。
_/sbin/reboot
_を発行すると、プレイがクラッシュします(ansibleがタスクを完了する前にSSH接続が閉じられ、_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 & )
行です。
シェルスクリプトで_( command & )
_を使用すると、プログラムがバックグラウンドで実行され、切り離されます。コマンドはすぐに成功しますが、シェルが破棄されても持続します。
Ansibleはすぐに応答を取得し、3秒後にサーバーが再起動します。
Ansibleの開発は急速に進んでおり、古い回答は役に立たなかった。
2つの問題が見つかりました。
実行することをお勧めします:Nohup bash -c "sleep 2s && shutdown -r now" &
これにより、sleep
&& shutdown
を使用してシェルが起動しますが、最後の&
が原因でシェルが終了するのを待ちません。スリープは、再起動前に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
私はNohupコマンドを以下から入手しました: https://github.com/keithchambers/microservices-playground/blob/master/playbooks/upgrade-packages.yml
このメッセージを編集して:
さらに別の(他の回答と組み合わせた)バージョン:
---
- 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バージョン> = 2.7を使用している場合、 here のようにreboot
モジュールを使用できます
reboot
モジュール自体の概要:
マシンを再起動し、マシンがダウンするのを待って、再びアップし、コマンドに応答します。
簡単な方法で、次のような簡単なタスクを定義できます。
- name: reboot server
reboot:
ただし、test_command
などのパラメーターを追加して、サーバーがさらにタスクを実行する準備ができているかどうかをテストできます。
- name: reboot server
reboot:
test_command: whoami
お役に立てれば!
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
これにより、再起動後できるだけ早くプレイブックが返されます。
次の解決策は私にとって完璧に機能します:
- 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
再起動時に、すべてのssh接続が閉じられます。これが、Ansibleタスクが失敗する理由です。 ignore_errors: true
またはfailed_when: false
ssh接続の処理が変更され、クローズされた接続がプレイ中にキャッチできない致命的なエラーになったため、Ansible 1.9.xの時点で追加は機能しなくなりました。
その方法を考え出した唯一の方法は、ローカルシェルタスクを実行することです。これにより、別のssh接続が開始され、その後失敗する可能性があります。
- name: Rebooting
delegate_to: localhost
Shell: ssh -S "none" {{ inventory_hostname }} Sudo /usr/sbin/reboot"
failed_when: false
changed_when: true