2008-10-28 12 views
14

He buscado todo un poco para preguntas similares, pero aparte de ejecutar un comando o quizás unos pocos comandos con elementos tales como:¿Cómo puedo automatizar la ejecución de comandos de forma remota a través de SSH a varios servidores en paralelo?

ssh [email protected] -t sudo su - 

Sin embargo, ¿qué pasaría si en esencia se necesita para ejecutar un script en (vamos decir) 15 servidores a la vez. ¿Es esto factible en bash? En un mundo perfecto, debo evitar instalar aplicaciones si es posible para lograr esto. Pongamos por caso, vamos a decir que tengo que hacer lo siguiente a través de 10 anfitriones:

  1. desplegar un nuevo contenedor Tomcat
  2. desplegar una aplicación en el contenedor, y configurarlo
  3. configurar un host virtual Apache
  4. Actualizar Apache

tengo un script que hace todo eso, pero depende de abrir sesión en todos los servidores, tirando de un guión abajo de un acuerdo de recompra, y luego ejecutarlo. Si esto no es factible en bash, ¿qué alternativas sugieres? ¿Necesito un martillo más grande, como Perl (es posible que se prefiera Python ya que puedo garantizar que Python está en todas las cajas en un entorno RHEL gracias a yum/up2date)? Si alguien puede señalarme cualquier información útil, sería muy apreciado, especialmente si es factible en bash. Me conformaré con Perl o Python, pero simplemente no los conozco (trabajando en eso). ¡Gracias!

+0

Uso 'sudo -sH' en lugar de' sudo su -'. – Zenexer

+0

¿Se está preguntando cómo ejecutar múltiples líneas de forma remota o cómo ejecutar líneas "en paralelo" en varios hosts simultáneamente? Para el paralelo, consulte https://serverfault.com/a/875812/27813 – rogerdpack

Respuesta

8

A menudo, sólo voy a utilizar la versión original Tcl de esperar. Solo necesita tener eso en la máquina local. Si estoy dentro de un programa que usa Perl, hago esto con Net::SSH::Expect. Otros idiomas tienen herramientas similares de "esperar".

+3

Fuimos por esta ruta. Gracias por la sugerencia (y la edición). Otro tenía buenas ideas, pero estoy buscando ejecutar un script de 300 líneas. Perl aporta un poco de "elegancia" a ese bash no proporcionará. (Perl .. elegancia ... nunca pensé que diría eso) :) – f4nt

+3

Si lo haces perl derecho, puede ser agradable;) – Johan

3

Para darle la estructura, sin código real.

  1. Use scp para copiar su script de instalación/instalación en el cuadro de destino.
  2. Use ssh para invocar su script en el cuadro remoto.
+0

Eso podría tener que funcionar al final. Esperaba algo un poco más lindo que eso. Al final, eso realmente solo corta la extracción del guión de la subversión, y la exportación de un script bash es una pérdida de tiempo mínima. – f4nt

+0

Puede usar un solo script para hacer todo eso automáticamente. Sin tener que escribir todos los comandos, en caso de que no fuera claro, f4nt –

1

Aunque es un tema complejo, recomiendo encarecidamente Capistrano.

-2

Aquí es un script para hacer un comando SSH en varios equipos, puede ayudar:

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

Incluso se puede poner esto por lo que es en su camino, lo llaman algo así como sshAll, a continuación, sólo tiene que escribir comandos sshAll.

1

Puede hacerlo de la misma manera que antes, simplemente scripts en lugar de hacerlo manualmente. El siguiente código se remueve a la máquina llamada 'loca' y ejecuta dos comandos allí. Lo que debe hacer es simplemente insertar los comandos que desea ejecutar allí.

[email protected] ~ $ ssh loca 'uname -a; echo something_else' 
Linux loca 2.6.25.9 #1 (blahblahblah) 
something_else

Entonces, para recorrer todas las máquinas, hacer algo como:

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

Con el fin de hacer que esto ssh trabajo sin necesidad de introducir contraseñas todo el tiempo, tendrá que configurar clave autenticación. Puede leer sobre esto al IBM developerworks.

+0

Esto no los ejecuta en paralelo de manera desafortunada (aunque podría agregar un '&' al final del comando ssh y un 'wait' en el fondo y se ejecutarían en paralelo :) – rogerdpack

1

Puede ejecutar el mismo comando en varios servidores a la vez con una herramienta como cluster ssh. El enlace es una discusión de clúster ssh en el paquete Debian del blog del día.

6

Tome un vistazo a tareas similares esperan (man expect)

que he logrado en el pasado el uso de esperar.

4

Puede canalizar el guión local al servidor remoto y ejecutarlo con un comando:

ssh -t [email protected] 'sh' < path_to_script 

Esto se puede automatizar aún más mediante el uso de la autenticación de clave pública y la envoltura con las secuencias de comandos para llevar a cabo la ejecución en paralelo.

11

puede ejecutar un script local, como se muestra por el Che y el Yang, y/o se puede utilizar una Aquí documento:

ssh [email protected] /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 
1

Bueno, para los pasos 1 y 2 no hay una interfaz web de tomcat manager; usted podría script que con el enrollamiento o zsh con el tapón libwww en

Para SSH lo que busca es:. 1) No te pida una contraseña (utilice las teclas) 2) pasar el comando (s) en el de SSH línea de comando, esto es similar al rsh en una red confiable.

Otros mensajes han demostrado lo que debe hacer, y probablemente haría uso de sh demasiado, pero me gustaría tener la tentación de utilizar perl como ssh [email protected] perl -e 'do-everything-on-one-line;' o se puede hacer esto:

ya seascp the_package.tbz [email protected]:the_place/.
ssh [email protected] /bin/sh <<\EOF
definen cosas comoTOMCAT_WEBAPPS=/usr/local/share/tomcat/webapps
tar xj the_package.tbzorsync 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 [normalmente no es necesario reiniciar Tomcat]
mv $THE_PLACE/vhost_file $APACHE_VHOST_DIR/vhost_file
$APACHECTL restart [podría tener que iniciar la sesión como usuario apache para mover ese archivo y reiniciar]
EOF

8

La cuestión de cómo ejecutar comandos en muchos servidores a la vez apareció en una lista de correo de Perl el otro día y daré la misma recomendación I gave there, que es usar gsh:

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

GSH es similar a la solución "for box in box1_name box2_name box3_name" already given pero me parece GSH a ser más conveniente. Usted configura un archivo/etc/ghosts que contiene sus servidores en grupos como web, db, RHEL4, x86_64 o lo que sea (fantasmas) y luego usa ese grupo cuando llama a gsh.

[[email protected] ~]$ 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 
[[email protected] ~]$ 

También puede combinar o dividir grupos fantasma, usando web + db o web-RHEL4, por ejemplo.

También mencionaré que, aunque nunca he usado shmux, its website contiene una lista de software (incluido gsh) que le permite ejecutar comandos en muchos servidores a la vez. Capistrano ya se ha mencionado y (según tengo entendido) podría estar en esa lista también.

+0

cómo usar gsh con comandos de varias líneas? –

1

Desea DSH o shell distribuido, que se utiliza mucho en clústeres. Aquí está el enlace: dsh

Básicamente tiene grupos de nodos (un archivo con listas de nodos en ellos) y especifica en qué grupo de nodos desea ejecutar comandos, entonces usaría dsh, como lo haría con ssh para ejecutar comandos en ellos.

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

Ejecutará el comando en todas las máquinas al mismo tiempo y devolverá la salida prefijada con el nombre de host. El comando o script debe estar presente en el sistema, por lo que un directorio NFS compartido puede ser útil para este tipo de cosas.

0

no estoy seguro de si este método funcionará para todo lo que desea, pero se puede intentar algo como esto:

$ cat your_script.sh | ssh your_host bash 

la que se ejecutará la secuencia de comandos (que reside localmente) en el servidor remoto.

2

pssh puede ser interesante ya que, a diferencia de la mayoría de las soluciones mencionadas aquí, los comandos se ejecutan en paralelo.

(Para mi propio uso, escribí un pequeño script más simple muy similar al de GavinCattell, es documented here - in french).

2

¿Has visto cosas como Puppet o Cfengine? Pueden hacer lo que quieran y probablemente mucho más.

4

Puedes probar paramiko. Es un cliente ssh puro-python. Puedes programar tus sesiones ssh. Nada para instalar en máquinas remotas.

Consulte esto great article sobre cómo usarlo.

0

Multixterm es genial para hacer esto, y le permite volver a colocar fácilmente la máquina 1 de n en secuencia.

2

Para aquellos que tropiezan con esta pregunta, incluiré una respuesta que usa Fabric, que resuelve exactamente el problema descrito anteriormente: Ejecutar comandos arbitrarios en varios hosts a través de ssh.

Una vez que se instala la tela, debe crear un fabfile.py e implementar las tareas que se pueden ejecutar en los hosts remotos. Por ejemplo, una tarea a Actualizar Apache podría tener este aspecto:

from fabric.api import env, run 

env.hosts = ['[email protected]', '[email protected]'] 

def reload(): 
    """ Reload Apache """ 
    run("sudo /etc/init.d/apache2 reload") 

A continuación, en el equipo local, ejecute el comando fab reload y sudo /etc/init.d/apache2 reload conseguiría ejecutar en todos los hosts especificados en env.hosts.

1

Crea el nombre de host comando ssh de todas las máquinas a las que se tiene acceso. 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 Ejecutar:

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

Hay una herramienta llamada FLATT (FLexible Automation and Troubleshooting Tool) que le permite ejecutar secuencias de comandos en varios Unix/Linux acoge con un clic de un botón. Es una aplicación de GUI de escritorio que se ejecuta en Mac y Windows pero también hay un cliente de línea de comando java.
Puede crear trabajos por lotes y reutilizar en varios hosts.
Requiere Java 1.6 o superior.

0

Acaba de leer un nuevo blog usando setsid sin ninguna instalación/configuración adicional además del kernel principal. Probado/verificado bajo Ubuntu14.04.

Mientras que el autor tiene un código de explicación y muestra muy claro, así, esta es la parte mágica para un rápido vistazo:

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