Как я могу автоматизировать параллельное выполнение команд через SSH на нескольких серверах? - PullRequest
18 голосов
/ 28 октября 2008

Я немного искал похожие вопросы, но кроме выполнения одной команды или нескольких команд с такими элементами, как:

ssh user@host -t sudo su -

Однако, что если мне нужно запустить скрипт (скажем, на 15 серверах одновременно). Это выполнимо в Bash? В идеальном мире мне нужно избегать установки приложений, если это вообще возможно. Ради аргумента, давайте просто скажем, что мне нужно сделать следующее на 10 хостах:

  1. Развертывание нового контейнера Tomcat
  2. Разверните приложение в контейнере и настройте его
  3. Настройка Apache vhost
  4. Перезагрузить Apache

У меня есть скрипт, который делает все это, но он полагается на то, что я захожу на все серверы, вытаскиваю скрипт из репозитория и запускаю его. Если это невозможно в bash, какие альтернативы вы предлагаете? Нужен ли мне больший молоток, такой как Perl (Python может быть предпочтительнее, так как я могу гарантировать, что Python есть на всех блоках в среде RHEL благодаря yum / up2date)? Если кто-нибудь может указать мне какую-либо полезную информацию, она будет очень признательна, особенно если это возможно в bash. Я соглашусь на Perl или Python, но я просто не знаю их (работает над этим). Спасибо!

Ответы [ 21 ]

11 голосов
/ 28 октября 2008

Вы можете запустить локальный скрипт, как показано che и Yang, и / или вы можете использовать документ Here:

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 
9 голосов
/ 28 октября 2008

Часто я просто использую оригинальную версию Expect для Tcl. Это нужно только на локальной машине. Если я нахожусь внутри программы, использующей Perl, я делаю это с Net :: SSH :: Expect . Другие языки имеют аналогичные инструменты «ожидают».

9 голосов
/ 29 октября 2008

Вопрос о том, как запускать команды на многих серверах одновременно, возник в списке рассылки Perl на днях, и я дам такую ​​же рекомендацию Я дал там , который должен использовать gsh :

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

gsh похож на решение "for box in box1_name box2_name box3_name" уже дано , но я считаю, что gsh более удобен. Вы настраиваете файл / etc / ghosts, содержащий ваши серверы в таких группах, как web, db, RHEL4, x86_64 или что-то еще (man 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, его веб-сайт содержит список программного обеспечения (включая gsh), которое позволяет вам запускать команды на многих серверах одновременно. Capistrano уже упоминалось и (насколько я понимаю) также может быть в этом списке.

6 голосов
/ 28 октября 2008

Взгляните на Expect (man expect)

В прошлом я выполнял подобные задачи, используя Expect.

4 голосов
/ 09 ноября 2009

Вы можете попробовать paramiko . Это ssh-клиент на чистом python. Вы можете запрограммировать ваши сеансы SSH. Нечего устанавливать на удаленных машинах.

См. Эту замечательную статью о том, как ее использовать.

4 голосов
/ 28 октября 2008

Вы можете передать локальный скрипт на удаленный сервер и выполнить его одной командой:

ssh -t user@host 'sh' < path_to_script

Это может быть дополнительно автоматизировано с использованием аутентификации с открытым ключом и переносом сценариев для выполнения параллельного выполнения.

3 голосов
/ 28 октября 2008

Чтобы дать вам структуру, без фактического кода.

  1. Используйте scp, чтобы скопировать скрипт установки / настройки в целевое окно.
  2. Используйте ssh для вызова вашего скрипта в удаленном окне.
2 голосов
/ 15 декабря 2008

Вы смотрели на такие вещи, как Кукольный или Cfengine . Они могут делать то, что вы хотите, и, вероятно, гораздо больше.

2 голосов
/ 30 апреля 2012

Для тех, кто наткнулся на этот вопрос, я включу ответ, который использует Fabric , который точно решает проблему, описанную выше: Запуск произвольных команд на нескольких хостах через ssh.

После установки Fabric вы создадите 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.

2 голосов
/ 15 декабря 2008

pssh может быть интересным, поскольку, в отличие от большинства решений, упомянутых здесь, команды выполняются параллельно.

(Для собственного использования я написал более простой маленький скрипт, очень похожий на скрипт GavinCattell, он задокументирован здесь - на французском ).

...