9

我想使用 Ansible 在多个远程节点上同时执行一个简单的作业。实际的工作涉及 grepping 一些日志文件,然后在我的本地主机上对结果进行后处理(远程节点上没有可用的软件)。

命令行 ansible 工具似乎不太适合这个用例,因为它们将 ansible 生成的格式与远程执行命令的输出混合在一起。Python API 似乎应该能够做到这一点,因为它公开了未修改的输出(除了一些在此处不相关的潜在 unicode 修改)。

我想出的 Python 程序的简化版本如下所示:

from sys import argv
import ansible.runner
runner = ansible.runner.Runner(
    pattern='*', forks=10,
    module_name="command",
    module_args=(
        """
        sleep 10
        """),
    inventory=ansible.inventory.Inventory(argv[1]),
)
results = runner.run()

在这里,sleep 10代表实际的日志 grepping 命令——这个想法只是模拟一个不会立即完成的命令。

但是,在运行此程序时,我观察到所花费的时间似乎与我的清单中的主机数量成正比。以下是分别针对 2、5 和 9 台主机的清单的计时结果:

exarkun@top:/tmp$ time python howlong.py two-hosts.inventory
real    0m24.285s
user    0m0.216s
sys     0m0.120s
exarkun@top:/tmp$ time python howlong.py five-hosts.inventory                                                                                   
real    0m55.120s
user    0m0.224s
sys     0m0.160s
exarkun@top:/tmp$ time python howlong.py nine-hosts.inventory
real    1m57.272s
user    0m0.360s
sys     0m0.284s
exarkun@top:/tmp$

其他一些随机观察:

  • ansible all --forks=10 -i five-hosts.inventory -m command -a "sleep 10"表现出相同的行为
  • ansible all -c local --forks=10 -i five-hosts.inventory -m command -a "sleep 10"似乎是同时执行的事情(但只适用于本地连接,当然)
  • ansible all -c paramiko --forks=10 -i five-hosts.inventory -m command -a "sleep 10"似乎同时执行的事情

也许这表明问题出在 ssh 传输上,与通过 Python API 而非命令行使用 ansible 无关。

无论我的清单中的主机数量如何,这有什么问题会阻止默认传输仅花费大约 10 秒?

4

3 回答 3

5

一些调查显示,ansible 正在 ~/.ssh/known_hosts 中查找我的清单中的主机。我的配置启用了 HashKnownHosts。ansible 永远无法找到它正在寻找的主机条目,因为它不理解散列已知主机条目格式。

每当 ansible 的 ssh 传输找不到已知主机条目时,它会在模块执行期间获取全局锁。这种融合的结果是所有执行都被有效地序列化了。

一个临时的解决方法是放弃一些安全性和禁用主机密钥检查,host_key_checking = False~/.ansible.cfg. 另一种解决方法是使用 paramiko 传输(但由于某种原因,这非常慢,可能比 ssh 传输慢数十或数百倍)。另一种解决方法是让一些未散列的条目添加到 known_hosts 文件中,以便 ansible 的 ssh 传输找到。

于 2013-07-31T19:47:43.667 回答
3

由于您启用了 HashKnownHosts,您应该升级到最新版本的 Ansible。1.3 版添加了对散列的支持known_hosts,请参阅错误跟踪器更改日志。这应该可以在不影响安全性(使用 的解决方法host_key_checking=False)或牺牲速度(使用 paramiko 的解决方法)的情况下解决您的问题。

于 2013-09-15T06:10:04.810 回答
0

使用 Ansible 2.0 Python API,我关闭了 StrictHostKeyChecking

import ansible.constants

ansible.constants.HOST_KEY_CHECKING = False

通过在托管计算机上设置以下内容,我设法大大加快了 Ansible。我认为,较新的 sshd 具有相反的默认值,因此在您的情况下可能不需要它。

/etc/ssh/sshd_config
----
UseDNS no
于 2016-04-23T12:08:14.450 回答