如何检测 Ansible playbook 在执行期间挂起的原因
Posted
技术标签:
【中文标题】如何检测 Ansible playbook 在执行期间挂起的原因【英文标题】:How to detect why Ansible playbook hangs during execution 【发布时间】:2014-01-14 22:22:35 【问题描述】:我写的一些任务开始并且永不结束。 Ansible 不提供任何可以解释这一点的错误或日志,即使使用 -vvvv 选项也是如此。剧本只是挂起,经过几个小时不会改变任何事情。
当我尝试手动运行我的任务(通过 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 的任务正确执行。
【问题讨论】:
你正在传递 -K 选项? 是的。但是我的问题在这里解决了groups.google.com/forum/#!topic/Ansible-project/mm99yAPVrfc 好酷。仅供参考,您应该将解决方案添加为答案并自己接受..这将有助于其他人查看此问题。 【参考方案1】:问题的最可能原因是 SSH 连接。当一个任务需要很长的执行时间时 SSH 超时。我曾经遇到过这样的问题,为了克服 SSH 超时问题,在运行 Ansible 的当前目录中创建一个 ansible.cfg 添加以下内容:
[ssh_connection]
ssh_args = -o ServerAliveInterval=n
n
是我们在通过 SSH 连接到服务器时使用的 ServerAliveInterval(秒)。将其设置在 1-255 之间。这将导致 ssh 客户端每隔n
秒向服务器发送一次空包,以避免连接超时。
【讨论】:
以下解决了我的问题:[ssh_connection]\n ssh_args = -o ServerAliveInterval=30 -o ControlMaster=auto -o ControlPersist=60s 一个小笔记。 ServerAliveInterval=100 本身会减慢执行 ansible 任务的速度。您必须将其与 ControlMaster=auto -o ControlPersist=10m 结合使用【参考方案2】:我在使用剧本时遇到了同样的问题。
它运行完美,直到某个点然后停止,所以我添加了 async 和 poll 参数以避免这种行为
- name: update packages full into each server
apt: upgrade=full
ignore_errors: True
async: 60
poll: 60
它就像一个魅力!我真的不知道发生了什么,但现在 Ansible 似乎记住了正在发生的事情并且不再冻结!
希望对你有帮助
【讨论】:
发生的事情是,ansible 不会等待命令(并在 ssh 连接上超时),而是会检查命令 - 在这种情况下每 60 秒到最多 60 秒(换句话说,一次)。这回避了 ssh 超时的问题。【参考方案3】:我遇到了同样的问题,经过一番摆弄后,我发现问题出在收集事实的步骤中。这里有一些提示可以更好地解决任何类似问题。
在你的剧本中禁用事实收集:
---
- hosts: myservers
gather_facts: no
..
重新运行剧本。如果它有效,则意味着罪魁祸首不在 SSH 本身,而是在收集事实的脚本中。我们可以很容易地调试这个问题。
-
SSH 到远程盒子
在
.ansible
文件夹中的某处找到 setup
文件。
使用./setup
或python -B setup
运行它
如果它挂起,那么我们肯定知道问题就在这里。要准确找到导致它挂起的原因,您可以简单地使用编辑器打开文件并主要在Facts
的populate()
方法中添加print
语句。重新运行脚本,看看它运行了多长时间。
对我来说,这个问题似乎是在尝试解决self.facts['fqdn'] = socket.getfqdn()
行的主机名,然后通过谷歌搜索发现是resolving the remote hostname 的问题。
【讨论】:
如果我的 .ansible 目录没有安装文件,只有一个 ./tmp 目录,它也是空的怎么办?【参考方案4】:对我来说完全不同的解决方法。我从 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
中。如果是后者,您可能希望在开始更改之前将其复制到本地目录!
【讨论】:
【参考方案5】:就我而言,ansible 是“永远挂起”,因为 apt-get 试图问我一个问题!我是怎么想出来的?我转到目标服务器并运行ps -aef | grep apt
,然后在适当的“卡住”apt-get
命令上执行kill
。
在我这样做之后,我的 ansible playbook 立即恢复了活力并报告了(提供了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
【讨论】:
【参考方案6】:删除我的 SSH 密钥的密码为我修复了它,例如:
ssh-keygen -p
【讨论】:
4 月 1 日答复?打得好,先生。【参考方案7】:我正在使用 ansible 在 Ubuntu 20.4 虚拟机上安装 OpenDayLight SDN 控制器集群。收集事实是报告一个python版本警告和挂起。在我的 3 个 VM 工作节点上安装 python 3.8 解决了这个问题
【讨论】:
以上是关于如何检测 Ansible playbook 在执行期间挂起的原因的主要内容,如果未能解决你的问题,请参考以下文章
ansible--playbook用法与自己的yml范例总结