仮想化大好きな皆さん( ノ゚Д゚)こんばんわ。…なんだこの顔文字。2ch辞書入れてる所為か、恐いな(;´Д`)
さて、家やAWSにサーバをお持ちの仮想化大好きの皆様は、もう100も 200もサーバを管理されていることと認知しています。したがって、マルチサイトを管理するための専用のツールなどを入れて、効率的に管理しているだろうと予想します。流石です。それにつけても、仮想化初心者の私の自宅サーバでは、マシンスペックも非力ですし、そんなにたくさんを管理することなど不可能です。ましてやお金がないのに、専用の管理ツールなんて…。
そのため、ごにょごにょして、ssh で rootでは non password で、DSAの鍵認証をさせて、あるサーバから、全てのサーバへログインできるようにして、複数のサイトへコマンドを実行できるように、なんてことをしています。例えばこんなワンライナーで。
1 | $ for server in host01 host02 host03 ; do ssh $server "command01;command02" ; done |
ただ、これではシングルタスクで順次実行ですし、”sudo” 使えないので、sudo したければ shell を組まねばなりません。
そこで登場したるは”GNU Parallel“コマンドです。複数ジョブを一気に実行できますし、コマンド化されているので sudoかけることもできます。先ほどの例を展開すると。
1 | $ sudo parallel -j 3 ssh {} "command01;command02" ::: host01 host02 host03 |
簡単ですね。ホスト名の一覧の入ったファイルを指定して
1 | $ cat hostlist | sudo parallel -j 3 ssh {} "command01;command02" |
こんなことをすることもできます。便利ですねヽ(´ー`)ノ [I]なお、”-j 3″はジョブを3つ並行起動する。です。大きくすれば同時実行数が増えます。CPU使用率での表現も可能です。”-j … Continue reading
しかし、実行してみるとわかるのですが、command02は parallel コマンド経由だと、ローカルホストで実行されてしまうんですね…。
parallel+sshで複数ホストに複数のコマンドを実行させる方法
対処は簡単でした。
1 | $ cat hostlist | sudo parallel -j 3 ssh {} '"command01;command02"' |
このように sshへの引数のダブルクォーテーションに、さらにシングルクォーテーションをつけるだけです。
これは、gnu parallel コマンドが sshへ引数を渡す時に、”command01;command02″ を展開して、command01;command02 として処理してしまうために、ssh へは ‘command01’ しか引き渡されないことに起因します。(多分)
shell として、parallel へは、”command01;command02″ を一つの引数として引き渡しているのですが、parallel が内部で展開してしまっているのだと思います。(多分)
まぁなんでもいいです。このようにやればうまく行くのです( ゚д゚ )クワッ!!
仮説の検証はどなたかにお任せしますので、動作の内情が分かったら教えてください。こっそりと。
あと、`command`もlocalで実行されてしまうので、次はこれをリモートで実行できないかとか変なことを考えてます。
References
↑I | なお、”-j 3″はジョブを3つ並行起動する。です。大きくすれば同時実行数が増えます。CPU使用率での表現も可能です。”-j 300%”みたいに。多分 |
---|
Consider using GNU Parallel’s –nonall:
sudo parallel –nonall –slf hostlist -j 3 command01 ; command02
You can make profile like this:
echo “–nonall –slf hostlist -j 3” >.parallel/my_servers
And then you can simply do:
sudo parallel -J my_servers command01 ; command02
Consider using GNU Parallel’s-nonall:
sudo parallel --nonall --slf hostlist -j 3 command01 ; command02
You can make profile like this:
echo "--nonall --slf hostlist-j 3" > .parallel/my_servers
And then you can use less quoting:
sudo parallel -J my_servers 'command01 ; command02'
Thank you for replying .
This is great and siimple.