获取多台主机命令执行结果

前端之家收集整理的这篇文章主要介绍了获取多台主机命令执行结果前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

之前在主产品用过一个运维同事写的工具,devpssh。可以通过指定主机列表来执行一条shell命令,然后获取到所有的返回结果,输出到屏幕上。

我个人觉得这个工具很实用,尤其是在有多台Nginx服务器的时候,由于负载均衡策略下,不同的请求可能会被下放到不同的get机,因此产生的日志文件就可能分布在多台机器上。如果我们一个个地到每台get机上去执行shell语句。首先工作量会很大,另外获取到的结果也不容易整理。而此时用一下devpssh,就没有这些负担了。

在正式介绍如何写一个这样的工具之前,先来看看需要哪些基础的知识。

  • 主机间信任
  • shell脚本

主机间信任

说到主机之间的信任,还是要将历史往前追溯一下。谈谈SSH。简单来说SSH是一种网络协议,用于计算机之间的加密登录。之所以是加密登录就是应为原始的用户远程登录是明文的,一旦被截获,信息就泄露了。

SSH是协议,具体有很多实现。有商业实现的,也有开源实现。不过大致来看,用法是一致的。

先来看看安装了ssh的机器有什么不同吧。

id_rsa是使用RSA算法得到的私钥
id_rsa.pub是对称的RSA算法得到的公钥。
了解过对称加密算法的应该都知道,妥善保存好私钥是一件很重要的事情。

一般来说,第一次使用ssh登录到远程主机的时候,会有如下提示信息:

The authenticity of host 'host (12.18.429.21)' can't be established.
  RSA key fingerprint is 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d.
  Are you sure you want to continue connecting (yes/no)?

这段话的大致意思是说,无法确认你即将登录的远程主机的真实性,但是可以了解的就只有它的公钥指纹,如果确定要进行连接,选择yes即可。
然后会出现如下字样:

  Warning: Permanently added 'host,12.18.429.21' (RSA) to the list of known hosts.

然后ssh会提示你使用密码进行登录了。正确输入密码后,就可以正常的登录了。这个时候,其实远程主机的公钥就被保存到了~/.ssh/known_hosts文件中了。内容如下:

其中每一行都代表了一个曾经成功连接过的远程主机的公钥信息。

但是每次远程登录都需要输入一遍密码,感觉次数多了,总是感觉有点麻烦。而ssh也支持使用公钥进行登录,这样就省去了每次登陆都要输入一遍密码的步骤了。

具体的做法如下:
将自己的电脑的公钥发送到目标主机的.ssh/authorized_keys中,这样登录的时候ssh协议通过对称加密,解密的验证过程,就可以实现公钥登录了。

这个对称加密,解密大致有这么个流程。
- 本地主机使用ssh进行远程登录
- 远程主机借助authorized_keys里面本地主机的信息生成一个随机字符串发给本地主机
- 本地主机用自己的私钥将这个字符串进行加密,发给远程主机。
- 远程主机使用本地主机的公钥进行 解密,如果成功,身份验证也就通过了。

最后来一个小总结:
- known_hosts里面是已经成功远程登录的主机的公钥信息。

- authenrized_keys是已经授权的,可以免密码登录到本机的“主机”的公钥信息。

公钥免密登录也会是待会主机间的信任的基础。再来回顾下需求,我要在某一台主机上执行一条命令,然后获取全部的get机上相对应的内容。那么这台主机就可以作为master。

在master上,将通过ssh-keygen命令生成的公钥发送到要进行远程登录的get机的.ssh/authenrized_keys中。
比如:
master机器为192.168.30.100
get机列表是:
192.168.32.102
192.168.32.105
192.168.32.109
192.168.32.110
我们就可以依次将100的公钥使用SCP命令或者其他的上传工具,上传到对应的get机的authenrized_keys文件中。

ssh-keygen -t rsa //此处一路回车,生成秘钥

scp .ssh/id_rsa.pub 192.168.32.102:~/ //把秘钥拷贝到其他远程机器

ssh 192.168.30.102 ‘cat id_rsa.pub >> .ssh/authorized_keys’ //(远程执行命令)在远程机器上生成认证文件

这样,将master的公钥就成功的添加到102这台get机上了。其他的get机就可以按照同样的方法做下处理。处理完之后,就可以使用公钥进行免密码登录到远程主机了。

至此,主机间的信任就算结束了。


shell脚本编写

目标需求是获取所有get机上执行的shell命令,并进行整合输出。我在网上找了一个shell脚本,大致的内容如下:

#!/usr/bin bash
docommand()
{
    hosts=`sed -n '/^[^#]/p' hostlist`
    for host in $hosts
        do
            echo "" # 换个行
            ssh $host "$@"
        done
    return 0
}
if [ $# -lt 1  ]
then
    echo "$0 cmd"
    exit
fi
docommand "$@"

然后需要在同级目录下创建一个get主机列表。

192.168.32.102
192.168.32.105
192.168.32.109
192.168.32.110

然后懒得输入bash前缀来执行命令的话,就可以写一个alias了在~/.bashrc 文件末尾添加如下内容

alias devpssh='bash /home/developer/runcommand.sh'

然后*source ~/.bashrc

这样就可以通过如下格式,来批量在主机之间执行shell命令了,具体的格式如下:

devpssh 'cat /var/log/Nginx/api_acces.log | grep curuserid=2614677 | tail -1'

至此,在多台主机之间执行shell命令也就得以实现了。


总结

本次内容比较少,单纯的了解了下ssh的一些相关知识点。然后是利用公钥免密登录并执行相关的shell命令。

麻雀虽小,但是却很实用。

猜你在找的Bash相关文章