Назад | Перейти на главную страницу

Ansible застрял на сборе фактов

У меня странные проблемы с моим доступным ящиком (бродяга).

Вчера все работало, и мой плейбук работал нормально.

Сегодня ансибл висит на "сборе фактов"?

Вот подробный вывод:

<5.xxx.xxx.xxx> ESTABLISH CONNECTION FOR USER: deploy
<5.xxx.xxx.xxx> REMOTE_MODULE setup
<5.xxx.xxx.xxx> EXEC ['ssh', '-C', '-tt', '-vvv', '-o', 'ControlMaster=auto', '-
o', 'ControlPersist=60s', '-o', 'ControlPath=/home/vagrant/.ansible/cp/ansible-s
sh-%h-%p-%r', '-o', 'Port=2221', '-o', 'KbdInteractiveAuthentication=no', '-o',
'PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey', '-o
', 'PasswordAuthentication=no', '-o', 'User=deploy', '-o', 'ConnectTimeout=10',
'5.xxx.xxx.xxx', "/bin/sh -c 'mkdir -p $HOME/.ansible/tmp/ansible-tmp-1411372677
.18-251130781588968 && chmod a+rx $HOME/.ansible/tmp/ansible-tmp-1411372677.18-2
51130781588968 && echo $HOME/.ansible/tmp/ansible-tmp-1411372677.18-251130781588
968'"]

У меня была аналогичная проблема с Ansible ping на Vagrant, он просто внезапно завис без причины и ранее работал абсолютно нормально. В отличие от любой другой проблемы, такой как ssh или проблема с соединением, она просто навсегда умирает без тайм-аута.

Одна вещь, которую я сделал, чтобы решить эту проблему, - очистить ~/.ansible каталог, и он снова работает. Я не могу понять, почему, но проблема была решена.

Если у вас есть сдача, чтобы получить ее снова, попробуйте очистить ~/.ansible папку перед обновлением файла Vagrant.

Для меня модуль модуля настройки застрял на мертвом монтировании NFS.

Если вы выполняете «df» на своей машине и ничего не происходит, возможно, вы находитесь в том же случае.

PS: если вы не можете размонтировать общий ресурс / точку монтирования NFS, подумайте об использовании неправильной команды «umount -l»

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

Ansible не может подключиться к целевому хосту

Проблемы с ключом хоста (known_hosts)

1) В более старых версиях Ansible (2.1 или более ранних) Ansible не всегда сообщал вам, если ключ хоста для пункта назначения не существует в источнике или есть несоответствие.

Решение: попробуйте открыть SSH-соединение с теми же параметрами для этого пункта назначения. Вы можете обнаружить ошибки SSH, которые необходимо устранить, и тогда команда будет работать.

2) Иногда Ansible отображает вам сообщение о соединении SSH среди других статусов, в результате чего Ansible "зависает" на этой задаче:

Warning: the ECDSA host key for 'myhost' differs from the key for the IP address '10.10.1.10'
Offending key for IP in /etc/ssh/ssh_known_hosts:246
Matching host key in /etc/ssh/ssh_known_hosts:477
Are you sure you want to continue connecting (yes/no)?

В этом случае просто набрав «да» на столько вопросов по SSH, сколько вам было задано, игра будет продолжена. После этого вы можете исправить проблемы с root-файлами known_hosts.

Проблемы с аутентификацией закрытого ключа

При использовании аутентификации на основе ключа и пароля возникают другие проблемы:

  • Закрытый ключ может быть неправильно настроен на месте назначения
  • Закрытый ключ может иметь неправильные разрешения локально (должен быть доступен для чтения только пользователю, выполняющему задание Ansible)

Решение: попробуйте запустить ansible -m ping <destination> -k против проблемного хоста - если это не сработает, попробуйте Основные проблемы хоста решения выше.

Ansible не может быстро собрать факты

В setup модуль (при автоматическом запуске в начале ansible-playbook запустить, или при запуске вручную как ansible -m setup <host>) часто может зависать при сборе аппаратных данных (например, при получении информации о диске от хостов с высоким уровнем ввода-вывода, неправильными записями монтирования и т. д.).

Решение: попробуйте запустить ansible -m setup -a gather_subset=!all <destination>. Если это сработает, вам следует подумать о том, чтобы установить эту строку в своем ansible.cfg:

gather_subset=!hardware

Есть много причин, по которым анзибл может зависать при сборе фактов, но прежде чем продолжить, вот первый тест, который вы должны сделать в любой такой ситуации:

ansible -m ping <hostname>

Этот тест просто подключается к хосту и выполняет достаточно кода для возврата:

<hostname> | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

Если это сработает, вы можете в значительной степени исключить любую проблему с настройкой или подключением, поскольку это доказывает, что вы можете разрешить целевое имя хоста, открыть соединение, аутентифицировать и выполнить доступный модуль с помощью удаленного интерпретатора python.

А теперь вот (не исчерпывающий) список вещей, которые могут пойти не так в начале сценария:

Команда, выполняемая ansible, ожидает интерактивного ввода

Я помню, как это происходило в более старых версиях ansible, где команда ожидала интерактивного ввода, который никогда не поступил бы, например, пароля sudo (когда вы забыли -K switch) или принятие нового отпечатка хоста ssh (для нового целевого хоста).

Современные версии ansible изящно обрабатывают оба этих случая и немедленно вызывают ошибку для обычных вариантов использования, поэтому, если вы сами не выполняете такие действия, как вызов ssh или sudo, у вас не должно быть таких проблем. И даже если бы вы это сделали, это было бы сбором фактов.

Мертвое главное соединение ssh

В журнале отладки, приведенном здесь, есть несколько очень интересных параметров, переданных ssh-клиенту:

  • ControlMaster=auto
  • ControlPersist=60s
  • ControlPath=/home/vagrant/.ansible/cp/ansible-ssh-%h-%p-%r

Эти параметры задокументированы в человек ssh_config.

По умолчанию ansible будет пытаться использовать ssh-соединение с умом. Для данного хоста вместо того, чтобы создавать новое соединение для каждой задачи в игре, он откроет его один раз и оставит открытым для всей playbook (и даже между playbooks).

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

На практике каждое 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 с сервера (с сетевым подключением более стабильным, чем у вашего ноутбука)
  • Использовать доступная конфигурация, или напрямую конфигурация клиента ssh отключить совместное использование подключения
  • Используйте те же ресурсы, но для точной настройки тайм-аутов, чтобы сбой основного соединения действительно превышал время ожидания.

Обратите внимание, что на момент написания несколько параметров были изменены (например, мой последний запуск дал мне ControlPath=/home/toadjaune/.ansible/cp/871b533295), но общая идея остается в силе.

Сбор фактов на самом деле занимает слишком много времени

В начале каждой игры ansible собирает много информации о целевой системе и помещает ее в Факты. Это переменные, которые вы затем можете использовать в своей книге воспроизведения, и обычно они действительно удобны, но иногда получение этой информации может быть очень долгим (плохие точки монтирования, диски с высокой скоростью ввода-вывода, высокая нагрузка ...)

При этом вы не строго нужны факты для запуска сценария, и почти наверняка не все из них, поэтому давайте попробуем отключить то, что нам не нужно. Для этого есть несколько вариантов:

В целях отладки действительно удобно вызывать модуль настройки прямо из командной строки:

ansible -m setup <hostname>

Эта последняя команда должна зависнуть так же, как и ваша playbook, и в конечном итоге тайм-аут (или успех). Теперь давайте снова запустим модуль, отключив все, что можно:

ansible -m setup -a gather_subset='!all' <hostname>

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

Если, однако, он работает нормально (и быстро), взгляните на документация модуля. У вас есть два варианта:

  • Ограничьте сбор фактов подмножеством, исключив то, что вам не нужно (см. Возможные значения для gather_subset)
  • gather_timeout также может помочь вам решить вашу проблему, предоставив больше времени (хотя это было бы для исправления ошибки тайм-аута, а не зависания)

Другие вопросы

Очевидно, что и другие вещи могут пойти не так. Несколько советов по отладке:

  • Использовать максимальный уровень детализации недоступного (-vvvv), так как он покажет вам каждую выполненную команду
  • Использовать ping и setup модули прямо из командной строки, как описано выше
  • Попробуйте использовать ssh вручную, если ansible -m ping не работает

У меня была аналогичная проблема с зависанием Ansible при сборе фактов. Я сократил свой сценарий до подсказки без задач или ролей, и он все еще завис.

В моем списке процессов, накопившихся за день, я обнаружил 12 зависших доступных процессов.

/usr/bin/python /tmp/ansible_Jfv4PA/ansible_module_setup.py
/usr/bin/python /tmp/ansible_M2T10L/ansible_module_setup.py

Как только я их убил, он снова заработал.

Дмитрий что-то понимает!

Ansible использует полное доменное имя хоста. Если ваш хост не разрешает DNS и у вас нет сопоставления в /etc/hosts ansible будет ждать тайм-аута DNS.

Добавляя ::1 <fqdn> в файле хоста компьютеров, которые вы подключаете, Ansible сразу получит полное доменное имя, не проходя через DNS.

Обратите внимание, что хост должен искать хосты из /etc/hosts, это значение по умолчанию для большинства, если не для всех, систем Linux, но если вы редактируете /etc/nsswitch.conf также это может быть проблемой.

Я была такая же проблема. Не получил никакой полезной информации при запуске ansible в подробном режиме.

Перед запуском playbook сервер был повторно подготовлен.

Удаление сервера из списка известных хостов исправило это с помощью следующей команды.

$ ssh-keygen -f "~/.ssh/known_hosts" -R <hostname>
$ ssh-keygen -f "~/.ssh/known_hosts" -R <ip_address>

Примечание: вам необходимо удалить и имя хоста, и IP-адрес.

Я не знаю, используете ли вы sudo playbook, но я был, и он зависал от пароля sudo.

Из документации - вы можете убить это, а затем использовать -K также.

Удачи.

Возможно, отпечаток вашей целевой системы изменился, например, при переустановке серверной ОС. Вы должны удалить записи в known_hosts, анзибль будет не уведомить, что проблема заключается в ненадежной записи, она просто застревает именно так, как вы описываете.

Похоже, что ansible не может аутентифицироваться ... поэтому используйте -k, чтобы позволить ansible запрашивать пароль сервера ... как показано ниже:

ansible-playbook  -K -i hosts playbook.yml -vvvv

В моем случае ансибл перестал работать посреди задачи. Причина в том, что мой ssh-агент перестал работать (ssh-add -l ничего не возвращал). Я перезапустил все, и снова заработало. Поэтому проверьте, правильно ли работает ваш ssh-агент (ssh-add -l не должно застревать).

Несоответствие полного доменного имени и имени хоста также может вызвать недоступную видеовстречу. Я использовал полное доменное имя, если домен отличается от домена имени хоста. После делая оба равнымиАнзибль работает отлично. Возможно, перед выполнением задач на удаленном хосте сравнивается полное доменное имя и имя хоста. Надеюсь, поможет!

Я решил эту проблему, сбросив бродячий ящик

vagrant destroy
vagrant up

Удаление ~/.ansible одна не сделала этого для меня. Итак, чтобы проверить, что находится в этом каталоге, я просто сделал ctrl-z (поместил процесс в спящий режим) и проверил, а затем продолжил доступный процесс через fg. В этом случае я ничего не удалял. но после этого просто продолжалось. Итак, я просто попробовал ctrl-z->fg в одиночку, и это тоже сработало. Похоже на танец дождя, но если кто-то застрял, попробуйте и это.

Я устранил причину этой проблемы, следуя советам от Почему мой ансибл-playbook зависает в разделе «Сбор фактов»? Сообщение блога.

Его можно упростить до:

  1. Устанавливать DEFAULT_KEEP_REMOTE_FILES=yes чтобы сохранить команды и включить -vvvv

  2. Снова запустите playbook.

  3. Когда воспроизведение останавливается, скопируйте последнюю напечатанную команду оболочки (часть после /bin/sh -c)

  4. Войдите на сервер через ssh.

  5. Использовать strace чтобы воспроизвести последний шаг пьесы. Пошаговая команда копируется из -vvv вывод. Например: strace -f /bin/sh -c "echo BECOME-SUCCESS-ltxvshvezrnmumzdprccoiekhjheuwxt; /usr/bin/python /home/user/.ansible/tmp/ansible-tmp-1527099315.31-224479822965785/setup.py"

  6. Проверить на каком вызове застрял "straced" шаг и исправить :)

В моем случае это был недоступный сетевой диск ...

Пароль Судо - проблема. Убедитесь, что (1) вы можете выполнить команду sudo что-нибудь'на недавно открытом терминале (где пароль не кэширован) без предоставления одной (2) марионетки, которая не отменила ваши предыдущие ручные изменения sudoers.