web-dev-qa-db-ja.com

多くのサーバーでSSHを介してコマンドを自動的に実行する

.txtファイルにIPアドレスのリストがあります。例:

1.1.1.1
2.2.2.2
3.3.3.3

すべてのIPアドレスの背後にサーバーがあり、すべてのサーバーのポート22でsshdが実行されています。すべてのサーバーがknown_hostsリスト(私のPCでは、Ubuntu 10.04 LTS/bash)。

これらのサーバーでコマンドを実行して出力を収集するにはどうすればよいですか?

理想的には、すべてのサーバーでコマンドを並行して実行したいと思います。

すべてのサーバーで公開鍵認証を使用します。

ここにいくつかの潜在的な落とし穴があります:

  • Sshは、指定されたサーバーのsshキーをknown_hostsファイル。
  • 与えられたコマンドは、出力が潜在的に無効であることを示す、ゼロ以外の終了コードを返す場合があります。私はそれを認識する必要があります。
  • ネットワークエラーなどが原因で、特定のサーバーへの接続が確立されない場合があります。
  • コマンドが予想よりも長く実行された場合、またはコマンドの実行中にサーバーがダウンした場合は、タイムアウトが必要です。

サーバーはAIX/kshです(しかし、それは本当に重要ではないと思います。

47
LanceBaynes

Psshなどをインストールできないとすると、次のようなことができます。

tmpdir=${TMPDIR:-/tmp}/pssh.$$
mkdir -p $tmpdir
count=0
while IFS= read -r userhost; do
    ssh -n -o BatchMode=yes ${userhost} 'uname -a' > ${tmpdir}/${userhost} 2>&1 &
    count=`expr $count + 1`
done < userhost.lst
while [ $count -gt 0 ]; do
    wait $pids
    count=`expr $count - 1`
done
echo "Output for hosts are in $tmpdir"
15
Arcege

複数のマシンに同時にログインして一連のコマンドを実行できるツールがいくつかあります。ここにカップルがあります:

62
Caleb

Python スクリプトをbashスクリプト以上に使用している場合、 Fabric がツールになるかもしれません。

Fabricホームページ から:

ファブリックは、Python(2.5以降))ライブラリであり、アプリケーションのデプロイメントやシステム管理タスクでのSSHの使用を効率化するためのコマンドラインツールです。

ローカルまたはリモートのシェルコマンド(通常またはSudoを介して)を実行し、ファイルをアップロード/ダウンロードするための基本的な操作スイートに加え、実行中のユーザーに入力を求めるプロンプトや実行の中止などの補助機能を提供します。

典型的な使い方は、1つ以上の関数を含むPythonモジュールを作成し、fabコマンドラインツールを介してそれらを実行することです。

18
Riccardo Murri

私は GNU parallel を使用していますが、最も具体的には this レシピを使用できます:

parallel --tag --nonall --slf your.txt command

your.txtは、サーバーのIPアドレス/名前を含むファイルです。

11
Anthon

非常に基本的なセットアップ:

for Host in $(cat hosts.txt); do ssh "$Host" "$command" >"output.$Host"; done

名前/パスワードで認証することは、本当に良い考えではありません。これには秘密鍵を設定する必要があります:

ssh-keygen && for Host in $(cat hosts.txt); do ssh-copy-id $Host; done
8
michas

Ansible.cc をお勧めします。構成マネージャーとコマンドディスパッチャーです。

4
Tom

Hypertable プロジェクトは最近マルチホストsshツールを追加しました。このツールはlibsshで構築され、接続を確立してコマンドを非同期でで並列に発行します並列処理を最大化します。完全なドキュメントについては Multi-Host SSH Tool を参照してください。一連のホストでコマンドを実行するには、次のように実行します。

$ ht ssh 1.1.1.1,2.2.2.2,3.3.3.3 uptime

ホスト名またはIPパターンを指定することもできます。次に例を示します。

$ ht ssh 1.1.1.[1-99] uptime
$ ht ssh Host[00-99] uptime

また、各ホストでのコマンドの開始を0〜--random-start-delay <millis>ミリ秒のランダムな時間間隔で遅らせる<millis>オプションもサポートしています。このオプションを使用すると、実行中のコマンドが中央のリソースにアクセスするときに、群れの問題を回避できます。

2
Doug judd

pssh と、通常のscp、rsyncなどの関連するパラレルバージョンを探していると思います。

2
unclejamil

私は Overcast と呼ばれるオープンソースのツールを作成して、このようなことを簡単にしています。

まず、サーバーを定義します。

overcast import vm.01 --ip 1.1.1.1 --ssh-key /path/to/key
overcast import vm.02 --ip 2.2.2.2 --ssh-key /path/to/key

次に、次のように、複数のコマンドとスクリプトファイルを順番または並列に実行できます。

overcast run vm.* uptime "free -m" /path/to/script --parallel
2
Andrew Childs

私は開発しました collectnode 複数のサーバー(ウィンドウを含む)でタスクを実行するのに非常にシンプルで効果的

CollectNodeの使用方法:

  1. 使用するサーバーのリストを作成します。

    # cat hosts.file
    server1
    server2
    server3
    server4
    server5
    
  2. サーバーのリストを渡してCollectNodeを実行します。

    collectnode --file servers.txt --command='cat /etc/httpd/conf/httpd.conf |grep ^User'
    
  3. 最適には、結果をフィルタリングすることができます。たとえば、このコマンドは、条件が満たされたサーバーのみを表示します。

    collectnode --file servers.txt --command='cat /etc/httpd/conf/httpd.conf |grep ^User' --where="command contain User"
    

https://collectnode.com/5-tasks-collectnode-can-help-managing-servers/

2
fvidalmolina

本当に素敵な質問の前置き:

私が見つけた最良の解決策は、当然のことながら、tmuxです。

Ctrl-Bを実行できます。tmuxでsetw synchronize-panesを実行すると、すばらしい結果が得られます。これを行うには、Tmuxの1つのウィンドウの異なるペインで、すべてのssh接続を開いておく必要があります。

1
Mikhail Krutov

「期待」はあなたが必要とするものだと思います。
多くの人はそれが存在することさえ知りません。それはあなたに代わって質問と可能な答えを作るtclベースのプログラムです。 https://wiki.tcl-lang.org/page/Expect をご覧ください

0
Clement

/ etc/sxx/hostsファイルを作成します

次のように入力します:

[grp_ips]
1.1.1.1
2.2.2.2
3.3.3.3

すべてのマシンでsshキーを共有します。

パッケージからsxxをインストールします。

https://github.com/ericcurtin/sxx/releases

次に、次のようにコマンドを実行します。

sxx username@grp_ips "whatever bash command"
0
ericcurtin

多分このようなものが機能し、コマンドを複数のホストで実行しますか?すべてのホストがパスワードなしのログイン用に.ssh/configで設定されていると仮定します。

$ < hosts.txt xargs -I {} ssh {} command

0
Y0NG

Paramiko http://www.paramiko.org/ およびスレッドベースの並列処理 https://docs.python.org/3/library/threading.html .belowを使用しますコードにより、各サーバーで複数のコマンドを並行して実行できます!

ssh = paramiko.SSHClient()
ssh.set_missing_Host_key_policy(paramiko.AutoAddPolicy())
ssh.load_system_Host_keys()
ssh.connect(hostname, port, username, password)
t = threading.Thread(target=tasks[index], args=(ssh, box_ip,))
t.start()

注:サーバーごとに上記の手順を繰り返します。

0
Sharma