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

时间:2013-07-30 23:01:44

标签: python concurrency parallel-processing 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()

这里,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无关。

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

3 个答案:

答案 0 :(得分:5)

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

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

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

答案 1 :(得分:3)

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

答案 2 :(得分:0)

使用Ansible 2.0 Python API,我用

关闭了StrictHostKeyChecking
/etc/ssh/sshd_config
----
UseDNS no

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

namespace App\Http\Controllers;

use App\taxonomy;
use Illuminate\Http\Request;

class newPostController extends Controller {

public function submitArticle(Request $request){
    $name = $request->all();
    return $name;
}