This is a read-only archive. Find the latest Linux articles, documentation, and answers at the new Linux.com!

Linux.com

Feature: Tools & Utilities

Parallel SSH execution and a single shell to control them all

By Ben Martin on October 30, 2008 (8:00:00 AM)

Share    Print    Comments   

Many people use SSH to log in to remote machines, copy files around, and perform general system administration. If you want to increase your productivity with SSH, you can try a tool that lets you run commands on more than one remote machine at the same time. Parallel ssh, Cluster SSH, and ClusterIt let you specify commands in a single terminal window and send them to a collection of remote machines where they can be executed.

ClusterIt

The third application, ClusterIt, provides much more than a way to control many SSH sessions from a single console. While it includes parallel versions of cp (pcp), rm (prm), top (dtop), and df (pdf), it also provides directives for running a command on any node of the cluster (run), issuing a collection of commands over different nodes in the cluster (seq), and ensuring that only a single job is run on any node at any one time (jsh).

There are no ClusterIT packages for openSUSE, Ubuntu Hardy, or Fedora 9. I built ClusterIt 2.5 from source on a 64-bit Fedora 9 machine using ./configure && make && sudo make install.

ClusterIt uses the dvt command to open a terminal to all the nodes in a cluster. Unlike Cluster SSH, ClusterIt does not tile the new windows for you, so you might have to manually arrange the terminals unless your window manager gives you a pleasant layout by default. The controlling window in ClusterIt also has fewer options than the one in Cluster SSH. To start a terminal on every node in a cluster with ClusterIt, use the -w option and specify the host names in a comma-separated list, as shown below. The screenshot shows the resulting terminals and control window. Closing the controlling window, the one with dtv in its title, does not close all the terminal windows -- you have to click on the quit button in the dvt window to close all the terminals in the session.

$ dvt -w p1,p2

For most of the ClusterIt commands, you specify the groups to connect to with -g, the nodes with -w, and can exclude nodes with -x.

Use the pcp command to copy files to all the nodes in your cluster either serially (the default) or in parallel (using the -c option). Copying in parallel can be quicker if you have the bandwidth to talk to all the nodes at once. If you copy in parallel, you can set the fanout using the -f option. The default is 64, meaning that a copy to 64 nodes will run in parallel.

Some of the options to cp< are available in pcp. Unfortunately the -a option commonly used with cp, which is an alias for -cdpR, is not. The cp -c option has a different meaning in pcp, and there is no -d option in pcp. The -p and -R options work the same in pcp as in cp.

Some other commonly used options are missing from some of the other ClusterIt commands. For instance, the -h option to df is missing in the ClusterIt parallel (pdf) implementation. Seeing the disk space in 1K blocks might be interesting for a computer, but you're likely more interested in knowing you have 140MB of free space on /var than the exact number of disk blocks.

In the commands below, I first recursively copy a directory tree to /tmp on both the hosts. If you want to copy to up to your fanout nodes all at once, include the -c option in the pcp line. The ssh invocation after this verifies that one of the files in the example-tree exists on the p1 host. As you can see, the output of pdf is not as easily digestible as a df -h would be. The prm command is then used to remove the tree on both hosts.

# pcp -pr -w p1,p2 example-tree /tmp/ df10.txt ... 100% 29 0.0KB/s 00:00 df1.txt ... 100% 29 0.0KB/s 00:00 ... # ssh p1 cat /tmp/example-tree/df10.txt Thu Oct 16 21:45:50 EST 2008 # pdf -w p1,p2 /tmp Node Filesystem 1K-Blks Used Avail Cap Mounted On p1 : /dev/mapper/VolGrou 15997880 3958792 11213336 27% / p2 : /dev/mapper/VolGrou 15997880 3536648 11635480 24% / # prm -rf -w p1,p2 /tmp/example-tree

The main strong point of ClusterIt is the support for job scheduling and barriers. Barriers allow you to write a script that runs on many nodes, and wait until all of the nodes are at the barrier before proceeding to execute the next part of the script. This sort of synchronization allows common "process then merge" scripting to be written without getting bogged down in the logistics of communicating with other nodes in your scripts. Just use the barrier command from your parallel scripts to wait for all the nodes to be at a given point in the script.

The jsh command can execute a command on any node of the cluster, with the restriction that only one command can be running on any node at any one point in time. This restriction prevents a node from becoming bogged down when the script using ClusterIt keeps issuing commands to be run on the cluster but the previous commands have not completed yet. For example, if you are compiling code using ClusterIt, perhaps there are a few source files that take much longer to compile than others. Without intelligent scheduling or the one-job-per-node restriction, the parallel compile might continue to give new jobs to a node that is still trying to compile a difficult file. Using jsh, nodes that need to take longer to work on a particular job can do so without having new jobs handed to them.

Using jsh is simple. You first execute the daemon jsd on the controlling host -- say, your desktop machine -- and then use jsh to issue commands. You can use the -g, -w, and -x options to tell the daemon what nodes are in the cluster, and then you can use jsh without any special arguments. An example of jsh usage is shown below. First the daemon is started and then a command is run with jsh. Running two calls to jsh and putting them into the background means that a job will be sent to both hosts, as the output shows at the end of the example.

# jsd -w p1,p2 jsd started with pid 24615 # jsh hostname p2: vfedora864prx2 # jsh "sleep 10; hostname" & [1] 24648 # jsh "sleep 10; hostname" & [2] 24650 p2: vfedora864prx2 p1: vfedora864prx1

Instead of using the -g, -w, or -x options, you can set the CLUSTER environment variable to the name of a file that contains a newline-separated list of hosts. The FANOUT variable controls how many nodes should be contacted in parallel for a job.

Final words

Each of these three applications has its strong points. If you are interested in issuing commands to a cluster and having some load balancing, ClusterIt should be your first choice. If you want a group of xterms and a single window to control them all, Cluster SSH provides the most user-friendly multiterminal of the three, allowing you to also disable a node temporarily or directly interact with just a single host before switching back to controlling them all. Parallel ssh includes a parallel rsync command and lets you control multiple hosts from a single terminal. You don't get to see your input mirrored to multiple xterms with Parallel ssh, but if you have a heterogeneous group of machines and frequently issue the same commands on them all, Parallel ssh will give you a single interactive terminal to them all without cluttering your display with individual xterms for each node.

Ben Martin has been working on filesystems for more than 10 years. He completed his Ph.D. and now offers consulting services focused on libferris, filesystems, and search solutions.

 

Share    Print    Comments   

Comments

on Parallel SSH execution and a single shell to control them all

Note: Comments are owned by the poster. We are not responsible for their content.

Parallel SSH execution and a single shell to control them all

Posted by: Anonymous [ip: 64.89.94.194] on October 30, 2008 01:05 PM
Another product that you should check out is called Func https://fedorahosted.org/func
from the product description:
Func is a secure, scriptable remote control framework and API. It is intended to replace SSH scripted infrastructure for a variety of datacenter automation tasks (such as taking hardware inventory, running queries, or executing remote commands) that are run against a large amount of systems at the same time. Func provides both a command line tool and a simple and powerful Python API. It is also intended to be very easy to integrate with your provisioning environment and tools like Cobbler.

So say you need to update just your test machines you do:
func "*.test.example.org" call yumcmd update

#

Re: Parallel SSH execution and a single shell to control them all

Posted by: Anonymous [ip: 67.173.12.114] on October 30, 2008 02:20 PM
Func is more feature rich then some of these applications but its also far more difficult to setup. Its hard to beat "yum install pssh" and be able to do what's listed in this article.

#

Parallel SSH execution and a single shell to control them all

Posted by: Anonymous [ip: 76.98.241.86] on October 31, 2008 06:32 PM
Capistrano (http://www.capify.org) is another tool to do this. It's billed as a deployment tool but is essentially a tool for defining sequences of operations to execute on remote hosts in parallel.

#

This isn't good enough?

Posted by: Anonymous [ip: 76.103.250.180] on November 01, 2008 01:46 AM
For x in `cat hosts`; do ssh -f $x "do stuff" & done && wait;

#

Re: This isn't good enough?

Posted by: Anonymous [ip: 98.215.194.203] on November 01, 2008 09:22 PM
no, its not. Lets take a sample size of 32 hosts and run a quick command on each:


$ time for f in `cat hosts`; do ssh $f 'ls / > /dev/null'; done
real 2m45.195s

That's roughly 5.15 seconds per host. If this were a 5000 node network we're looking at about 7.1 hours to complete this command. Lets do the same test with pssh and a max parallel of 10:

$ time pssh -p 10 -h hosts "ls > /dev/null"
real 0m17.220s

That's some considerable savings. lets try each one in parallel and set the max to 32:
$ time pssh -p 32 -h hosts "ls > /dev/null"
real 0m7.436s

If one run took about 5 seconds, doing them all at the same time also took about 5 seconds, just with a bit of overhead. I don't have a 5000 node network (anymore) but you can see there are considerable savings by doing some things in parallel. You probably wouldn't ever run 5000 commands in parallel but really thats a limit of your hardware and network. if you had a beefy enough host machine you probably could run 50, 100 or even 200 in parallel if the machine could handle it.

#

Re(1): This isn't good enough?

Posted by: Anonymous [ip: 99.156.88.107] on November 02, 2008 07:54 PM
It's absolutely not good enough. 4 or so years ago a coworker and I wrote a suite of parallel ssh tools to help perform security related duties on the very large network in our global corp. With our tools on a mosix cluster using load balanced ssh-agents across multiple nodes we could run upto 1000 outbound sessions concurrently. This made tasks such as looking for users processes or cronjobs on 10,000+ hosts world wide a task that could be done in a reasonable amount of time, as opposed to taking more than a day.

#

Parallel SSH execution and a single shell to control them all

Posted by: Anonymous [ip: 24.14.35.105] on November 02, 2008 12:43 PM
I use the parallel option to xargs for this. Tried shmux, and some other tools, but xargs seems to work best for me. Just use a more recent gnu version. Some older gnu versions, some aix version, etc... have some issues. Only real gotcha that I've run into is that it will stop the whole run if a command exits non-zero. Just write a little wrapper that exits 0 and you're good to go. I've used this in 2 ~1000 server environments to push code(pipe tar over ssh for better compatibility), and remotely execute commands.

#

Parallel SSH execution and a single shell to control them all

Posted by: Anonymous [ip: 66.151.59.138] on November 04, 2008 04:09 PM
Ticketmaster wrote a really good tool to do parallel systems administration tasks like this called "onall".

It is released under the gplv3 and can be downloaded from:
http://code.google.com/p/onall/

I do something like this to execute a command on all hosts and set the timeout to 10 seconds:
host -l internal.dns.zone | awk '{print $1}' | onall -t10 "uptime"

#

Parallel SSH execution and a single shell to control them all

Posted by: Anonymous [ip: 87.230.108.21] on November 06, 2008 10:08 AM
What I'm curious about is this:
"""
if you want to interactively edit the same file on multiple machines, it might be quicker to use a parallel SSH utility and edit the file on all nodes with vi rather than concoct a script to do the same edit.
"""

I would have found a short note on which of these three is capable of doing so very helpfull. Cluster SSH's description sounds as though it would be the tool that could do it. But I just don't have the time to test it just yet.
Anyone tried that yet? Or knows to which tool this statement refers to?

#

Re: Parallel SSH execution and a single shell to control them all

Posted by: Anonymous [ip: 75.25.174.30] on November 14, 2008 05:33 AM
I don't see ssh keys mentioned anywhere...I'm not getting how this allows authentication to happen. Is this thing secure?

#

This story has been archived. Comments can no longer be posted.



 
Tableless layout Validate XHTML 1.0 Strict Validate CSS Powered by Xaraya