獲取多臺主機命令執行結果

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

以前在主產品用過一個運維同事寫的工具,devpssh。能夠經過指定主機列表來執行一條shell命令,而後獲取到全部的返回結果,輸出到屏幕上。nginx

我我的以爲這個工具很實用,尤爲是在有多臺Nginx服務器的時候,因爲負載均衡策略下,不一樣的請求可能會被下放到不一樣的get機,所以產生的日誌文件就可能分佈在多臺機器上。若是咱們一個個地到每臺get機上去執行shell語句。首先工做量會很大,另外獲取到的結果也不容易整理。而此時用一下devpssh,就沒有這些負擔了。算法

在正式介紹如何寫一個這樣的工具以前,先來看看須要哪些基礎的知識。shell

  • 主機間信任
  • shell腳本

主機間信任

說到主機之間的信任,仍是要將歷史往前追溯一下。談談SSH。簡單來講SSH是一種網絡協議,用於計算機之間的加密登陸。之因此是加密登陸就是應爲原始的用戶遠程登陸是明文的,一旦被截獲,信息就泄露了。api

SSH是協議,具體有不少實現。有商業實現的,也有開源實現。不過大體來看,用法是一致的。bash

先來看看安裝了ssh的機器有什麼不一樣吧。 服務器

執行過ssh-keygen後

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

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語句的效果

至此,在多臺主機之間執行shell命令也就得以實現了。


總結

本次內容比較少,單純的瞭解了下ssh的一些相關知識點。而後是利用公鑰免密登陸並執行相關的shell命令。

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

相關文章
相關標籤/搜索