獲取多臺主機命令執(zhí)行結(jié)果

在多臺主機之間批量執(zhí)行shell語句的效果

之前在主產(chǎn)品用過一個運維同事寫的工具,devpssh??梢酝ㄟ^指定主機列表來執(zhí)行一條shell命令,然后獲取到所有的返回結(jié)果,輸出到屏幕上。

我個人覺得這個工具很實用,尤其是在有多臺Nginx服務(wù)器的時候,由于負載均衡策略下,不同的請求可能會被下放到不同的get機,因此產(chǎn)生的日志文件就可能分布在多臺機器上。如果我們一個個地到每臺get機上去執(zhí)行shell語句。首先工作量會很大,另外獲取到的結(jié)果也不容易整理。而此時用一下devpssh,就沒有這些負擔了。

在正式介紹如何寫一個這樣的工具之前,先來看看需要哪些基礎(chǔ)的知識。

  • 主機間信任
  • shell腳本

主機間信任

說到主機之間的信任,還是要將歷史往前追溯一下。談?wù)凷SH。簡單來說SSH是一種網(wǎng)絡(luò)協(xié)議,用于計算機之間的加密登錄。之所以是加密登錄就是應(yīng)為原始的用戶遠程登錄是明文的,一旦被截獲,信息就泄露了。

SSH是協(xié)議,具體有很多實現(xiàn)。有商業(yè)實現(xiàn)的,也有開源實現(xiàn)。不過大致來看,用法是一致的。

先來看看安裝了ssh的機器有什么不同吧。


執(zhí)行過ssh-keygen后

id_rsa是使用RSA算法得到的私鑰
id_rsa.pub是對稱的RSA算法得到的公鑰。
了解過對稱加密算法的應(yīng)該都知道,妥善保存好私鑰是一件很重要的事情。

一般來說,第一次使用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即可。
然后會出現(xiàn)如下字樣:

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

然后ssh會提示你使用密碼進行登錄了。正確輸入密碼后,就可以正常的登錄了。這個時候,其實遠程主機的公鑰就被保存到了~/.ssh/known_hosts文件中了。內(nèi)容如下:


known_hosts文件內(nèi)容

其中每一行都代表了一個曾經(jīng)成功連接過的遠程主機的公鑰信息。

但是每次遠程登錄都需要輸入一遍密碼,感覺次數(shù)多了,總是感覺有點麻煩。而ssh也支持使用公鑰進行登錄,這樣就省去了每次登陸都要輸入一遍密碼的步驟了。

具體的做法如下:
將自己的電腦的公鑰發(fā)送到目標主機的.ssh/authorized_keys中,這樣登錄的時候ssh協(xié)議通過對稱加密,解密的驗證過程,就可以實現(xiàn)公鑰登錄了。

這個對稱加密,解密大致有這么個流程。

  • 本地主機使用ssh進行遠程登錄
  • 遠程主機借助authorized_keys里面本地主機的信息生成一個隨機字符串發(fā)給本地主機
  • 本地主機用自己的私鑰將這個字符串進行加密,發(fā)給遠程主機。
  • 遠程主機使用本地主機的公鑰進行 解密,如果成功,身份驗證也就通過了。

最后來一個小總結(jié):

  • known_hosts里面是已經(jīng)成功遠程登錄過的主機的公鑰信息。
  • authenrized_keys是已經(jīng)授權(quán)的,可以免密碼登錄到本機的“主機”的公鑰信息。

公鑰免密登錄也會是待會主機間的信任的基礎(chǔ)。再來回顧下需求,我要在某一臺主機上執(zhí)行一條命令,然后獲取全部的get機上相對應(yīng)的內(nèi)容。那么這臺主機就可以作為master。

在master上,將通過ssh-keygen命令生成的公鑰發(fā)送到要進行遠程登錄的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命令或者其他的上傳工具,上傳到對應(yīng)的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’ //(遠程執(zhí)行命令)在遠程機器上生成認證文件

這樣,將master的公鑰就成功的添加到102這臺get機上了。其他的get機就可以按照同樣的方法做下處理。處理完之后,就可以使用公鑰進行免密碼登錄到遠程主機了。

至此,主機間的信任就算結(jié)束了。


shell腳本編寫

目標需求是獲取所有g(shù)et機上執(zhí)行的shell命令,并進行整合輸出。我在網(wǎng)上找了一個shell腳本,大致的內(nèi)容如下:

#!/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 "$@"

然后需要在同級目錄下創(chuàng)建一個get主機列表。

192.168.32.102
192.168.32.105
192.168.32.109
192.168.32.110

然后懶得輸入bash前綴來執(zhí)行命令的話,就可以寫一個alias了在~/.bashrc 文件末尾添加如下內(nèi)容:

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

然后*source ~/.bashrc

這樣就可以通過如下格式,來批量在主機之間執(zhí)行shell命令了,具體的格式如下:

devpssh 'cat /var/log/nginx/api_acces.log | grep curuserid=2614677 | tail -1'
在多臺主機之間批量執(zhí)行shell語句的效果

至此,在多臺主機之間執(zhí)行shell命令也就得以實現(xiàn)了。


總結(jié)

本次內(nèi)容比較少,單純的了解了下ssh的一些相關(guān)知識點。然后是利用公鑰免密登錄并執(zhí)行相關(guān)的shell命令。

麻雀雖小,但是卻很實用。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容