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

时间:2013-12-27 10:12:05

标签: ubuntu deployment ansible ansible-playbook provisioning

我写的一些任务开始并且永不结束。 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正确执行的任务。

6 个答案:

答案 0 :(得分:8)

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

它完美运行直到某个点然后停止,所以我添加了异步民意调查参数以避免此行为

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

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

希望有所帮助

答案 1 :(得分:8)

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

[ssh_connection]

ssh_args = -o ServerAliveInterval=n

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

答案 2 :(得分:8)

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

在剧本中禁用事实收集:

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

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

  1. SSH到远程框
  2. setup文件夹中找到.ansible文件。
  3. 使用./setuppython -B setup
  4. 运行它

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

    对我来说,问题似乎是尝试解决第self.facts['fqdn'] = socket.getfqdn()行的主机名,并通过谷歌搜索结果证明resolving the remote hostname存在问题。

答案 3 :(得分:3)

对我来说完全不同的解决方法。我从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“共享”连接。我转到ansible.cfg并找到ssh_args行并设置ControlMaster=no。这可能现在执行缓慢,因为我已经失去了应该给出的SSH性能提升,但似乎这与apt-get之间存在一些导致问题的交互。

您的ansible.cfg可能位于您ansible/etc/ansible中的09-06 23:49:32.807 15229-15229/? E/AndroidRuntime: FATAL EXCEPTION: main Process: <my_package>, PID: 15229 java.lang.IllegalStateException: Conflicting property name definitions: 'locale' (for [field com.nestlabs.sdk.Device#b]) vs 'name' (for [method com.nestlabs.sdk.Device#b(0 params)]) at com.fasterxml.jackson.databind.introspect.POJOPropertyBuilder.findRenamed(Unknown Source) at com.fasterxml.jackson.databind.introspect.POJOPropertyBuilder.findNewName(Unknown Source) at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._renameProperties(Unknown Source) at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.collect(Unknown Source) at com.fasterxml.jackson.databind.introspect.BasicClassIntrospector.collectProperties(Unknown Source) at com.fasterxml.jackson.databind.introspect.BasicClassIntrospector.forDeserialization(Unknown Source) at com.fasterxml.jackson.databind.introspect.BasicClassIntrospector.forDeserialization(Unknown Source) at com.fasterxml.jackson.databind.DeserializationConfig.introspect(Unknown Source) at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(Unknown Source) at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(Unknown Source) at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(Unknown Source) at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(Unknown Source) at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(Unknown Source) at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(Unknown Source) at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(Unknown Source) at com.fasterxml.jackson.databind.ObjectMapper.readValue(Unknown Source) at com.firebase.client.d.a(Unknown Source) at com.nestlabs.sdk.aa.a(Unknown Source) at com.firebase.client.c.ba.run(Unknown Source) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 目录中。如果是后者,您可能希望在开始更改之前将其复制到本地目录中!

答案 4 :(得分:1)

删除我的SSH密码的密码为我修复了它,例如:

ssh-keygen -p

答案 5 :(得分:0)

在我的情况下,ansible是“永远挂着”,因为apt-get试图问我一个问题!我是怎么知道的?我去到目标服务器并运行ps -aef | grep apt,然后对适当的“卡住” kill命令执行了apt-get

这样做之后,我的那本可玩的剧本立即恢复了活力并开始报道(提供了ansible-playbook -vvv选项):

    " ==> Deleted (by you or by a script) since installation.",
    " ==> Package distributor has shipped an updated version.",
    "   What would you like to do about it ?  Your options are:",
    "    Y or I  : install the package maintainer's version",
    "    N or O  : keep your currently-installed version",
    "      D     : show the differences between the versions",
    "      Z     : start a shell to examine the situation",
    " The default action is to keep your current version.",
    "*** buildinfo.txt (Y/I/N/O/D/Z) [default=N] ? "

阅读了有用的诊断输出后,我立即意识到我需要一些适当的dpkg选项(例如,参见this devops post)。就我而言,我选择了:

apt:
  name: '{{ item }}'
  state: latest
  update_cache: yes
  # Force apt to always update to the newer config files in the package:
  dpkg_options: 'force-overwrite,force-confnew'
loop: '{{ my_packages }}'

此外,别忘了在您死掉的ansible会话后使用类似方法进行清理,否则您的安装仍可能会失败:

sudo dpkg --configure -a