web-dev-qa-db-ja.com

複数のマシンで多くのSSHリモートコマンドをバッチで実行するにはどうすればよいですか?

SSHを使用して、forループ内の複数のリモートマシンでいくつかのコマンドを実行します。 IPアドレスのリストに対して同じコマンドを実行します。一部のIPアドレスは到達できない可能性があるため、ConnectTimeoutオプションを使用しました。

しかし、私のスクリプトは思い通りに機能しませんでした。実際には、リストの次のIPアドレスをあきらめて試行するのではなく、最初の到達不能IPでスタックしました。

これが私のスクリプトの関連部分です:

for ip in ${IP} ; do
    ssh  -o BatchMode=yes \
         -o StrictHostKeyChecking=no \
         -o ConnectTimeout=10 \
         -l ${USERNAME} \
         ${SCRIPT_Host} \
         "${COMMAND} -i $ip || echo timeout" \
         >> ./myscript.out
done

到達可能なIPでは問題なく機能しますが、特定のIPがダウンしている場合はしばらく待機し(10秒を超える、おそらく35〜40秒)、端末にエラーメッセージを表示します。

ERROR connecting : Connection timed out

だから私は私が正しく使用しなかったオプションを疑問に思っています。

13
JavaRed

ConnectTimeoutの使用は正しいので、30秒以上後にタイムアウトする理由は明らかではありません。

タイムアウトの問題を完全に回避するためにスクリプトを変更する方法は次のとおりです。

  • GNU parallelを使用して、同時に複数の宛先ホストに接続します。
  • SSHで-fオプションを使用して、バックグラウンドで処理します。

GNU parallelを使用したソリューションで、最大50の接続を同時に実行します。

parallel --gnu --bg --jobs 50 \
ssh -o BatchMode=yes \
    -o StrictHostKeyChecking=no \
    -o ConnectTimeout=10 \
    -l ${USERNAME} \
    {} \
    "${COMMAND} -i {} || echo timeout" \
::: ${IP}

parallel <command> ::: <arguments>は、<command> <argument>リストを分割することにより、<arguments>を並列で何度も実行します。 <argument>のプレースホルダーは{}です。

parallel --jobs nを使用して、並列接続の数を制限します。

15
Sigi

接続タイムアウトは、すでに接続を確立していて、接続がその秒数の間アイドル状態のままである場合、切断されます(つまり、接続の確立を妨げるKEEP_ALIVE sshパラメータもアクティブにしていない場合)アイドル)。

タイムアウトが発生するまでに30秒以上かかる理由は、TCPプロトコル内部タイマーがその時間接続しようとし、接続できないというエラーメッセージを返すためです。 sftpサーバーです。sshからではありません。

1
tsezane