本地須要管理遠程的一批服務器,主要執行如下任務:html
1) 將本地的文件複製到遠端全部服務器;
2) 須要在遠程服務器中執行一個個命令;python
遠端服務器路徑並不是徹底一致,通常訪問經過環境變量中定義的變量路徑訪問;
好比在.bashrc中定義$app_path=/opt/app/bingit
最終選擇ansible,使用這個自動化運維工具能夠知足個人需求;
下面介紹下對於我這種場景須要使用的ansible的主要模塊;
關於ansible是什麼以及安裝配置請自行百度;github
使用copy模塊,能夠將本地文件一鍵複製到遠程服務器;
-a後跟上參數,參數中指定本地文件和遠端路徑;shell
ansible myservers -m copy -a "src=/opt/app/bin/transfer.tar dest=~/"
ansible經過ssh登陸到遠程服務器後,並不執行.bash_profile來設置用戶自定義的環境變量;若是咱們須要管理的目標服務器的路徑不一樣,就不能直接寫絕對路徑,也不能寫變量替換的路徑;api
好比:針對服務器A的目標複製路徑爲 /opt/app/user1/bin ,服務器B的目標複製路徑爲/opt/app/user2/bin; 這兩個路徑在各自的服務器中的路徑變量都設置爲$bin; 但在copy模塊中,咱們不能直接使用dest = $bin/;
路徑設置通常放在.bashrc /.bash_profile文件,但ansible模塊登陸後並不加載這兩個文件;bash
解決方法:
針對這種狀況,能夠將dest路徑設置爲~/,都複製到用戶目錄,後續再經過遠程腳本處理;服務器
須要在遠程執行一個個命令來管理遠程服務器;app
遠程執行命令的模塊有command、shell、scripts、以及raw模塊;運維
command模塊爲ansible默認模塊,不指定-m參數時,使用的就是command模塊;
comand模塊比較簡單,常見的命令均可以使用,但其命令的執行不是經過shell執行的,因此,像這些 "<", ">", "|", and "&"操做都不能夠,固然,也就不支持管道;
示例:顯示遠程路徑:
ansible myservers -a 'pwd' 10.6.143.38 | success | rc=0 >> /home/rduser 10.6.143.53 | success | rc=0 >> /home/rduser 10.6.143.37 | success | rc=0 >> /home/rduser
缺點:不支持管道,就無法批量執行命令;
使用shell模塊,在遠程命令經過/bin/sh來執行;因此,咱們在終端輸入的各類命令方式,均可以使用;
可是咱們本身定義在.bashrc/.bash_profile中的環境變量shell模塊因爲沒有加載,因此沒法識別;若是須要使用自定義的環境變量,就須要在最開始,執行加載自定義腳本的語句;
對shell模塊的使用能夠分紅兩塊:
1) 若是待執行的語句少,能夠直接寫在一句話中:
ansible myservers -a ". .bash_profile;ps -fe |grep sa_q" -m shell
2) 若是在遠程待執行的語句比較多,可寫成一個腳本,經過copy模塊傳到遠端,而後再執行;但這樣就又涉及到兩次ansible調用;對於這種需求,ansible已經爲咱們考慮到了,script模塊就是幹這事的;
使用scripts模塊能夠在本地寫一個腳本,在遠程服務器上執行:
ansible myservers -m script -a "/opt/app/target.sh"
這裏是命令模塊的官方文檔:
http://docs.ansible.com/list_of_commands_modules.html
遠程批量命令執行的另一種方式是用playbooks;
這裏是playbooks的官方文檔:http://docs.ansible.com/playbooks.html
這裏有ansible的playbooks示例:https://github.com/ansible/ansible-examples
以上執行ansible模塊的方式都是在命令行中直接調用,若是對返回結果須要進一步處理,能夠在程序中經過API調用的方式來使用ansible模塊:
好比,以上在命令行中調用scripts的模塊的方式在API中調用:
import ansible.runner results = ansible.runner.Runner( pattern='myservers', forks=5, module_name='script', module_args='/opt/app/target.sh', ).run()
這裏是官方給出的一個詳細示例,直接運行一次,將result所有打印出來,會有直觀的瞭解:
#!/usr/bin/python import ansible.runner import sys # construct the ansible runner and execute on all hosts results = ansible.runner.Runner( pattern='*', forks=10, module_name='command', module_args='/usr/bin/uptime', ).run() if results is None: print "No hosts found" sys.exit(1) print "UP ***********" for (hostname, result) in results['contacted'].items(): if not 'failed' in result: print "%s >>> %s" % (hostname, result['stdout']) print "FAILED *******" for (hostname, result) in results['contacted'].items(): if 'failed' in result: print "%s >>> %s" % (hostname, result['msg']) print "DOWN *********" for (hostname, result) in results['dark'].items(): print "%s >>> %s" % (hostname, result)
API設計詳見:http://docs.ansible.com/developing_api.html
Posted by: 大CC | 26MAY,2015
博客:blog.me115.com [訂閱]
微博:新浪微博