9

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 秒しかかからないのは何が問題なのですか?

4

3 に答える 3

5

調査の結果、ansible が ~/.ssh/known_hosts のインベントリーでホストを探していることがわかりました。私の構成では、HashKnownHosts が有効になっています。ansible は、ハッシュの既知のホスト エントリ形式を理解していないため、探しているホスト エントリを見つけることができません。

ansible の ssh トランスポートが既知のホスト エントリを見つけられない場合は常に、モジュールの実行中にグローバル ロックを取得します。この合流の結果、すべての実行が効果的にシリアル化されます。

一時的な回避策は、一部のセキュリティを放棄し、ホスト キーのチェックを無効にすることhost_key_checking = Falseです~/.ansible.cfg。もう 1 つの回避策は、paramiko トランスポートを使用することです (ただし、これは信じられないほど遅く、何らかの理由で ssh トランスポートよりもおそらく数十倍または数百倍も遅くなります)。もう 1 つの回避策は、ハッシュされていないエントリを known_hosts ファイルに追加して、ansible の ssh トランスポートが検出できるようにすることです。

于 2013-07-31T19:47:43.667 に答える
3

HashKnownHosts が有効になっているため、最新バージョンの Ansible にアップグレードする必要があります。バージョン 1.3 では hashed のサポートが追加されました。バグ トラッカー変更ログknown_hostsを参照してください。これにより、セキュリティを犠牲にしたり (を使用した回避策)、速度を犠牲にしたり (paramiko を使用した回避策)することなく、問題を解決できます。host_key_checking=False

于 2013-09-15T06:10:04.810 に答える