Como posso automatizar executando comandos remotamente por SSH para vários servidores em paralelo?

StackOverflow https://stackoverflow.com/questions/243750

  •  04-07-2019
  •  | 
  •  

Pergunta

Eu procurei em torno de um bocado para perguntas semelhantes, mas diferente do que correr um comando ou talvez um comando poucos com itens como:

ssh user@host -t sudo su -

No entanto, o que se eu basicamente precisa executar um script em (digamos de LET) 15 servidores ao mesmo tempo. É este factível em bash? Em um mundo perfeito eu preciso para evitar a instalação de aplicativos, se possível para puxar esta off. Por causa do argumento, vamos apenas dizer que eu preciso fazer o seguinte em 10 exércitos:

  1. Implantar um novo recipiente Tomcat
  2. implantar um aplicativo no recipiente, e configurá-lo
  3. Configurar um Apache vhost
  4. Recarregar Apache

Eu tenho um script que faz tudo isso, mas depende de mim fazer login em todos os servidores, puxando um script para baixo de um repo, e depois executá-lo. Se isto não é factível em bash, que alternativas você sugere? Preciso de um martelo maior, como Perl (Python pode ser preferido desde que eu posso garantir Python é em todas as caixas em um ambiente RHEL graças a yum / up2date)? Se alguém pode apontar-me a qualquer informação útil seria muito apreciada, especialmente se é factível em bash. Eu vou resolver para Perl ou Python, mas eu só não sei as também (trabalhando nisso). Obrigado!

Foi útil?

Solução

Muitas vezes, eu só vou usar a versão original Tcl de esperar. Você só precisa ter essa na máquina local. Se eu estou dentro de um programa usando Perl, eu faço isto com Net :: SSH :: esperar . Outras línguas têm similar "esperar" ferramentas.

Outras dicas

Você pode executar um script local como mostrado por che e Yang, e / ou você pode usar um documento aqui:

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 

A questão de como executar comandos em vários servidores ao mesmo tempo surgiu em uma lista Perl no outro dia e eu vou dar a mesma recomendação Eu dei lá , que é a utilização gsh:

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

GSH é semelhante à solução "for box in box1_name box2_name box3_name" dada mas acho GSH a ser mais conveniente. Você configurar um arquivo / etc / fantasmas contendo os servidores em grupos tais como web, db, RHEL4, x86_64, ou qualquer outra coisa (homem fantasmas), então você usar esse grupo quando você chamar 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 ~]$

Você também pode combinar ou grupos de fantasmas de divisão, usando web + db ou web-RHEL4, por exemplo.

Eu também vou mencionar que, embora eu nunca usei shmux, seu site contém uma lista de software (incluindo GSH) que permite executar comandos em vários servidores ao mesmo tempo. Capistrano já foi mencionado e (pelo que entendi) poderia estar nessa lista também.

Dê uma olhada em esperar (man expect)

Eu tenho feito tarefas semelhantes no passado usando Espere.

Você pode canalizar o script local para o servidor remoto e executá-lo com um comando:

ssh -t user@host 'sh' < path_to_script

Isto pode ser ainda mais automatizado usando autenticação de chave pública e envolvimento com scripts para executar a execução paralela.

Você pode tentar paramiko . É um cliente ssh puro-python. Você pode programar suas sessões SSH. Nada a instalar em máquinas remotas.

Veja este ótimo artigo sobre como usá-lo.

Para dar-lhe a estrutura, sem código real.

  1. Use scp para copiar o script de instalação / configuração para a caixa alvo.
  2. Use ssh para chamar o script na caixa remoto.

phsss pode ser interessante uma vez que, ao contrário da maioria das soluções mencionadas aqui, os comandos são executados em paralelo .

(Para meu próprio uso, eu escrevi um pequeno script simples muito semelhante à própria GavinCattell, é documentado aqui -. em francês )

Você já olhou para coisas como Puppet ou Cfengine . Eles podem fazer o que quiser e provavelmente muito mais.

Para aqueles que tropeçar através desta pergunta, eu vou incluir uma resposta que usos Tecido , que resolve exatamente o problema descrito acima:. Executar comandos arbitrários em vários hosts sobre ssh

Uma vez que tecido é instalado, você criar um fabfile.py, e implementar tarefas que pode ser executado em seus hosts remotos. Por exemplo, uma tarefa a Recarregar Apache pode ter esta aparência:

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 Então, em sua máquina local, correr e o comando sudo /etc/init.d/apache2 reload iria se executar em todos os hosts especificados no env.hosts.

Você pode fazê-lo da mesma forma que fez antes, apenas escrevê-lo em vez de fazê-lo manualmente. Os seguintes controles remotos código a máquina chamada 'loca' e corre dois comandos. O que você precisa fazer é simplesmente inserir comandos que você deseja executar lá.

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

Então, para percorrer todas as máquinas, fazer algo como:

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

A fim de fazer isso ssh coisa trabalho sem digitar senhas o tempo todo, você precisa configurar a autenticação de chave. Você pode ler sobre ele em IBM developerWorks .

Você pode executar o mesmo comando em vários servidores ao mesmo tempo com uma ferramenta como aglomerado ssh . O link é para uma discussão sobre ssh cluster no pacote Debian do dia blog.

Bem, para o passo 1 e 2 não existe uma interface de gerenciamento web tomcat; você poderia script que com a onda ou zsh com o plug libwww em.

Para SSH você está olhando para: 1) não se for solicitada uma senha (use as teclas) 2) passar o comando (s) na linha de comando do SSH, este é semelhante ao rsh em uma rede confiável.

Outras mensagens têm mostrado o que fazer, e eu provavelmente usaria sh também, mas eu ficaria tentado a utilização perl como ssh tomcatuser@server perl -e 'do-everything-on-one-line;' ou você poderia fazer isso:

qualquer scp the_package.tbz tomcatuser@server:the_place/.
ssh tomcatuser@server /bin/sh <<\EOF
definir coisas como TOMCAT_WEBAPPS=/usr/local/share/tomcat/webapps
tar xj the_package.tbz ou 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 [você normalmente não é necessário reiniciar tomcat]
mv $THE_PLACE/vhost_file $APACHE_VHOST_DIR/vhost_file
$APACHECTL restart [ser necessário fazer login como apache usuário mover o arquivo e reiniciar]
EOF

Você quer DSH ou distributed shell, que é usado em aglomerados muito. Aqui está o link: dsh

Você tem basicamente grupos de nós (um arquivo com listas de nós em-los) e você especificar qual grupo nó que você deseja executar comandos em seguida, você usaria dsh, como se fosse ssh para executar comandos sobre eles.

dsh -a /path/to/some/command/or/script

Ele será executado o comando em todas as máquinas ao mesmo tempo e retorna a saída prefixado com o nome do host. O comando ou script tem de estar presente no sistema, de modo que um diretório NFS compartilhado pode ser útil para esses tipos de coisas.

Cria hostname comando ssh de todas as máquinas acessados. por 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 Executar:

$for i in hostname{1..10}; do $i who;done

Há uma ferramenta chamada Flatt (flexível Automação e Solução de Problemas Tool) que lhe permite executar scripts em múltiplos Unix / Linux hosts com um clique de um botão. É um aplicativo GUI desktop que roda em Mac e Windows, mas há também um cliente de linha de comando java.
Você pode criar trabalhos em lote e reutilização em vários hosts.
Requer Java 1.6 ou superior.

Embora seja um tema complexo, recomendo Capistrano .

Eu não tenho certeza se este método irá funcionar para tudo o que quiser, mas você pode tentar algo como isto:

$ cat your_script.sh | ssh your_host bash

O que irá executar o script (que reside no local) no servidor remoto.

Multixterm é legal para fazer isso, e permite que você fez facilmente o 1 de n volta máquina em sequência.

Basta ler um novo usando setsid sem qualquer outra instalação / configuração além do kernel do mainstream. Testado / Verificado sob Ubuntu14.04.

Enquanto o autor tem uma explicação muito clara e código de exemplo, bem, aqui é a parte mágica para uma rápida olhada:

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

Aqui está um script para fazer um comando SSH em várias máquinas, pode ajudar:

#!/bin/bash
MACHINES="machine1 machine2 machine3 machine4 machine5 machine6"
for m in $MACHINES
do
        cmd="ssh $m '$*'"
        eval $cmd
done

Você pode até mesmo colocar isso por isso é no seu caminho, chamá-lo de algo como sshAll, em seguida, basta digitar o comando sshAll.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top