How can I automate running commands remotely over

2019-01-21 08:21发布

I've searched around a bit for similar questions, but other than running one command or perhaps a few command with items such as:

ssh user@host -t sudo su -

However, what if I essentially need to run a script on (let's say) 15 servers at once. Is this doable in bash? In a perfect world I need to avoid installing applications if at all possible to pull this off. For argument's sake, let's just say that I need to do the following across 10 hosts:

  1. Deploy a new Tomcat container
  2. Deploy an application in the container, and configure it
  3. Configure an Apache vhost
  4. Reload Apache

I have a script that does all of that, but it relies on me logging into all the servers, pulling a script down from a repo, and then running it. If this isn't doable in bash, what alternatives do you suggest? Do I need a bigger hammer, such as Perl (Python might be preferred since I can guarantee Python is on all boxes in a RHEL environment thanks to yum/up2date)? If anyone can point to me to any useful information it'd be greatly appreciated, especially if it's doable in bash. I'll settle for Perl or Python, but I just don't know those as well (working on that). Thanks!

21条回答
狗以群分
2楼-- · 2019-01-21 08:43

The issue of how to run commands on many servers at once came up on a Perl mailing list the other day and I'll give the same recommendation I gave there, which is to use gsh:

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

gsh is similar to the "for box in box1_name box2_name box3_name" solution already given but I find gsh to be more convenient. You set up a /etc/ghosts file containing your servers in groups such as web, db, RHEL4, x86_64, or whatever (man ghosts) then you use that group when you call 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 ~]$

You can also combine or split ghost groups, using web+db or web-RHEL4, for example.

I'll also mention that while I have never used shmux, its website contains a list of software (including gsh) that lets you run commands on many servers at once. Capistrano has already been mentioned and (from what I understand) could be on that list as well.

查看更多
仙女界的扛把子
3楼-- · 2019-01-21 08:44

Although it's a complex topic, I can highly recommend Capistrano.

查看更多
Melony?
4楼-- · 2019-01-21 08:44

Multixterm is cool for doing this, and allows you to easily put the 1 out of n machine back in sequence.

查看更多
爱情/是我丢掉的垃圾
5楼-- · 2019-01-21 08:45

There is a tool called FLATT (FLexible Automation and Troubleshooting Tool) that allows you to execute scripts on multiple Unix/Linux hosts with a click of a button. It is a desktop GUI app that runs on Mac and Windows but there is also a command line java client.
You can create batch jobs and reuse on multiple hosts.
Requires Java 1.6 or higher.

查看更多
Emotional °昔
6楼-- · 2019-01-21 08:47

For those that stumble across this question, I'll include an answer that uses Fabric, which solves exactly the problem described above: Running arbitrary commands on multiple hosts over ssh.

Once fabric is installed, you'd create a fabfile.py, and implement tasks that can be run on your remote hosts. For example, a task to Reload Apache might look like this:

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")

Then, on your local machine, run fab reload and the sudo /etc/init.d/apache2 reload command would get run on all the hosts specified in env.hosts.

查看更多
手持菜刀,她持情操
7楼-- · 2019-01-21 08:47

You can do it the same way you did before, just script it instead of doing it manually. The following code remotes to machine named 'loca' and runs two commands there. What you need to do is simply insert commands you want to run there.

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

Then, to iterate through all the machines, do something like:

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

In order to make this ssh thing work without entering passwords all the time, you'll need to set up key authentication. You can read about it at IBM developerworks.

查看更多
登录 后发表回答