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>
这对于一次修复是完美的,但是如果它经常发生,则可能需要寻找长期修复。以下是一些可能有助于实现这一目标的指标:
请注意,在撰写本文时,一些选项已更改(例如,我最近的运行给了我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
),因为它将向您显示执行的每个命令
- 如上所述,直接从命令行使用
ping
和setup
模块
- 如果
ansible -m ping
不起作用,请尝试手动ssh
vagrant ssh
和探讨杭期间,看是否存在什么有用的ps
和netstat
?另外,挂起的第一个可疑对象之一是DNS-检查DNS是否从虚拟机内部解析。