it-swarm.cn

在许多服务器上通过SSH自动运行命令

.txt文件中有一个IP地址列表,例如:

1.1.1.1
2.2.2.2
3.3.3.3

每个IP地址的后面都有一个服务器,并且每个服务器上的端口22上都运行着一个sshd。并不是每个服务器都在known_hosts列表中(在我的电脑上,Ubuntu 10.04 LTS/bash)。

如何在这些服务器上运行命令并收集输出?

理想情况下,我想在所有服务器上并行运行命令。

我将在所有服务器上使用公钥身份验证。

以下是一些潜在的陷阱:

  • Ssh提示我将给定的服务器ssh密钥放入我的known_hosts文件中。
  • 给定的命令可能返回非零退出代码,指示输出可能无效。我需要认识到这一点。
  • 例如,由于网络错误,可能无法建立到给定服务器的连接。
  • 如果命令的运行时间比预期的长,或者服务器在运行命令时关闭,则应该有一个超时时间。

服务器是AIX/ksh(但我认为那并不重要。

47
LanceBaynes

假设您无法安装pssh或其他产品,则可以执行以下操作:

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"
15
Arcege

有几种工具可让您同时登录多台计算机并在其中执行一系列命令。这是一对:

62
Caleb

如果您比--bash脚本更多地使用 Python 脚本,那么 Fabric 可能是适合您的工具。

Fabric主页

Fabric是Python(2.5或更高版本))和命令行工具,用于简化SSH在应用程序部署或系统管理任务中的使用。

它提供了用于执行本地或远程Shell命令(通常或通过Sudo)和上载/下载文件的基本操作套件,以及诸如提示正在运行的用户进行输入或中止执行等辅助功能。

典型的用法是创建一个Python)包含一个或多个函数的模块,然后通过fab命令行工具执行它们。

18
Riccardo Murri

我为此使用 GNU parallel ,最具体地说,您可以使用 this 配方:

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

your.txt是具有服务器IP地址/名称的文件。

11
Anthon

基本设置:

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

使用名称/密码进行身份验证确实不是一个好主意。您应该为此设置一个私钥:

ssh-keygen && for Host in $(cat hosts.txt); do ssh-copy-id $Host; done
8
michas

我建议 Ansible.cc 。它是配置管理器和命令调度程序。

4
Tom

Hypertable 项目最近添加了一个多主机ssh工具。此工具是使用libssh构建的,可建立连接并发出命令异步in parallel,以实现最大的并行度。有关完整的文档,请参见 多主机SSH工具 。要在一组主机上运行命令,请按以下方式运行它:

$ ht ssh 1.1.1.1,2.2.2.2,3.3.3.3 uptime

您还可以指定主机名或IP模式,例如:

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

它还支持--random-start-delay <millis>选项,该选项将在每个主机上将命令的启动延迟0到<millis>毫秒之间的随机时间间隔。当运行的命令访问中央资源时,可以使用此选项来避免出现雷电群问题。

2
Doug judd

我认为您正在寻找 pssh 以及通常的scp,rsync等的相关并行版本。

2
unclejamil

我构建了一个名为 Overcast 的开源工具,以简化此类操作。

首先,定义服务器:

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

然后,您可以依次或并行运行多个命令和脚本文件,如下所示:

overcast run vm.* uptime "free -m" /path/to/script --parallel
2
Andrew Childs

我已经开发了 collectnode 非常简单有效,可以在多个服务器(包括Windows)中执行任务

如何使用CollectNode:

  1. 创建服务器列表,以使用:

    # cat hosts.file
    server1
    server2
    server3
    server4
    server5
    
  2. 执行CollectNode传递服务列表:

    collectnode --file servers.txt --command='cat /etc/httpd/conf/httpd.conf |grep ^User'
    
  3. 最佳地,可以过滤结果,例如,此命令仅显示满足条件的服务器。

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

https://collectnode.com/5-tasks-collectnode-can-help-managing-servers/

2
fvidalmolina

只是一个关于一个很好的问题的提示:

我发现的最好的解决方案是tmux,这并不奇怪。

您可以执行Ctrl-B:setw在tmux中进行同步窗格以实现惊人的结果。为此,您必须在Tmux的1个窗口的不同窗格中打开所有ssh连接。

1
Mikhail Krutov

我认为“期望”是您所需要的。
许多人甚至都不知道它的存在。这是一个基于tcl的程序,它将代表您提出问题和可能的答案。看看 https://wiki.tcl-lang.org/page/Expect

0
Clement

创建一个文件/ etc/sxx/hosts

像这样填充:

[grp_ips]
1.1.1.1
2.2.2.2
3.3.3.3

在所有计算机上共享ssh密钥。

从软件包安装sxx:

https://github.com/ericcurtin/sxx/releases

然后像这样运行命令:

sxx [email protected]_ips "whatever bash command"
0
ericcurtin

也许这样的事情可以在多个主机上运行命令吗?假设所有主机都在.ssh/config中设置为无密码登录。

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

0
Y0NG

使用Paramiko http://www.paramiko.org/ 和基于线程的并行性 https://docs.python.org/3/library/threading.html 。代码允许在每个服务器上并行执行多个命令!

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()

注意:对每台服务器重复以上说明。

0
Sharma