以前在主产品用过一个运维同事写的工具,devpssh。能够经过指定主机列表来执行一条shell命令,而后获取到全部的返回结果,输出到屏幕上。nginx
我我的以为这个工具很实用,尤为是在有多台Nginx服务器的时候,因为负载均衡策略下,不一样的请求可能会被下放到不一样的get机,所以产生的日志文件就可能分布在多台机器上。若是咱们一个个地到每台get机上去执行shell语句。首先工做量会很大,另外获取到的结果也不容易整理。而此时用一下devpssh,就没有这些负担了。算法
在正式介绍如何写一个这样的工具以前,先来看看须要哪些基础的知识。shell
说到主机之间的信任,仍是要将历史往前追溯一下。谈谈SSH。简单来讲SSH是一种网络协议,用于计算机之间的加密登陆。之因此是加密登陆就是应为原始的用户远程登陆是明文的,一旦被截获,信息就泄露了。api
SSH是协议,具体有不少实现。有商业实现的,也有开源实现。不过大体来看,用法是一致的。bash
先来看看安装了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也支持使用公钥进行登陆,这样就省去了每次登录都要输入一遍密码的步骤了。
具体的作法以下: 将本身的电脑的公钥发送到目标主机的.ssh/authorized_keys中,这样登陆的时候ssh协议经过对称加密,解密的验证过程,就能够实现公钥登陆了。
这个对称加密,解密大体有这么个流程。
最后来一个小总结:
公钥免密登陆也会是待会主机间的信任的基础。再来回顾下需求,我要在某一台主机上执行一条命令,而后获取所有的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机就能够按照一样的方法作下处理。处理完以后,就可使用公钥进行免密码登陆到远程主机了。
至此,主机间的信任就算结束了。
目标需求是获取全部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命令。
麻雀虽小,可是却很实用。