SSHを介して複数のサーバーに対して並行してリモートでコマンドを実行することを自動化するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/243750

  •  04-07-2019
  •  | 
  •  

質問

同様の質問を少し検索しましたが、1つのコマンドを実行したり、次のような項目を使用していくつかのコマンドを実行したりする以外は、

ssh user@host -t sudo su -

ただし、15台のサーバー(一度に)でスクリプトを実行する必要がある場合はどうでしょうか。これはbashで実行可能ですか?完璧な世界では、アプリケーションをインストールすることを可能な限り回避する必要があります。引数のために、10個のホストで次のことを行う必要があるとだけ言ってみましょう。

  1. 新しいTomcatコンテナをデプロイします
  2. コンテナにアプリケーションをデプロイし、構成します
  3. Apache vhostの構成
  4. Apacheのリロード

すべてを実行するスクリプトがありますが、すべてのサーバーにログインし、レポジトリからスクリプトを取得して実行することに依存しています。これがbashで実行できない場合、どのような代替案を提案しますか? Perlなどの大きなハンマーが必要ですか(yum / up2dateのおかげでPythonがRHEL環境のすべてのボックスにあることを保証できるので、Pythonが好まれます)?誰かが私に有用な情報を指し示すことができれば、特にbashで実行可能であれば、それは大歓迎です。私はPerlまたはPythonに落ち着きますが、私もそれらを知りません(それに取り組んでいます)。ありがとう!

役に立ちましたか?

解決

多くの場合、Expectの元のTclバージョンを使用します。それはローカルマシン上でのみ必要です。 Perlを使用してプログラム内にいる場合、 Net :: SSH ::を使用してこれを実行します。期待。他の言語にも同様の<!> quot; expect <!> quot;があります。ツール。

他のヒント

cheとYangが示すようにローカルスクリプトを実行できます。また、ヒアドキュメントを使用できます。

ssh root@server /bin/sh <<\EOF  
wget http://server/warfile    # Could use NFS here  
cp app.war /location  
command 1  
command 2  
/etc/init.d/httpd restart  
EOF 

多くのサーバーでコマンドを一度に実行する方法の問題は、先日Perlメーリングリストで取り上げられました。同じ推奨事項を私がそこに与えた、これはgsh

を使用することです

http://outflux.net/unix/software/gsh

gshは<!> quot; for box in box1_name box2_name box3_name <!> quot;と似ています。解決策既に与えられているが、gshの方が便利だと思う。 web、db、RHEL4、x86_64、その他(man ghosts)などのグループのサーバーを含む/ etc / ghostsファイルを設定し、gshを呼び出すときにそのグループを使用します。

[pdurbin@beamish ~]$ gsh web "cat /etc/redhat-release; uname -r"
www-2.foo.com: Red Hat Enterprise Linux AS release 4 (Nahant Update 7)
www-2.foo.com: 2.6.9-78.0.1.ELsmp
www-3.foo.com: Red Hat Enterprise Linux AS release 4 (Nahant Update 7)
www-3.foo.com: 2.6.9-78.0.1.ELsmp
www-4.foo.com: Red Hat Enterprise Linux Server release 5.2 (Tikanga)
www-4.foo.com: 2.6.18-92.1.13.el5
www-5.foo.com: Red Hat Enterprise Linux Server release 5.2 (Tikanga)
www-5.foo.com: 2.6.18-92.1.13.el5
[pdurbin@beamish ~]$

たとえば、web + dbまたはweb-RHEL4を使用して、ゴーストグループを結合または分割することもできます。

shmuxを使用したことはありませんが、そのWebサイトには、多くのサーバーでコマンドを一度に実行できるソフトウェア(gshを含む)。 Capistrano は既に言及されており、(私が理解している限りでは)そのリストにも載っている可能性があります。

期待(man expect)を見てください

Expectを使用して、過去に同様のタスクを実行しました。

ローカルスクリプトをリモートサーバーにパイプして、1つのコマンドで実行できます。

ssh -t user@host 'sh' < path_to_script

これは、公開鍵認証を使用し、スクリプトでラップして並列実行することにより、さらに自動化できます。

paramiko を試すことができます。これは、純粋なPython sshクライアントです。 SSHセッションをプログラムできます。リモートマシンにインストールするものはありません。

こちらをご覧くださいすばらしい記事使用方法について。

実際のコードなしで構造を提供する。

  1. scpを使用して、インストール/セットアップスクリプトをターゲットボックスにコピーします。
  2. sshを使用して、リモートボックスでスクリプトを呼び出します。

pssh は、ここで説明したほとんどのソリューションとは異なり、コマンドが並行して実行されるため、興味深い場合があります。 。

(私自身が使用するために、GavinCattellのスクリプトに非常によく似たシンプルな小さなスクリプトを作成しました。これはここに文書化-フランス語で)。

Puppet または Cfengine 。彼らはあなたが望むことをすることができ、おそらくもっと多くのことができます。

この質問に出くわした人のために、 Fabric を使用する回答を記載します。これにより、記載されている問題を正確に解決できます。上記:sshを介して複数のホストで任意のコマンドを実行します。

ファブリックをインストールしたら、fabfile.pyを作成し、リモートホストで実行できるタスクを実装します。たとえば、Apacheをリロードするタスクは次のようになります:

from fabric.api import env, run

env.hosts = ['host1@example.com', 'host2@example.com']

def reload():
    """ Reload Apache """
    run("sudo /etc/init.d/apache2 reload")

次に、ローカルマシンでfab reloadを実行すると、sudo /etc/init.d/apache2 reloadで指定されたすべてのホストでenv.hostsコマンドが実行されます。

以前と同じ方法で実行できます。手動で行うのではなく、スクリプトを作成するだけです。次のコードは、「loca」という名前のマシンにリモート接続し、そこで2つのコマンドを実行します。必要なのは、そこで実行したいコマンドを挿入するだけです。

che@ovecka ~ $ ssh loca 'uname -a; echo something_else'
Linux loca 2.6.25.9 #1 (blahblahblah)
something_else

次に、すべてのマシンを反復処理するには、次のようにします。

for box in box1_name box2_name box3_name
do
   ssh $box 'commmands_to_run_everywhere'
done

このsshを常にパスワードを入力せずに機能させるには、キー認証を設定する必要があります。これについては、 IBM developerworks で読むことができます。

cluster ssh 。リンクは、今日のブログのDebianパッケージにあるクラスターsshの議論へのリンクです。

まあ、ステップ1と2には、TomcatマネージャーのWebインターフェースはありません。 libwwwプラグインでcurlまたはzshを使用してスクリプトを作成できます。

SSHの場合: 1)パスワードの入力を求められない(キーを使用) 2)SSHのコマンドラインでコマンドを渡します。これは、信頼できるネットワークのrshに似ています。

他の投稿で何をすべきかが示されており、おそらくshも使用したいと思いますが、perlのようにssh tomcatuser@server perl -e 'do-everything-on-one-line;'を使用したい、またはこれを行うことができます:

いずれか scp the_package.tbz tomcatuser@server:the_place/.
ssh tomcatuser@server /bin/sh <<\EOF
次のようなものを定義 TOMCAT_WEBAPPS=/usr/local/share/tomcat/webapps
tar xj the_package.tbz または rsync rsync://repository/the_package_place
mv $TOMCAT_WEBAPPS/old_war $TOMCAT_WEBAPPS/old_war.old
mv $THE_PLACE/new_war $TOMCAT_WEBAPPS/new_war
touch $TOMCAT_WEBAPPS/new_war [通常はTomcatを再起動する必要はありません]
mv $THE_PLACE/vhost_file $APACHE_VHOST_DIR/vhost_file
$APACHECTL restart [そのファイルを移動して再起動するには、Apacheユーザーとしてログインする必要がある場合があります]
EOF

クラスターでよく使用されるDSHまたは分散シェルが必要です。リンクは次のとおりです。 dsh

基本的にノードグループ(ノードのリストを含むファイル)があり、コマンドを実行するノードグループを指定し、sshでコマンドを実行するようにdshを使用します。

dsh -a /path/to/some/command/or/script

すべてのマシンで同時にコマンドを実行し、ホスト名を前に付けた出力を返します。コマンドまたはスクリプトはシステム上に存在する必要があるため、共有NFSディレクトリはこれらの種類のものに役立ちます。

アクセスされるすべてのマシンのhostname sshコマンドを作成します。 キエラティ http://pastebin.com/pddEQWq2

#Use in .bashrc
#Use "HashKnownHosts no" in ~/.ssh/config or /etc/ssh/ssh_config 
# If known_hosts is encrypted and delete known_hosts

[ ! -d ~/bin ] && mkdir ~/bin
for host in `cut -d, -f1 ~/.ssh/known_hosts|cut -f1 -d " "`;
  do
    [ ! -s ~/bin/$host ] && echo ssh $host '$*' > ~/bin/$host
done
[ -d ~/bin ] && chmod -R 700 ~/bin
export PATH=$PATH:~/bin 

Ex Execute:

$for i in hostname{1..10}; do $i who;done

FLATT(FLexible Automation and Troubleshooting Tool)というツールがあり、複数のUnix / Linuxでスクリプトを実行できます。ボタンをクリックするだけでホストできます。 MacとWindowsで実行されるデスクトップGUIアプリですが、コマンドラインJavaクライアントもあります。
バッチジョブを作成して、複数のホストで再利用できます。
Java 1.6以降が必要です。

複雑なトピックですが、 Capistrano を強くお勧めします。

この方法が必要なものすべてに機能するかどうかはわかりませんが、次のようなものを試すことができます:

$ cat your_script.sh | ssh your_host bash

リモートサーバーで(ローカルに存在する)スクリプトを実行します。

Multixterm はこれを行うのに便利で、nのうち1を簡単に配置できます。マシンを順番に戻します。

新しいブログを読むだけ setsid を使用します。メインストリームカーネル以外のインストール/設定は必要ありません。 Ubuntu14.04でテスト/検証済み。

作成者には非常に明確な説明とサンプルコードもありますが、ここでは簡単に説明するための魔法の部分を示します。

#----------------------------------------------------------------------
# Create a temp script to echo the SSH password, used by SSH_ASKPASS
#----------------------------------------------------------------------
SSH_ASKPASS_SCRIPT=/tmp/ssh-askpass-script
cat > ${SSH_ASKPASS_SCRIPT} <<EOL
#!/bin/bash
echo "${PASS}"
EOL
chmod u+x ${SSH_ASKPASS_SCRIPT}

# Tell SSH to read in the output of the provided script as the password.
# We still have to use setsid to eliminate access to a terminal and thus avoid
# it ignoring this and asking for a password.
export SSH_ASKPASS=${SSH_ASKPASS_SCRIPT}
......
......
# Log in to the remote server and run the above command.
# The use of setsid is a part of the machinations to stop ssh 
# prompting for a password.
setsid ssh ${SSH_OPTIONS} ${USER}@${SERVER} "ls -rlt"

複数のマシンでSSHコマンドを実行するスクリプトを以下に示します。役立つ場合があります。

#!/bin/bash
MACHINES="machine1 machine2 machine3 machine4 machine5 machine6"
for m in $MACHINES
do
        cmd="ssh $m '$*'"
        eval $cmd
done

これをパスに挿入して、sshAllなどの名前を付けてから、sshAllコマンドを入力することもできます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top