44

これを使用して、サーバーを再起動してから待機しようとしています:

- 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
4

11 に答える 11

61

Ansible >= 2.7 (2018 年 10 月にリリース)

組み込みの再起動モジュールを使用します。

- name: Wait for server to restart
  reboot:
    reboot_timeout: 3600

アンシブル < 2.7

タスクとして再開

- name: restart server
  shell: 'sleep 1 && shutdown -r now "Reboot triggered by Ansible" && sleep 1'
  async: 1
  poll: 0
  become: true

これにより、シェル コマンドが非同期タスクとして実行されるため、Ansible はコマンドの終了を待機しません。通常、asyncparam はタスクの最大時間を提供しますが、poll0 に設定されているため、コマンドが終了した場合、Ansible は決してポーリングしません。これにより、このコマンドは「起動して忘れる」ようになります。shutdownAnsible がリモート ホストに接続されている間、再起動中に 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 

..インベントリ (Ansiblehostsファイル) 内。

これにより、Ansible を実行しているマシンでwait_forタスクが実行されます。このタスクは、リモート ホストでポート 22 が開くのを待ち、10 秒後に開始します。

再起動してハンドラとして待機

ただし、これらの両方をタスクではなくハンドラーとして使用することをお勧めします。

これを行う主な理由は 2 つあります。

  • コードの再利用 - 多くのタスクにハンドラーを使用できます。例:タイムゾーンの変更後およびカーネルの変更後にサーバーの再起動をトリガーします。

  • 一度だけトリガーする - いくつかのタスクにハンドラーを使用し、それらの複数が何らかの変更を行う場合 => ハンドラーをトリガーすると、ハンドラーが行うことは一度だけ発生します。例: httpd 構成の変更と SSL 証明書の更新に接続された httpd 再起動ハンドラーがある場合、構成と SSL 証明書の両方が変更された場合、httpd は 1 回だけ再起動されます。

ハンドラーの詳細については、こちらをご覧ください。

ハンドラーとしての再起動と再起動の待機:

  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

ハンドラは、リストされている順序ではなく、定義されている順序で実行されるnotifyことに注意してください。

于 2015-01-21T15:24:11.960 に答える
37

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
于 2014-05-27T11:35:28.847 に答える
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 の使用が提案されています。これらの両方が当てはまる場合、これは適切です。

  • マシンに直接アクセスできます
  • ポート 22 が開いた直後にマシンにアクセスできる

これらは常に正しいとは限らないため、5 分間の計算時間を無駄にすることにしました。時間の無駄を避けるために、実際にホストの状態をチェックするように 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
于 2016-01-25T19:35:52.813 に答える
4

試行錯誤と多くの読書を通じて、これは最終的に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:
于 2015-09-03T18:51:53.457 に答える
1
- wait_for:
    port: 22
    host: "{{ inventory_hostname }}"
  delegate_to: 127.0.0.1
于 2015-04-10T04:53:32.573 に答える