Подтвердить что ты не робот

Как перезагрузить CentOS 7 с помощью Ansible?

Я пытаюсь перезагрузить сервер под управлением CentOS 7 на VirtualBox. Я использую эту задачу:

- 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

Что я делаю неправильно? Как я могу это исправить?

4b9b3361

Ответ 1

Вероятно, вы ничего не делаете неправильно, просто это /sbin/reboot закрывает сервер так быстро, что сервер срывает соединение SSH, используемое Ansible, до того как сам Ansible может закрыть его. В результате Ansible сообщает об ошибке, так как видит непредвиденную попытку подключения SSH.

Что вы можете сделать, чтобы обойти это, это перейти от использования /sbin/reboot к использованию /sbin/shutdown. Команда shutdown позволяет вам пропустить время, и в сочетании с переключателем -r он выполнит перезагрузку, а не завершает работу. Поэтому вы можете попробовать такую ​​задачу:

- name: Restart server
  command: /sbin/shutdown -r +1
  async: 0
  poll: 0
  ignore_errors: true

Это задержит перезагрузку сервера в течение 1 минуты, но при этом он должен предоставить Ansible достаточно времени для закрытия самого SSH-соединения, тем самым избегая ошибки, которую вы сейчас получаете.

Ответ 2

После задачи перезагрузки у вас должна быть задача local_action, ожидающая завершения перезагрузки удаленного хоста, в противном случае соединение ssh будет завершено, и также будет playbook.


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

Ответ 3

- 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

Ответ 4

Ни одно из вышеперечисленных решений не было надежным для меня.

Выдача /sbin/reboot приводит к сбою воспроизведения (соединение SSH закрывается до того, как закончена задача, она сработает даже с ignore_errors: true), а /usr/bin/systemd-run --on-active=2 /usr/bin/systemctl reboot не перезагрузится через 2 секунды, но после случайного промежутка времени между 20 секунд и одна минута, поэтому задержки иногда недостаточно, и это не предсказуемо.

Также я не хочу ждать минут, пока сервер облаков может перезагрузиться через несколько секунд.

Итак, вот мое решение:

- 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 & ) в оболочке script запускает программу в фоновом режиме и отделяет ее: команда выполняется немедленно, но сохраняется после уничтожения оболочки.

Ansible немедленно получит ответ, и сервер перезагрузится через 3 секунды.

Ответ 5

Другое решение:

- 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 в wait_for, чтобы добавить дополнительные 20 секунд, чтобы убедиться, что хост действительно начал перезагружаться.

Ответ 6

Во время перезагрузки все соединения ssh закрыты. Вот почему задача Ansible не работает. Добавления ignore_errors: true или failed_when: false больше не работают с Ansible 1.9.x, потому что обработка соединений ssh ​​изменилась, и закрытое соединение теперь является фатальной ошибкой, которая не может быть обнаружена во время воспроизведения.

Единственный способ, которым я понял, как это сделать, - запустить локальную задачу оболочки, которая затем запускает отдельное ssh-соединение, которое затем может потерпеть неудачу.

- name: Rebooting
  delegate_to: localhost
  shell: ssh -S "none" {{ inventory_hostname }} sudo /usr/sbin/reboot"
  failed_when: false
  changed_when: true

Ответ 7

Еще одна (в сочетании с другими ответами) версия:

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

Ответ 8

Ansible быстро развивается, и старые ответы не работают для меня.

Я нашел два вопроса:

  • Рекомендуемый способ перезагрузки может убить SSH-соединение до того, как Ansible завершит задачу.

Лучше запустить: 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

Я отредактировал это сообщение:

  • добавить предложение krad portability, используя shutdown -r вместо перезагрузки
  • добавить задержку. Необходимо, чтобы Ansible выполнил следующий шаг, если перезагрузка будет медленной.
  • увеличить таймаут, 120 секунд было слишком мало для некоторых медленных BIOS.