如何以编程方式和并发方式驱动Ansible?

Jea*_*one 9 python parallel-processing concurrency ansible

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

命令行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()
Run Code Online (Sandbox Code Playgroud)

在这里,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$
Run Code Online (Sandbox Code Playgroud)

其他一些随机观察:

  • 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无关.

这里有什么不对,无论我的库存中的主机数量是多少,都会阻止默认传输只需大约十秒钟?

Jea*_*one 5

一些调查显示,ansible正在〜/ .ssh/known_hosts中查找我的库存中的主机.我的配置启用了HashKnownHosts.ansible永远无法找到它正在寻找的主机条目,因为它不了解哈希已知主机条目格式.

每当ansible的ssh传输无法找到已知的hosts条目时,它就会在模块执行期间获取全局锁.这种融合的结果是所有执行都是有效序列化的.

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