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 所有作业都停止处理并无限期挂起——为啥的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在无限循环中休眠的 python 脚本停止运行?

无限循环(动作脚本3)

组装无限循环[家庭作业]

NodeJS 在多次请求后无限期挂起

svnadmin hotcopy 无限期挂起

玩笑无限期挂起,不运行任何测试