Как я могу автоматизировать удаленное выполнение команд через SSH на нескольких серверах параллельно?
Вопрос
Я немного искал похожие вопросы, но кроме запуска одной команды или, возможно, нескольких команд с такими элементами, как:
ssh user@host -t sudo su -
Однако что делать, если мне по сути нужно запустить скрипт (скажем) на 15 серверах одновременно.Это выполнимо в bash?В идеальном мире мне нужно избегать установки приложений, если это вообще возможно.В качестве аргумента скажем, что мне нужно сделать следующее на 10 хостах:
- Развертывание нового контейнера Tomcat
- Разверните приложение в контейнере и настройте его.
- Настройка виртуального хоста Apache
- Перезагрузить Апач
У меня есть сценарий, который делает все это, но он требует, чтобы я заходил на все серверы, извлекал сценарий из репозитория и затем запускал его.Если это невозможно в bash, какие альтернативы вы предлагаете?Нужен ли мне более мощный молоток, например Perl (Python может быть предпочтительнее, поскольку я могу гарантировать, что Python присутствует на всех устройствах в среде RHEL благодаря yum/up2date)?Если кто-нибудь может указать мне на какую-либо полезную информацию, я буду очень признателен, особенно если это выполнимо в bash.Я соглашусь на Perl или Python, но я их просто не знаю (работаю над этим).Спасибо!
Решение
Часто я просто использую оригинальную версию Expect для Tcl. Это нужно только на локальной машине. Если я в программе, использующей Perl, я делаю это с Net :: SSH :: Ожидать . Другие языки имеют аналогичные & Quot; Ожидайте & Quot; инструменты.
Другие советы
Вы можете запустить локальный скрипт, как показано 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
Вопрос о том, как запускать команды на нескольких серверах одновременно, возник на днях в списке рассылки 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), которое позволяет запускать команды на многих серверах одновременно. Капистрано уже упоминалось и (насколько я понимаю) тоже может быть в этом списке.
Посмотрите на Expect (man expect
)
В прошлом я выполнял подобные задачи, используя Expect.
Вы можете передать локальный скрипт на удаленный сервер и выполнить его одной командой:
ssh -t user@host 'sh' < path_to_script
Это может быть дополнительно автоматизировано путем использования аутентификации с открытым ключом и переноса сценариев для выполнения параллельного выполнения.
Вы можете попробовать paramiko . Это ssh-клиент на чистом python. Вы можете запрограммировать ваши сеансы SSH. Нечего устанавливать на удаленных машинах. Р>
См. эту замечательную статью о том, как его использовать.
Чтобы дать вам структуру, без реального кода.
<Ол>pssh может быть интересным, поскольку, в отличие от большинства упомянутых здесь решений, команды выполняются параллельно . р>
(Для собственного использования я написал более простой небольшой скрипт, очень похожий на скрипт GavinCattell, это задокументировано здесь - на французском языке ).
Для тех, кто сталкивается с этим вопросом, я включу ответ, который использует 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
.
Вы можете сделать это так же, как и раньше, просто сделайте сценарий вместо того, чтобы делать это вручную. Следующий код удален к машине с именем 'loca' и запускает там две команды. Что вам нужно сделать, это просто вставить команды, которые вы хотите запустить там.
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 . Ссылка на обсуждение кластера ssh в пакете Debian дневного блога.
Ну, для шагов 1 и 2 нет веб-интерфейса менеджера tomcat; Вы можете написать это с помощью curl или zsh с подключаемым модулем libwww.
Для 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
[обычно вам не нужно перезапускать кота]
mv $THE_PLACE/vhost_file $APACHE_VHOST_DIR/vhost_file
$APACHECTL restart
[может потребоваться войти в систему как пользователь apache, чтобы переместить этот файл и перезапустить]
EOF
Вам нужен DSH или распределенная оболочка, которая часто используется в кластерах. Вот ссылка: dsh
У вас в основном есть группы узлов (файл со списками узлов в них), и вы указываете, в какой группе узлов вы хотите запускать команды, тогда вы будете использовать dsh, как если бы вы использовали ssh для запуска команд на них.
dsh -a /path/to/some/command/or/script
Он запустит команду на всех машинах одновременно и вернет вывод с префиксом имени хоста. Команда или сценарий должны присутствовать в системе, поэтому общий каталог NFS может быть полезен для такого рода вещей.
Создает команду hostname ssh для всех машин, к которым получен доступ. по Quierati 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) , который позволяет выполнять сценарии в нескольких Unix / Linux хосты одним нажатием кнопки. Это настольное приложение с графическим интерфейсом, которое работает на Mac и Windows, но также есть и клиент командной строки для командной строки.
Вы можете создавать пакетные задания и повторно использовать их на нескольких хостах.
Требуется Java 1.6 или выше.
Хотя это сложная тема, я настоятельно рекомендую Capistrano .
Я не уверен, что этот метод будет работать для всего, что вы хотите, но вы можете попробовать что-то вроде этого:
$ cat your_script.sh | ssh your_host bash
Который будет запускать скрипт (который находится локально) на удаленном сервере.
Multixterm отлично подходит для этого и позволяет легко поставить 1 из n Машина снова в последовательности. Р>
Просто прочитайте новый блог используя 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.