Ansible坚持收集事实


52

我的ansible盒子(无用)有一些奇怪的问题。

昨天一切正常,我的剧本还不错。

今天,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'"]

1
它挂了多少时间?你尝试vagrant ssh和探讨杭期间,看是否存在什么有用的psnetstat?另外,挂起的第一个可疑对象之一是DNS-检查DNS是否从虚拟机内部解析。
Antonis Christofides

1
感谢您的评论。解决方案很简单,无所不用其极,然后无所作为...我仍然认为它刚刚停止工作很奇怪吗?
Bj Blazkowicz 2014年

1
如果有无法访问的(cifs-)挂载,我会遇到Ansible停顿的问题。
rektide

1
刚发生时,这是由known_hosts文件中的主机密钥过时引起的。很奇怪在这种情况下连接没有像往常一样失败。
GnP

您可以在“ vagrant”框中检查sshd日志吗?您可能需要在/ etc / ssh / sshd_config中设置“ LogLevel DEBUG”,但这可能会提供更多有关正在发生的情况的信息。
巴勃罗·马丁内斯

Answers:


31

我对Vagrant的Ansible ping也遇到了类似的问题,它突然突然无缘无故卡住,并且以前工作得非常好。与ssh或连接性问题之类的其他任何问题不同,它永远不会超时就消失。

解决该问题的一件事是清理~/.ansible目录,它又可以正常工作了。我不知道为什么,但是确实解决了。

如果您再次进行更改,请尝试清理~/.ansible文件夹,然后再刷新Vagrant。


3
rm -rf ~/.ansible我没有工作,在萨尔瓦多Captitan
Quanlong

8
rm -rf〜/ .ansible / cp就足够了
melihovv

20

对我来说,安装模块模块卡在了失效的NFS支架上。

如果在计算机上执行“ df”操作,但没有任何反应,则可能是同一情况。

PS:如果无法卸载NFS共享/挂载点,请考虑使用错误的“ umount -l”


是的,就是这样!
Saurabh Nanda

我最初通过设置gather_facts为来解决此问题,False但该技巧确实节省了一天,因为那也是我的问题。
pkaramol

18

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问题“是”,就可以继续播放。之后,您可以解决根已知的主机问题。

私钥认证问题

如果使用基于密钥的身份验证而不是密码,则其他问题包括:

  • 目的地上的私钥可能未正确设置
  • 私钥可能在本地具有不正确的权限(仅应由运行Ansible作业的用户才能读取)

解决方案:尝试ansible -m ping <destination> -k针对有问题的主机运行-如果这不起作用,请尝试上述“ 主机关键问题”解决方案。

Ansible无法快速收集事实

setup模块(在运行开始时自动ansible-playbook运行时,或以方式手动运行时ansible -m setup <host>)在收集硬件事实时(例如,如果从具有高I / O,错误装入条目的主机获取磁盘信息)经常会挂起。

解决方案:尝试运行ansible -m setup -a gather_subset=!all <destination>。如果可行,则应考虑在ansible.cfg中设置以下行:

gather_subset=!hardware

1
传递给'gather_subset =!hardware'进行设置可用于未响应的特定VM。
JamesP

2
为我固定。我认为是狡猾的坐骑点。我有一个用于ansible置备的VM,在添加新的NFS共享之前,该VM一直有效。现在不行,直到我添加了上面的内容。
大卫·波什顿

在我看来,这是一个主机密钥问题。主机已重新成像,因此我的第一次运行失败,我运行了建议的ssh-keygen -R命令来删除有问题的密钥。我运行ssh一次以添加密钥,但第二次运行已挂起。当我再次运行ssh时,得到了密钥确认提示,这是意外的。我意识到有一个有问题的密钥需要删除,因此在删除该密钥并重新运行ssh之后,我收到了Warning: Permanently added the ECDSA host key ...消息,然后仅继续进行事实收集。
haridsv

我可以从@DavidBoshton确认观察。在装有NFS目录的VM上出现此问题,该目录不可用(NFS服务器问题)。修复NFS服务器后,它开始工作
tschale

7

我在Ansible Facting Facts上遇到了类似的问题。我将脚本缩减为没有任务或角色的提示符,但该脚本仍然挂起。

我发现在一天中累积了12个挂起的ansible进程。

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

一旦我杀死了它们,它就会重新开始工作。


5

Ansible可能会挂在事实收集上的原因有很多,但是在进一步进行之前,这是您在任何这种情况下都应该进行的第一个测试:

ansible -m ping <hostname>

该测试仅连接到主机,并执行足够的代码以返回:

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

如果这行得通,您几乎可以排除任何设置或连接问题,因为它证明您可以解析目标主机名,打开连接,进行身份验证并使用远程python解释器执行ansible模块。

现在,这是(非详尽的)清单,可能会在剧本开始时出现问题:

Ansible执行的命令正在等待交互式输入

我可以记得在旧版本的ansible上发生的情况,在该版本中,命令将等待永远不会出现的交互式输入,例如sudo密码(当您忘记-K切换时),或者接受新的ssh主机指纹(对于新目标)主办)。

现代版本的ansible可以优雅地处理这两种情况,并在正常情况下立即引发错误,因此,除非您自己进行诸如调用ssh或sudo之类的操作,否则您就不会遇到此类问题。即使您这样做了,也要在事实收集之后。

无效的SSH主连接

在此处给出的调试日志中,有一些非常有趣的选项传递给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客户端仍认为已建立连接。当您从笔记本电脑执行剧本,并且失去WiFi连接(或从WiFi切换到以太网等)时,通常会发生这种情况

最后一个示例是一个糟糕的情况:您可以使用默认的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>

这对于一次修复是完美的,但是如果它经常发生,则可能需要寻找长期修复。以下是一些可能有助于实现这一目标的指标:

  • 从服务器启动剧本(网络连接方式比笔记本电脑稳定)
  • 使用ansible配置或直接ssh客户端配置禁用连接共享
  • 使用相同的资源,但微调超时,以便主连接崩溃实际上更快地超时

请注意,在撰写本文时,一些选项已更改(例如,我最近的运行给了我ControlPath=/home/toadjaune/.ansible/cp/871b533295),但总体思路仍然有效。

事实收集实际上花费了太多时间

在每次播放的开头,ansible都会收集有关目标系统的大量信息,并将其放入Facts中。这些是您可以在剧本中使用的变量,通常非常方便,但是有时获取此信息可能会很长(坏的装载点,具有高I / O的磁盘,高负载…)

这是说,你不严格需要事实来运行一个剧本,而且几乎可以肯定他们不是全部,所以让我们尝试和禁止什么,我们不需要。有几种选择:

出于调试目的,直接从命令行调用setup模块确实非常方便:

ansible -m setup <hostname>

最后一个命令应与您的剧本一起挂起,并最终超时(或成功)。现在,让我们再次执行模块,禁用所有我们可以做到的:

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

如果仍然无法解决问题,您可以随时尝试完全禁用游戏中的模块,但实际上您的问题可能出在其他地方。

但是,如果可以正常运行(并且很快),请查看模块文档。您有两种选择:

  • 将事实收集限制为一个子集,不包括不需要的部分(请参阅的可能值gather_subset
  • gather_timeout 还可以通过允许更多时间来帮助您解决问题(尽管这将解决超时错误,而不是挂起)

其他事宜

显然,其他事情可能出错。一些帮助调试的指针:

  • 使用ansible最大详细程度(-vvvv),因为它将向您显示执行的每个命令
  • 如上所述,直接从命令行使用pingsetup模块
  • 如果ansible -m ping不起作用,请尝试手动ssh

4

Dmytro即将开始!

Ansible使用主机的FQDN。如果您的主机不是DNS可解析的,并且您没有/etc/hostsansible 的映射,则会等待DNS超时。

通过添加::1 <fqdn>要连接的计算机的主机文件,Ansible将立即获得FQDN,而无需通过DNS。

请注意,主机应该从中查找主机/etc/hosts,这是大多数(如果不是全部)Linux系统的默认值,但是如果您进行的编辑/etc/nsswitch.conf也可能是一个问题。


2

我遇到过同样的问题。在详细模式下运行ansible并没有得到任何有用的信息。

运行剧本之前,服务器已重新配置。

使用以下命令从已知主机列表中删除服务器即可解决此问题。

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

注意:您需要同时删除主机名和IP地址


就我而言,我重用了一个IP地址。因此,known_hosts文件中存在两个主机密钥
Karthik,

1

我不知道您是否正在使用sudo剧本-但我曾经使用过,并且它挂在sudo密码上。

从文档中-您可以杀死它,然后再使用-K

祝好运。


1

例如,当您重新安装服务器操作系统时,目标系统的指纹可能已更改。您必须删除known_hosts中的条目,ansible 不会通知问题是不可信的条目,它只是完全按照您的描述卡住了。


1

听起来ansible无法认证...所以使用-k让ansible要求输入服务器密码....如下所示:

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

0

FQDN和主机名不匹配也会导致视频群聊。我使用的FQDN的域名不同于主机名域名。在使两者相等之后,ansible完美运行。在远程主机上执行任务之前,可能会比较FQDN和主机名。希望能帮助到你!


0

我通过重置游民箱来解决此问题

vagrant destroy
vagrant up

0

就我而言,ansible在任务中间停止工作。原因是因为我的ssh-agent停止工作(ssh-add -l未返回任何东西)。我重新启动了一切,然后又重新开始了。因此,请检查您的ssh-agent是否正常工作(ssh-add -l不应卡住)。


0

~/.ansible独自删除并不能帮我。因此,要检查该目录中的内容,我只是做了一个ctrl-z(使进程进入睡眠状态)并进行了检查,然后通过继续了ansible进程fg。在这种情况下,我没有删除任何内容。但是之后就继续了。所以我只尝试了ctrl-z-> fg,它也起作用了。感觉像跳雨舞,但如果有人被卡住,也请尝试一下。


0

我已按照“ 为什么我的ansible-playbook挂在“收集事实”中的建议”中的建议解决了此问题的原因博客文章。

可以简化为:

  1. 设置DEFAULT_KEEP_REMOTE_FILES=yes为保留命令并启用-vvvv

  2. 再次运行剧本。

  3. 当播放卡住时,复制最后打印的shell命令(后面的部分/bin/sh -c

  4. 通过登录服务器ssh

  5. 使用strace重播该剧的最后一步。从-vvv输出中复制了step命令。例如:strace -f /bin/sh -c "echo BECOME-SUCCESS-ltxvshvezrnmumzdprccoiekhjheuwxt; /usr/bin/python /home/user/.ansible/tmp/ansible-tmp-1527099315.31-224479822965785/setup.py"

  6. 检查哪个呼叫“停留”步骤卡住并修复它:)

就我而言,这是无法访问的网络驱动器...


-1

须藤的密码就是问题所在。确保(1)您可以在新打开的终端上发出“ sudo any ”(未缓存密码),而无需提供(2)up没有撤消您先前的手动“ sudoers”更改。


1
木偶?什么p 这是一个难题。
鹿猎人

是的我知道。有人可能在使用
ansible
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.