当前位置: 首页>>技术问答>>正文


如何检测Ansible playbook在执行期间挂起的原因

问题描述

我写的一些任务开始并且永远不会结束。 Ansible不提供任何可以解释这一点的错误或日志,即使使用-vvvv选项也是如此。 Playbook只是挂起,过了几个小时不会改变任何东西。

当我尝试手动运行我的任务时(通过SSH输入命令)一切都很好。

挂起的示例任务:

- name: apt upgrade
  shell: apt-get upgrade

有没有办法看到stdout和stderr?我试过了:

- name: apt upgrade
  shell: apt-get upgrade
  register: hello
- debug: msg="{{ hello.stdout }}"
- debug: msg="{{ hello.stderr }}"

但没有改变。

我确实有必要的权限,我传递了正确的sudo密码 – 其他需要sudo正确执行的任务。

最佳解决方法

最可能的问题原因是SSH连接。当任务需要较长的执行时间SSH超时时。我曾经遇到过这样的问题,为了克服SSH超时问题,在运行Ansible的当前目录中创建一个ansible.cfg,添加以下内容:

[ssh_connection]

ssh_args = -o ServerAliveInterval=n

其中n是我们在通过SSH连接到服务器时使用的ServerAliveInterval(秒)。设置在1-255之间。这将导致ssh客户端每隔n秒向服务器发送空数据包,以避免连接超时。

次佳解决方法

我有同样的问题,经过一番摆弄后,我发现问题在于收集事实。以下是一些可以更好地解决任何类似问题的提示。

在你的剧本中禁用fact-gathering:

---
- hosts: myservers
  gather_facts: no
..

重新播放剧本。如果它有效,则意味着罪魁祸首不在SSH本身,而是在收集事实的脚本中。我们可以很容易地调试这个问题。

  1. SSH到远程框

  2. .ansible文件夹中的某处找到setup文件。

  3. 使用./setuppython -B setup运行它

如果它挂起,那么我们知道问题就在这里。要准确找到使其挂起的原因,您只需使用编辑器打开文件,并主要在Factspopulate()方法中添加print语句。重新运行脚本,看看它有多长。

对我来说,问题似乎是试图解决self.facts['fqdn'] = socket.getfqdn()行的主机名,并且通过谷歌搜索结果发现它与resolving the remote hostname有关。

第三种解决方法

我在剧本中遇到了同样的问题。

它完美运行直到某个点然后停止,所以我添加了异步和轮询参数以避免这种行为

- name: update packages full into each server
  apt: upgrade=full
  ignore_errors: True
  async: 60
  poll: 60

它就像一个魅力!我真的不知道发生了什么,但现在似乎Ansible记住发生了什么,不要再冻结了!

希望能帮助到你

第四种方法

对我来说完全不同的work-around。我从Debian Jessie(Linux PwC-Deb64 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt25-2+deb8u3 (2016-07-02) x86_64 GNU/Linux)到我试图在AWS中构建的另一个Debian映像。

在这里的许多建议对我不起作用之后,我怀疑SSH “shared”连接。我去了我的ansible.cfg并找到了ssh_args线并设置了ControlMaster=no。这可能现在执行缓慢,因为我已经失去了应该给出的SSH性能提升,但似乎这与apt-get之间存在一些导致问题的交互。

您的ansible.cfg可以位于您运行ansible的目录中,也可以位于/etc/ansible中。如果是后者,您可能希望在开始更改之前将其复制到本地目录中!

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/6533.html,未经允许,请勿转载。