ansibleが実際の収集でハングする理由はたくさんありますが、先に進む前に、そのような状況で最初に行うべきテストを以下に示します。
ansible -m ping <hostname>
このテストはホストに接続し、十分なコードを実行して戻ります。
<hostname> | SUCCESS => {
"changed": false,
"ping": "pong"
}
これが機能する場合、ターゲットのホスト名を解決し、接続を開き、認証し、リモートPythonインタープリターでansibleモジュールを実行できることを証明するため、セットアップまたは接続の問題をほとんど除外できます。
さて、ここに、プレイブックの冒頭で間違ってしまう可能性のある(網羅的でない)リストがあります:
ansibleによって実行されたコマンドは、インタラクティブな入力を待っています
これは、コマンドがsudoパスワード(-K
スイッチを忘れたとき)、または新しいsshホストフィンガープリントの受け入れ(新しいターゲット用)など、決して来ないインタラクティブな入力を待つ古いansibleバージョンで起こったことを覚えていますホスト)。
ansibleの最新バージョンは、これらの両方のケースを適切に処理し、通常のユースケースではすぐにエラーを発生させるため、sshやsudoを自分で呼び出すなどのことをしているのでなければ、この種の問題は発生しません。そして、たとえあなたがやったとしても、それは事実の収集の後でしょう。
デッドSSHマスター接続
ここに示されているデバッグログには、sshクライアントに渡されるいくつかの非常に興味深いオプションがあります:
ControlMaster=auto
ControlPersist=60s
ControlPath=/home/vagrant/.ansible/cp/ansible-ssh-%h-%p-%r
これらのオプションはman ssh_configに記載されています。
デフォルトでは、ansibleはssh接続の使用に関して賢くしようとします。特定のホストでは、プレイのタスクごとに新しい接続を作成する代わりに、一度だけ開き、プレイブック全体(さらにはプレイブック全体)で開いたままにします。
新しい接続の確立は、既存の接続を使用するよりもはるかに遅く、計算集約型なので、それは良いことです。
実際には、すべてのssh接続はでソケットの存在を確認します~/.ansible/cp/some-host-specific-path
。最初の接続はそれを見つけることができないため、正常に接続してから作成します。その後のすべての接続は、このソケットを使用して、すでに確立された接続を通過します。
確立された接続が最終的にタイムアウトし、十分に長い間使用されなかった後に閉じられたとしても、ソケットも閉じられ、正方形に戻ります。
ここまでは順調ですね。
ただし、接続が実際に停止する場合もありますが、sshクライアントはまだ接続が確立されていると見なします。これは通常、ノートブックからプレイブックを実行し、WiFi接続を失った(またはWiFiからイーサネットに切り替えるなど)ときに発生します。
この最後の例は恐ろしい状況です:デフォルトのssh構成でターゲットマシンにssh できますが、以前の接続がまだアクティブであるとみなされる限り、ansibleは新しい接続を確立しようとさえしません。
この時点で、この古いソケットを取り除きたいだけで、それを行う最も簡単な方法はそれを削除することです:
# Delete all the current sockets (may disrupt currently running playbooks)
rm -r ~/.ansible/cp
# Delete only the affected socket (requires to know which one it is)
rm ~/.ansible/cp/<replace-by-your-socket>
これは、1回限りの修正には最適ですが、あまりにも頻繁に発生する場合は、長期的な修正を探す必要があります。この目標に向けて役立つ可能性のあるポインタを次に示します。
- サーバーからプレイブックを起動します(ラップトップよりも安定したネットワーク接続方法で)
- ansible構成を使用するか、直接sshクライアント構成を使用して接続共有を無効にします
- 同じリソースを使用しますが、タイムアウトを微調整して、マスター接続のクラッシュが実際より速くタイムアウトするようにします
この記事を書いている時点では、いくつかのオプションが変更されています(たとえば、最新の実行で提供されたなどControlPath=/home/toadjaune/.ansible/cp/871b533295
)が、一般的な考え方はまだ有効です。
事実収集に時間がかかりすぎている
すべてのプレイの開始時に、ansibleはターゲットシステムに関する多くの情報を収集し、それをFactsに入れます。これらはプレイブックで使用できる変数であり、通常は非常に便利ですが、時々、この情報を取得するのに非常に時間がかかる場合があります(悪いマウントポイント、高I / Oのディスク、高負荷...)
そうは言っても、プレイブックを実行するためにファクトは厳密に必要ではなく、ほとんどすべてのファクトはそうではないので、必要のないものを無効にしてみましょう。そのためのいくつかのオプション:
デバッグのために、コマンドラインから直接セットアップモジュールを呼び出すのが非常に便利です。
ansible -m setup <hostname>
この最後のコマンドは、プレイブックと同様にハングし、最終的にタイムアウト(または成功)するはずです。それでは、モジュールを再度実行して、可能なすべてを無効にします。
ansible -m setup -a gather_subset='!all' <hostname>
それでも問題が解決しない場合は、いつでもプレイでモジュールを完全に無効にすることができますが、問題はどこか別の場所にある可能性が高いです。
ただし、正常に(かつ迅速に)動作する場合は、モジュールのドキュメントを参照してください。次の2つのオプションがあります。
- ファクト収集をサブセットに制限し、不要なものを除外します(可能な値を参照
gather_subset
)
gather_timeout
より多くの時間を許可することで、問題を解決するのに役立ちます(ただし、ハングアップではなくタイムアウトエラーを修正します)
その他の問題
明らかに、他のことがうまくいかない可能性があります。デバッグに役立ついくつかのポインタ:
-vvvv
実行可能なすべてのコマンドが表示されるため、無制限の最大冗長レベル()を使用します
- 上記で説明されているように、コマンドラインからモジュール
ping
とsetup
モジュールを直接使用します
ansible -m ping
動作しない場合は手動でsshを試してください
vagrant ssh
際に有用何があるかどうかを確認するためにハング中および調査ps
とはnetstat
?また、ハングの最初の疑いの1つはDNSです-DNSが仮想マシンの内部から解決しているかどうかを確認します。