bash - script - ssh comando en linux
¿Cómo puedo automatizar la ejecución de comandos de forma remota a través de SSH a varios servidores en paralelo? (21)
¿Has visto cosas como Puppet o Cfengine ? Pueden hacer lo que quieran y probablemente mucho más.
He buscado un poco por preguntas similares, pero aparte de ejecutar un comando o tal vez algunos comandos con elementos tales como:
ssh user@host -t sudo su -
Sin embargo, ¿qué pasa si esencialmente necesito ejecutar un script en (digamos) 15 servidores a la vez? ¿Es esto factible en bash? En un mundo perfecto, debo evitar instalar aplicaciones si es posible para lograr esto. Por el bien de los argumentos, digamos que necesito hacer lo siguiente en 10 hosts:
- Implementar un nuevo contenedor Tomcat
- Implemente una aplicación en el contenedor y configúrela
- Configurar un host de Apache
- Recargar Apache
Tengo un script que hace todo eso, pero depende de que inicie sesión en todos los servidores, retire un script de un repositorio y luego lo ejecute. 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!
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, está documentado aquí, en francés ).
A menudo, solo usaré la versión original de Tcl de Expect. 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".
Aquí hay una secuencia de comandos para hacer un comando SSH en varias máquinas, puede ayudar:
#!/bin/bash
MACHINES="machine1 machine2 machine3 machine4 machine5 machine6"
for m in $MACHINES
do
cmd="ssh $m ''$*''"
eval $cmd
done
Incluso podría poner esto para que esté en su camino, llámelo algo así como sshAll, luego simplemente escriba sshTodo el comando.
Bueno, para los pasos 1 y 2 no hay una interfaz web de administrador de tomcat; podrías escribir eso con curl o zsh con el plug-in de libwww.
Para SSH busca: 1) que no se le solicite una contraseña (use claves) 2) pase los comandos en la línea de comandos de SSH, esto es similar a rsh
en una red confiable.
Otras publicaciones te han mostrado qué hacer, y probablemente usaría sh
también, pero estaría tentado de usar perl
como ssh tomcatuser@server perl -e ''do-everything-on-one-line;''
o podrías hacer esto:
o bien scp the_package.tbz tomcatuser@server:the_place/.
ssh tomcatuser@server /bin/sh <</EOF
definir cosas como TOMCAT_WEBAPPS=/usr/local/share/tomcat/webapps
tar xj the_package.tbz
o 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
[normalmente no tienes que reiniciar tomcat]
mv $THE_PLACE/vhost_file $APACHE_VHOST_DIR/vhost_file
$APACHECTL restart
[puede necesitar iniciar sesión como usuario de apache para mover ese archivo y reiniciar]
EOF
Echa un vistazo a Esperar ( man expect
)
Realicé tareas similares en el pasado usando Esperar.
Para darle la estructura, sin código real.
- Use scp para copiar su script de instalación / instalación al cuadro de destino.
- Use ssh para invocar su script en el cuadro remoto.
Puede canalizar el script local al servidor remoto y ejecutarlo con un comando:
ssh -t user@host ''sh'' < path_to_script
Esto se puede automatizar aún más mediante el uso de la autenticación de clave pública y el ajuste con scripts para realizar la ejecución en paralelo.
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.
Puede ejecutar un script local como lo muestran che y Yang, y / o puede usar un documento aquí:
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
Puede hacerlo de la misma manera que antes, simplemente guiarlo 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í.
che@ovecka ~ $ ssh loca ''uname -a; echo something_else'' Linux loca 2.6.25.9 #1 (blahblahblah) something_else
Luego, para iterar a través de todas las máquinas, haga algo como:
for box in box1_name box2_name box3_name do ssh $box ''commmands_to_run_everywhere'' done
Para hacer que este ssh funcione sin ingresar contraseñas todo el tiempo, tendrás que configurar la autenticación de clave. Puede leer sobre esto en IBM developerworks .
Desea DSH o shell distribuido, que se usa 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 los comandos, entonces usaría dsh, como lo haría con ssh para ejecutar comandos sobre ellos.
dsh -a /path/to/some/command/or/script
Ejecutará el comando en todas las máquinas al mismo tiempo y devolverá la salida con el nombre de host prefijado. 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.
No estoy seguro de si este método funcionará para todo lo que desee, pero puede intentar algo como esto:
$ cat your_script.sh | ssh your_host bash
Que ejecutará la secuencia de comandos (que reside localmente) en el servidor remoto.
Puedes probar paramiko . Es un cliente ssh puro-python. Puedes programar tus sesiones ssh. Nada para instalar en máquinas remotas.
Vea este gran artículo sobre cómo usarlo.
Para aquellos que tropiecen 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 haya instalado fabric, creará un fabfile.py
e implementará tareas que se pueden ejecutar en sus hosts remotos. Por ejemplo, una tarea para Recargar Apache podría verse así:
from fabric.api import env, run
env.hosts = [''[email protected]'', ''[email protected]'']
def reload():
""" Reload Apache """
run("sudo /etc/init.d/apache2 reload")
Luego, en su máquina local, ejecute fab reload
y el comando sudo /etc/init.d/apache2 reload
se ejecutará en todos los hosts especificados en env.hosts
.
Crea el nombre de host del comando ssh de todas las máquinas a las que se accede. 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
Ejecutar Ex:
$for i in hostname{1..10}; do $i who;done
Multixterm es genial para hacer esto, y le permite volver a colocar fácilmente la máquina 1 de n en secuencia.
Existe una herramienta llamada FLATT (herramienta de automatización y solución de problemas FLexible) que le permite ejecutar scripts en múltiples hosts Unix / Linux 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.
Simplemente lea un blog nuevo usando setsid sin ninguna instalación / configuración adicional además del kernel mainstream. Probado / verificado bajo Ubuntu14.04.
Si bien el autor también tiene una explicación muy clara y un código de muestra, esta es la parte mágica para un vistazo rápido:
#----------------------------------------------------------------------
# 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"
Aunque es un tema complejo, puedo recomendar encarecidamente Capistrano .
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 le daré la misma recomendación que di allí , 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
" que ya se ha proporcionado, pero creo que gsh es 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.
[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 ~]$
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, su sitio web contiene una lista de software (incluido gsh) que le permite ejecutar comandos en muchos servidores a la vez. Capistrano ya ha sido mencionado y (por lo que yo sé) podría estar en esa lista también.