Есть много причин, по которым ansible может зависнуть при сборе фактов, но прежде чем идти дальше, вот первый тест, который вы должны выполнить в любой такой ситуации:
ansible -m ping <hostname>
Этот тест просто подключается к хосту и выполняет достаточно кода для возврата:
<hostname> | SUCCESS => {
"changed": false,
"ping": "pong"
}
Если это работает, вы можете в значительной степени исключить любую проблему с настройкой или подключением, поскольку это доказывает, что вы можете разрешить целевое имя хоста, открыть соединение, аутентифицироваться и выполнить ответный модуль с помощью удаленного интерпретатора python.
Теперь, вот (не исчерпывающий) список вещей, которые могут пойти не так в начале книги игр:
Команда, выполняемая ansible, ожидает интерактивного ввода
Я могу вспомнить, что это происходило в более старых версиях ANSI, где команда ожидала интерактивного ввода, который никогда не поступит, такого как пароль sudo (если вы забыли -K
переключатель), или принятие нового отпечатка хоста ssh (для новой цели). хост).
Современные версии ansible корректно обрабатывают оба этих случая и немедленно вызывают ошибку для обычных случаев использования, поэтому, если вы сами не делаете такие вещи, как вызов ssh или sudo, у вас не должно быть проблем такого рода. И даже если бы вы это сделали, это было бы после сбора фактов.
Dead ssh master соединение
В журнале отладки, приведенном здесь, есть несколько очень интересных опций, переданных клиенту ssh:
ControlMaster=auto
ControlPersist=60s
ControlPath=/home/vagrant/.ansible/cp/ansible-ssh-%h-%p-%r
Эти параметры описаны в man ssh_config .
По умолчанию ansible постарается проявить смекалку в отношении использования ssh-соединения. Для данного хоста вместо создания нового соединения для каждой задачи в пьесе он откроет его один раз и оставит открытым для всей пьесы (и даже для всех книг).
Это хорошо, поскольку установление нового соединения намного медленнее и требует больших вычислительных ресурсов, чем использование уже существующего.
На практике каждое ssh-соединение будет проверять наличие сокета в ~/.ansible/cp/some-host-specific-path
. Первое соединение не может найти его, поэтому оно подключается нормально, а затем создает его. Каждое последующее соединение будет просто использовать этот сокет, чтобы пройти через уже установленное соединение.
Даже если установленное соединение, наконец, перестает работать и закрывается после того, как не использовалось достаточно долго, сокет тоже закрывается, и мы возвращаемся к исходной точке.
Все идет нормально.
Иногда, однако, соединение на самом деле умирает, но клиент ssh по-прежнему считает его установленным. Обычно это происходит, когда вы запускаете playbook со своего ноутбука и теряете соединение WiFi (или переключаетесь с WiFi на Ethernet и т. Д.)
Последний пример - ужасная ситуация: вы можете использовать ssh на целевой машине с конфигурацией ssh по умолчанию, но пока ваше предыдущее соединение все еще считается активным, ansible даже не будет пытаться установить новое.
На данный момент мы просто хотим избавиться от этого старого сокета, и самый простой способ сделать это - удалить его:
# Delete all the current sockets (may disrupt currently running playbooks)
rm -r ~/.ansible/cp
# Delete only the affected socket (requires to know which one it is)
rm ~/.ansible/cp/<replace-by-your-socket>
Это идеально подходит для однократного исправления, но если это происходит слишком часто, вам, возможно, придется искать более долгосрочное исправление. Вот несколько советов, которые могут помочь в достижении этой цели:
- Запуск Playbooks с сервера (с более стабильным подключением к сети, чем у вашего ноутбука)
- Используйте конфигурацию ANSIBLE или непосредственно конфигурацию клиента ssh, чтобы отключить общий доступ к соединению
- Используйте те же ресурсы, но для точной настройки тайм-аутов, чтобы сбой основного соединения фактически превышал время ожидания
Обратите внимание, что на момент написания этой статьи несколько вариантов изменилось (например, мой последний прогон дал мне ControlPath=/home/toadjaune/.ansible/cp/871b533295
), но общая идея остается в силе.
На самом деле сбор фактов занимает слишком много времени
В начале каждой игры ansible собирает много информации о целевой системе и помещает ее в факты . Это переменные, которые вы можете затем использовать в своей книге игр, и они обычно очень удобны, но иногда получение этой информации может быть очень долгим (плохие точки монтирования, диски с высокой скоростью ввода-вывода, высокой нагрузкой…)
Это , как говорится, не строго нужны факты , чтобы запустить сборник пьес, и почти наверняка не все из них, так что давайте попробуем отключить то , что нам не нужно. Несколько вариантов для этого:
В целях отладки действительно удобно вызывать модуль установки непосредственно из командной строки:
ansible -m setup <hostname>
Эта последняя команда должна зависнуть так же, как ваша книга воспроизведения, и, в конечном итоге, время ожидания (или успех). Теперь давайте снова запустим модуль, отключив все, что можем:
ansible -m setup -a gather_subset='!all' <hostname>
Если это все еще зависает, вы всегда можете попробовать полностью отключить модуль в вашей игре, но вполне вероятно, что ваша проблема в другом месте.
Если, однако, он работает хорошо (и быстро), то посмотрите документацию к модулю . У вас есть два варианта:
- Ограничьте сбор фактов подмножеством, исключая то, что вам не нужно (см. Возможные значения для
gather_subset
)
gather_timeout
может также помочь вам решить вашу проблему, предоставив больше времени (хотя это будет исправление ошибки тайм-аута, а не зависание)
Другие вопросы
Очевидно, что другие вещи могут пойти не так, как надо. Несколько указателей, помогающих отладке:
- Используйте максимально допустимый уровень детализации (
-vvvv
), так как он покажет вам каждую выполненную команду
- Используйте
ping
и setup
модули непосредственно из командной строки, как описано выше
- Попробуйте ssh вручную, если
ansible -m ping
не работает
vagrant ssh
исследовать во время зависания, чтобы увидеть, есть ли что-нибудь полезное вps
иnetstat
? Кроме того, одним из первых подозреваемых в зависаниях является DNS - проверьте, разрешается ли DNS изнутри виртуальной машины.