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无关.
这里有什么不对,无论我的库存中的主机数量是多少,都会阻止默认传输只需大约十秒钟?
一些调查显示,ansible正在〜/ .ssh/known_hosts中查找我的库存中的主机.我的配置启用了HashKnownHosts.ansible永远无法找到它正在寻找的主机条目,因为它不了解哈希已知主机条目格式.
每当ansible的ssh传输无法找到已知的hosts条目时,它就会在模块执行期间获取全局锁.这种融合的结果是所有执行都是有效序列化的.
临时解决办法是通过将放弃一些安全性和禁用的主机密钥检查host_key_checking = False
到~/.ansible.cfg
.另一种解决方法是使用paramiko传输(但由于某些原因,这速度非常慢,可能比ssh传输慢几十或几百倍).另一种解决方法是将一些未散列的条目添加到known_hosts文件中,以便找到ansible的ssh传输.