使用ansible批量管理遠端伺服器

發表於2016-03-29

使用ansible批量管理遠端伺服器

背景

本地需要管理遠端的一批伺服器,主要執行以下任務:

1) 將本地的檔案複製到遠端所有伺服器;
2) 需要在遠端伺服器中執行一個個命令;

遠端伺服器路徑並非完全一致,一般訪問通過環境變數中定義的變數路徑訪問;
比如在.bashrc中定義$app_path=/opt/app/bin

最終選擇ansible,使用這個自動化運維工具可以滿足我的需求;
下面介紹下對於我這種場景需要使用的ansible的主要模組;
關於ansible是什麼以及安裝配置請自行百度;

複製

copy模組

使用copy模組,可以將本地檔案一鍵複製到遠端伺服器;
-a後跟上引數,引數中指定本地檔案和遠端路徑;

ansible通過ssh登入到遠端伺服器後,並不執行.bash_profile來設定使用者自定義的環境變數;如果我們需要管理的目標伺服器的路徑不同,就不能直接寫絕對路徑,也不能寫變數替換的路徑;

比如:針對伺服器A的目標複製路徑為 /opt/app/user1/bin ,伺服器B的目標複製路徑為/opt/app/user2/bin; 這兩個路徑在各自的伺服器中的路徑變數都設定為$bin; 但在copy模組中,我們不能直接使用dest = $bin/;
路徑設定一般放在.bashrc /.bash_profile檔案,但ansible模組登入後並不載入這兩個檔案;

解決方法:

針對這種情況,可以將dest路徑設定為~/,都複製到使用者目錄,後續再通過遠端指令碼處理;

遠端批量命令

需要在遠端執行一個個命令來管理遠端伺服器;

遠端執行命令的模組有command、shell、scripts、以及raw模組;

command模組

command模組為ansible預設模組,不指定-m引數時,使用的就是command模組;

comand模組比較簡單,常見的命令都可以使用,但其命令的執行不是通過shell執行的,所以,像這些 “”, “|”, and “&”操作都不可以,當然,也就不支援管道;

示例:顯示遠端路徑:

缺點:不支援管道,就沒法批量執行命令;

shell模組

使用shell模組,在遠端命令通過/bin/sh來執行;所以,我們在終端輸入的各種命令方式,都可以使用;
但是我們自己定義在.bashrc/.bash_profile中的環境變數shell模組由於沒有載入,所以無法識別;如果需要使用自定義的環境變數,就需要在最開始,執行載入自定義指令碼的語句;

對shell模組的使用可以分成兩塊:

1) 如果待執行的語句少,可以直接寫在一句話中:

2) 如果在遠端待執行的語句比較多,可寫成一個指令碼,通過copy模組傳到遠端,然後再執行;但這樣就又涉及到兩次ansible呼叫;對於這種需求,ansible已經為我們考慮到了,script模組就是幹這事的;

scripts模組

使用scripts模組可以在本地寫一個指令碼,在遠端伺服器上執行:

這裡是命令模組的官方文件:
http://docs.ansible.com/list_of_commands_modules.html

批量執行playbooks

遠端批量命令執行的另外一種方式是用playbooks;

這裡是playbooks的官方文件:http://docs.ansible.com/playbooks.html

這裡有ansible的playbooks示例:https://github.com/ansible/ansible-examples

在python中使用ansbile API

以上執行ansible模組的方式都是在命令列中直接呼叫,如果對返回結果需要進一步處理,可以在程式中通過API呼叫的方式來使用ansible模組:

比如,以上在命令列中呼叫scripts的模組的方式在API中呼叫:

這裡是官方給出的一個詳細示例,直接執行一次,將result全部列印出來,會有直觀的瞭解:

API設計詳見:http://docs.ansible.com/developing_api.html

相關文章