Executa automaticamente comandos por SSH em muitos servidores

42

Existe uma lista de endereços IP em um arquivo .txt, por exemplo:

1.1.1.1
2.2.2.2
3.3.3.3

Por trás de cada endereço IP existe um servidor, e em cada servidor há um sshd rodando na porta 22. Nem todo servidor está na lista known_hosts (no meu PC, Ubuntu 10.04 LTS / bash).

Como posso executar comandos nesses servidores e coletar a saída?

Idealmente, gostaria de executar os comandos em paralelo em todos os servidores.

Eu usarei a autenticação de chave pública em todos os servidores.

Aqui estão algumas possíveis armadilhas:

  • O ssh solicita que eu coloque a chave ssh do servidor em questão no meu arquivo known_hosts .
  • Os comandos fornecidos podem retornar um código de saída diferente de zero, indicando que a saída é potencialmente inválida. Eu preciso reconhecer isso.
  • Uma conexão pode não ser estabelecida em um determinado servidor, por exemplo, devido a um erro de rede.
  • Deve haver um tempo limite, caso o comando seja executado por mais tempo do que o esperado ou o servidor fique inativo durante a execução do comando.

Os servidores são AIX / ksh (mas acho que isso não importa realmente.

    
por LanceBaynes 19.08.2011 / 14:40

14 respostas

14

Supondo que você não consiga instalar o pssh ou outros, você pode fazer algo semelhante a:

tmpdir=${TMPDIR:-/tmp}/pssh.$$
mkdir -p $tmpdir
count=0
while IFS= read -r userhost; do
    ssh -n -o BatchMode=yes ${userhost} 'uname -a' > ${tmpdir}/${userhost} 2>&1 &
    count='expr $count + 1'
done < userhost.lst
while [ $count -gt 0 ]; do
    wait $pids
    count='expr $count - 1'
done
echo "Output for hosts are in $tmpdir"
    
por 19.08.2011 / 16:55
59

Existem várias ferramentas que permitem que você faça login e execute séries de comandos em várias máquinas ao mesmo tempo. Aqui está um casal:

por 19.08.2011 / 15:10
16

Se você gosta de scripts Python mais do que bash scripting, então Tecido pode ser o ferramenta para você.

Na página inicial do Fabric :

Fabric is a Python (2.5 or higher) library and command-line tool for streamlining the use of SSH for application deployment or systems administration tasks.

It provides a basic suite of operations for executing local or remote shell commands (normally or via sudo) and uploading/downloading files, as well as auxiliary functionality such as prompting the running user for input, or aborting execution.

Typical use involves creating a Python module containing one or more functions, then executing them via the fab command-line tool.

    
por 19.08.2011 / 15:16
11

Eu uso o paralelo GNU para isso, mais especificamente você pode usar esta receita:

parallel --tag --nonall --slf your.txt command

Com your.txt sendo o arquivo com o endereço IP do servidor / nomes.

    
por 23.05.2013 / 06:45
8

Configuração muito básica:

for host in $(cat hosts.txt); do ssh "$host" "$command" >"output.$host"; done

Autenticar com nome / senha não é uma boa ideia. Você deve configurar uma chave privada para isso:

ssh-keygen && for host in $(cat hosts.txt); do ssh-copy-id $host; done
    
por 23.05.2013 / 09:00
4

Sugiro Ansible.cc . É um gerenciador de configuração e um dispatcher de comandos.

    
por 27.05.2013 / 13:33
2

Desenvolvi collectnode Muito simples e eficaz para executar tarefas em vários servidores (incluindo janelas)

Como usar o CollectNode:

  1. Crie a lista de servidores para trabalhar com:

    # cat hosts.file
    server1
    server2
    server3
    server4
    server5
    
  2. Execute o CollectNode passando a lista de servidores:

    collectnode --file servers.txt --command='cat /etc/httpd/conf/httpd.conf |grep ^User'
    
  3. Opcionalmente, é possível filtrar os resultados, por exemplo, este comando só exibe o servidor onde a condição é realizada.

    collectnode --file servers.txt --command='cat /etc/httpd/conf/httpd.conf |grep ^User' --where="command contain User"
    

link

    
por 27.02.2018 / 15:07
2

Eu acho que você está procurando por pssh e as versões paralelas relacionadas ao scp usual, rsync, etc.

    
por 19.08.2011 / 15:08
2

Eu criei uma ferramenta de código aberto chamada Overcast para facilitar esse tipo de coisa.

Primeiro você define seus servidores:

overcast import vm.01 --ip 1.1.1.1 --ssh-key /path/to/key
overcast import vm.02 --ip 2.2.2.2 --ssh-key /path/to/key

Em seguida, você pode executar vários comandos e arquivos de script entre eles, sequencialmente ou em paralelo, assim:

overcast run vm.* uptime "free -m" /path/to/script --parallel
    
por 10.05.2014 / 22:56
2

O projeto Hypertable adicionou recentemente uma ferramenta ssh de vários hosts. Esta ferramenta é construída com libssh e estabelece conexões e emite comandos assíncrona e em paralelo para o paralelismo máximo. Consulte a Ferramenta SSH de vários hosts para obter a documentação completa. Para executar um comando em um conjunto de hosts, você o executaria da seguinte maneira:

$ ht ssh 1.1.1.1,2.2.2.2,3.3.3.3 uptime

Você também pode especificar um nome de host ou um padrão de IP, por exemplo:

$ ht ssh 1.1.1.[1-99] uptime
$ ht ssh host[00-99] uptime

Ele também suporta uma opção --random-start-delay <millis> que atrasará o início do comando em cada host por um intervalo de tempo aleatório entre 0 e <millis> milissegundos. Esta opção pode ser usada para evitar problemas de rebanho quando o comando que está sendo executado acessa um recurso central.

    
por 04.12.2014 / 22:13
1

Apenas um heads-up para uma pergunta muito legal:

A melhor solução que encontrei é, não tão surpreendentemente, o tmux.

Você pode fazer Ctrl-B: setw sincronizar painéis no tmux para obter resultados incríveis. Você deve ter todas as suas conexões ssh abertas, em diferentes painéis de 1 janela do Tmux para isso.

    
por 18.01.2016 / 02:59
0

Talvez algo como isso funcione, para executar o comando em vários hosts? suponha que todos os hosts estejam configurados em .ssh / config para login sem senha.

$ < hosts.txt xargs -I {} ssh {} command

    
por 13.02.2018 / 08:58
0

Crie um arquivo / etc / sxx / hosts

preencha assim:

[grp_ips]
1.1.1.1
2.2.2.2
3.3.3.3

compartilhe a chave ssh em todas as máquinas.

Instale sxx do pacote:

link

Em seguida, execute o comando da seguinte forma:

sxx username@grp_ips "whatever bash command"
    
por 20.03.2018 / 23:31
0

Use o link e o paralelismo baseado em threads link .below code permite executar vários comandos em cada servidor em paralelo!

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.load_system_host_keys()
ssh.connect(hostname, port, username, password)
t = threading.Thread(target=tasks[index], args=(ssh, box_ip,))
t.start()

Nota: repita as instruções acima para cada servidor.

    
por 24.10.2018 / 15:28