ansible批量管理遠程服務器

使用ansible批量管理遠程服務器

安裝ansible:

wget https://pypi.python.org/packages/source/a/ansible/ansible-2.0.0.0.tar.gz
tar zxf ansible-2.0.0.0.tar.gz
cd ansible-2.0.0.0
python setup.py  install
mkdir /etc/ansible
cp examples/ansible.cfg  /etc/ansible/
cp examples/hosts  /etc/ansible/

查看ansible版本:
ansible --version
ansible 2.0.0.0
  config file = /root/.ansible.cfg
  configured module search path = Default w/o overrides






配置ansible:


vi /etc/ansible/ansible.cfg
hostfile       = /etc/ansible/hosts
library        = /usr/share/ansible
remote_tmp     = $HOME/.ansible/tmp
pattern        = *
forks          = 5
poll_interval  = 15
sudo_user      = ansible
#ask_sudo_pass = True
#ask_pass      = True
transport      = smart
remote_port    = 22
module_lang    = C





vi /etc/ansible/hosts


[deploy]
100.144.207.45 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=root134 ansible_connection=paramiko
100.144.177.31 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=root123 ansible_connection=paramiko


測試ansible

ansible -i hosts all -m ping
背景
本地需要管理遠程的一批服務器,主要執行以下任務:
1) 將本地的文件複製到遠端所有服務器; 
2) 需要在遠程服務器中執行一個個命令;
遠端服務器路徑並非完全一致,一般訪問通過環境變量中定義的變量路徑訪問; 
比如在.bashrc中定義$app_path=/opt/app/bin
最終選擇ansible,使用這個自動化運維工具可以滿足我的需求; 
下面介紹下對於我這種場景需要使用的ansible的主要模塊; 
關於ansible是什麼以及安裝配置請自行百度;
複製
copy模塊
使用copy模塊,可以將本地文件一鍵複製到遠程服務器; 
-a後跟上參數,參數中指定本地文件和遠端路徑;
ansible myservers -m copy -a "src=/opt/app/bin/transfer.tar dest=~/"
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 "&"操作都不可以,當然,也就不支持管道; 
示例:顯示遠程路徑:
ansible myservers  -a 'pwd'10.6.143.38 | success | rc=0 >>/home/rduser10.6.143.53 | success | rc=0 >>/home/rduser10.6.143.37 | success | rc=0 >>/home/rduser
缺點:不支持管道,就沒法批量執行命令;
shell模塊
使用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模塊
使用scripts模塊可以在本地寫一個腳本,在遠程服務器上執行:
ansible myservers  -m script -a "/opt/app/target.sh"
這裏是命令模塊的官方文檔: 
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中調用:
import ansible.runner
results = ansible.runner.Runner(pattern='myservers', forks=5,module_name='script', module_args='/opt/app/target.sh',).run()
這裏是官方給出的一個詳細示例,直接運行一次,將result全部打印出來,會有直觀的瞭解:
#!/usr/bin/pythonimport ansible.runnerimport sys# construct the ansible runner and execute on all hostsresults = 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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章