Ansible を使用して、複数のリモート ノードで単純なジョブを同時に実行したいと考えています。実際の作業では、いくつかのログ ファイルを grep し、ローカル ホスト (リモート ノードでは使用できないソフトウェアを使用) で結果を後処理します。
コマンド ラインの 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
は、実際のログ grep コマンドを代用しています。アイデアは、すぐには完了しないコマンドをシミュレートすることです。
ただし、これを実行すると、かかる時間がインベントリ内のホストの数に比例しているように見えます。それぞれ 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 秒しかかからないのは何が問題なのですか?