Столкнулись с задачей: полностью пустой сервер, настраивать полностью через ansible, «так что бы даже обезьяна» справилась", — дословная цитата клиента.
Исходные данные: есть сервер, с ОС СentOS 7, внешним IP и паролем root.
Задача: установить на него все обновления, ПО по списку и ни разу к нему не подключиться консолью. Весь процесс описывать нет смысла, но есть два интересных момента о которых я и расскажу. А именно, как с помощью ansible настроить ansible и как перезагрузить сервер, а потом продолжить выполнять palybook.
Из исходных данных видно, что на сервере есть только root. Большинство заметок по ansible начинаются с того, что надо сгенерировать ключ, потом добавить его в доверенные на подчиненных машинах, прописать в sudoers права и тд. А если мы не хотим каждый раз делать это сами? Можно сделать шаблон вм, где это уже будет все сделано. А если это физический сервер и ОС ставит на него хостер? А вот тут нам на помощь приходит волшебный ключ: --ask-pass. Этот ключ позволяет использовать авторизацию не по ключу, а по паролю. Ну а дальше дело техники — прописываем через task все, что нам нужно.
Так, сервер подготовлен для работы с ansible, теперь надо поставить на него обновления, а ведь среди них может быть и ядро. И тогда нам понадобится перезагрузка. Если просто его перезагрузить, то ansible, выдаст ошибку. 5 минут общения выдали мне рабочий вариант. Я обрадовался, заварил себя чашечку ароматного кофе и приготовился наслаждаться тем, как все само настраивается. Не тут-то было! Оказалось, в СentOS 7 reboot выполняется по технологии as soon as posible и, как следствие, ansible не успевает обрабатывать результат и вылетает с ошибкой. Достаточно быстро нашлось очевидное решение, выполнять shutdown -r 1, что делает задержку в одну минуту. Да это работает и вполне подойдет если надо развернуть 1-2 хоста, но если их 100, то задержка получится в 100 минут + время ребута. А это… очень много времени.
Методом проб и ошибок, был найден следующий вариант:
name: Reboot
shell: nohup bash -c «sleep 2s && reboot» &
when: kernel_update.changed
async: 0
poll: 0
ignore_errors: true
register: reboot
— name: wait for the server to restart
local_action: wait_for host={{ inventory_hostname }}
port=22
delay=10
timeout=300
state=started
sudo: false
when: reboot.changed
Результатом выполнения является перезагрузка сервера и ожидание пока он станет доступен после оного.
Спасибо за внимание!
Автор: системный администратор компании Magvai69
Комментарии (9)
schors
20.08.2015 12:42-1[кашлянув] Вы перегружаете сервер командой «reboot»? Я что-то пропустил и за последние 10 лет shutdown и reboot местами поменялись? Reboot же всегда аварийной командой был.
akhaustov
20.08.2015 12:49Сервер пустой, ничего на нем нет, потому и нет смысла ждать завершения процессов.
Последние 3 года использую reboot вместо shutdown -r и все прекрасно. Правда, только в CentOS.
alterpub
20.08.2015 14:17reboot давненько уже стопает сервисы и на убунтах и на федорах
schors
20.08.2015 14:24Я не уверен, что это хорошо. Неаккуратненько. Поведение разнится от системы к системе. На CentOS это вообще systemctl, который хрен знает что там делает. Ну или, кстати, тогда уж systemctl сразу, почему нет?
xtavras
21.08.2015 15:27reboot на systemd системах это лишь симлинк для «systemctl reboot»
schors
21.08.2015 15:30На systemd да, а на не systemd по разному. Более того, не факт, что в будующем systemd будет это идентично воспринимать. Изначально задача всё-таки подразумевает shutdown. И например копипаста reboot на хост с FreeBSD приведет немного не к тем последствиям, а shutdown — везде shutdown
foxmuldercp
22.08.2015 21:05Ansible-playbook можно легко превратить в кроссдистрибутивный, если правильно обработать предварительно собранное состояние машины, в частности параметр значения операционной системы хоста
isden
© support.ansible.com/hc/en-us/articles/201958037-Reboot-a-server-and-wait-for-it-to-come-back