AWX 所有作业都停止处理并无限期挂起——为啥
Posted
技术标签:
【中文标题】AWX 所有作业都停止处理并无限期挂起——为啥【英文标题】:AWX all jobs stop processing and hang indefinitely -- whyAWX 所有作业都停止处理并无限期挂起——为什么 【发布时间】:2022-01-16 02:05:13 【问题描述】:问题
我们有一个在 v5.0.0 上运行的 Ansible AWX 实例已经运行了一年多,但突然所有作业都停止工作 - 没有呈现输出。它们将开始“运行”,但会无限期挂起,而不会打印出任何日志记录。
AWX 实例在此处定义的 docker compose 容器设置中运行:https://github.com/ansible/awx/blob/5.0.0/INSTALL.md#docker-compose
观察
标准故障排除(例如重新启动容器、主机操作系统等)没有帮助。两种环境都没有配置更改。
在调试实际的 playbook 命令时,我们观察到从 UI 运行 playbook 的命令如下所示:
ssh-agent sh -c ssh-add /tmp/awx_11021_0fmwm5uz/artifacts/11021/ssh_key_data && rm -f /tmp/awx_11021_0fmwm5uz/artifacts/11021/ssh_key_data && ansible-playbook -vvvvv -u ubuntu --become --ask-vault-pass -i /tmp/awx_11021_0fmwm5uz/tmppo7rcdqn -e @/tmp/awx_11021_0fmwm5uz/env/extravars playbook.yml
依次分解为三个命令:
ssh-agent sh -c ssh-add /tmp/awx_11021_0fmwm5uz/artifacts/11021/ssh_key_data
rm -f /tmp/awx_11021_0fmwm5uz/artifacts/11021/ssh_key_data
ansible-playbook -vvvvv -u ubuntu --become --ask-vault-pass -i /tmp/awx_11021_0fmwm5uz/tmppo7rcdqn -e @/tmp/awx_11021_0fmwm5uz/env/extravars playbook.yml
您可以在第 3 部分中看到,-vvvvv
是调试参数——但是,挂起发生在命令 #1 上。这与 ansible 或 AWX 无关,但它不会为我们提供太多调试信息。
我尝试通过strace
来查看发生了什么,但由于下面给出的原因,很难了解它实际挂起的内容。如果可能有帮助,我可以提供此输出。
分析
那么命令 #1 的一个自然问题是 'ssh_key_data' 是什么?
这就是我们在 AWX 中设置的机器凭证(一个 SSH 密钥)——它已经有一段时间没有改变了,在直接 SSH 命令中使用时它工作得很好。它显然也被 AWX 设置为文件管道:
prw------- 1 root root 0 Dec 10 08:29 ssh_key_data
这开始解释为什么它可能会挂起(如果没有从管道的另一端读入)。
从命令行运行一个普通的 ansible-playbook(并以更正常的方式提供 SSH 密钥)工作得很好,所以我们仍然可以部署,但现在只能通过 CLI —— 只是 AWX 坏了。
结论
那么问题就变成了“为什么是现在”?以及“如何调试”?我检查了 awx_postgres 的运行状况,并确认机器凭据确实以预期的格式存在(在 main_credential
表中)。我还验证了可以在 awx_task 容器上使用 ssh-agent 而无需使用该管道密钥文件。因此,问题似乎确实是这个管道文件 - 但我无法从任何日志中收集管道另一端(发送者)应该是什么,或者他们为什么不发送数据.
【问题讨论】:
一些搜索表明管道的另一端由this code 写入,并且使用管道的目的是防止解密的密钥接触磁盘。同样,ssh-agent 用于将密钥保存在内存中。 确实,再往下看,管道写入似乎是在 ansible-runner 中完成的,这里:github.com/ansible/ansible-runner/blob/1.3.4/ansible_runner/… 即使在最新版本的 ansible-runner (v2.1.1) 中,open_fifo_write():
的代码也是相同的
您的工作ID号最近是否超过10000?也许你遇到了这个错误:github.com/ansible/awx/issues/10489
澄清一下,目前只有剧本作业失败。库存同步作业仍在工作。但是最后一个成功的 playbook 作业 ID 是 10987,这太疯狂了(所有 playbook 都以作业 ID 10993 开始失败)。这非常接近报告的幻数,并且阅读 cmets,似乎没有关于触发条件的数字 10000 的具体内容(有些提供的数字相互冲突)。特别是此评论描述了我的问题中的 exact 症状:github.com/ansible/awx/issues/10489#issuecomment-930118691
【参考方案1】:
从本周五开始,在与您相同的时间范围内遇到了同样的问题。原来,Crowdstrike(猎鹰传感器)代理是罪魁祸首。我猜他们推送了一个定义更新,它破坏或阻塞了 fifo 管道。当我们停止 CS 代理时,AWX 再次开始正常工作,没有任何问题。看看您是否正在运行类似的安全产品。
【讨论】:
我们在几乎相同的时间范围内遇到了同样的问题,并且在移除 Crowdstirke 代理后它正在工作。 您的 AWX 是否在 docker 容器中运行? 确认,我们在这台服务器上使用 CS v6.31,但策略在周三晚上更新,并且确实传播了他们基于脚本的执行监控策略,这显然会阻止 fifo 管道导致这些 AWX 作业失败. 此安装未在 docker 容器中运行。这是一个基于 RPM 的安装。【参考方案2】:对于 Crowdstrike 的用户,问题可能与您的组织在周末实施的政策变更有关:
crowdstrike 发布了 6.32 版本,该版本已被许多组织采用以应对周末的 log4j 漏洞,该漏洞引入了脚本级别检查方面的一些更改。
基于脚本的执行监控是造成中断的罪魁祸首。正如其他用户所说,您可以完全禁用众筹并重新启动 AWX 作业以使其正常工作,但出于生产安全考虑,这可能不合适。
相反,您必须联系您的众筹管理员,他们将更新您的实例配置文件的政策以包括基于脚本的执行监控。策略管理 GUI 有一个复选框,可以启用/禁用此功能的使用(6.32 中的新功能)。要求他们禁用它并将日志发送给供应商。
【讨论】:
有趣。感谢您的反馈。在我们的服务器上,AWX 在容器中运行——Crowdsrike 安装在主机操作系统上(而不是在容器中)。但是,部署的版本仍然是 6.31.12803.0 -- 是否可以独立于 CS 版本号部署此策略? 已确认它也会影响 v6.31 - 该策略可以包括基于脚本的执行监控,无论它是否为 6.32。【参考方案3】:已确认 Crowdstrike 政策更新是 Ansible Tower 在我们公司停止工作 48 小时的问题所在。禁用监控选项可以让作业几乎立即成功运行。
【讨论】:
【参考方案4】:即使 AWX 在容器上运行,我也确认相同的情况...
关于现有的解决方案,不适合我的情况:
-
禁用 Crowdstrike 服务... 出于安全原因,不可能
要求禁用“基于脚本的执行监控”在我目前的职位上会很头疼
所以我已经修补了 ansible-runner 以避免让 shell/bash(又名基于脚本)读取文件并让 Python 来完成它
我使用的是旧版本的 AWX 15.0.1,因此相应的 ansible-runner 可能有点旧。但我检查过主方法仍然存在(但在不同的文件上)
我已经搬家了
def wrap_args_with_ssh_agent(self, args, ssh_key_path, ssh_auth_sock=None, silence_ssh_add=False):
"""
Given an existing command line and parameterization this will return the same command line wrapped with the
necessary calls to ``ssh-agent``
"""
if ssh_key_path:
ssh_add_command = args2cmdline('ssh-add', ssh_key_path)
...
到
def wrap_args_with_ssh_agent(self, args, ssh_key_path, ssh_auth_sock=None, silence_ssh_add=False):
"""
Given an existing command line and parameterization this will return the same command line wrapped with the
necessary calls to ``ssh-agent``
"""
if ssh_key_path:
ssh_key_content = ""
with open(ssh_key_path) as f:
ssh_key_content = f.read()
ssh_add_command = 'ssh-add - <<< "' + ssh_key_content + '"'
注意私钥内容将在日志中公开。只是一个 POC,我认为我们可以做得更好(也许重写其他文件的内容?并使用新的克隆)
【讨论】:
【参考方案5】:Crowdstrike 已发布传感器版本 6.32.12905 来解决此问题。在您的环境中配置 Falcon 的任何人都可以创建/修改传感器更新策略以将最新版本推送到受影响的主机。
发行说明: 概括 此修补程序版本解决了基于脚本的执行监控的问题,在该问题中,Linux 传感器可能会挂起包含管道文件的命令行。
固定 解决了基于脚本的执行监控的问题,其中 Linux 传感器可能会挂起包含管道文件的命令行
【讨论】:
以上是关于AWX 所有作业都停止处理并无限期挂起——为啥的主要内容,如果未能解决你的问题,请参考以下文章