Ansible是一款基於Linux環境開發的運維自動化工具,相較其它類似軟件,它最大的特點是無需在目標系統安裝客戶端(Agent)即可實現對其進行統一管理和操作。
在我使用了一個多月Ansible後,我感覺Ansible的確是一款搞運維工作朋友的好助手。本文將結合筆者工作中利用ansible處理的實際案例,一窺ansible的功能及其妙用。
Ansible的安裝(centos為例)
在centOS下安裝Ansible只需一條命令:
$ sudo yum install ansible
安裝過程很簡單,但如果操作系統版本較低,需要額外安裝Python2.6 或 Python2.7,注意目標客戶機上也要求安裝Python,並且版本不得低於2.5 。
Ansible默認使用ssh協議管理客戶機,我也是按照默認協議進行的配置,所以目標客戶機需要開啟ssh協議。檢查ssh是否運行的命令:
$ ps ax | grep sshd
經過以上簡單的兩步,我們就可以初試牛刀了。我將通過我在工作中遇到的需求來一步一步和大家一起探索ansible的強大功能。
運用案例
批量部署zabbix客戶端
筆者最近接到一個工作,需要監測約100臺在線服務器的運行情況。部署方案採用zabbix來完成監控任務,因為zabbix需要部署客戶端,逐臺部署對我這樣的懶人是一個讓人崩潰的工作,於是在網上搜索了自動化運維的知識,很多軟件可以完成我的工作任務,但我選擇了Ansible,看中的就是無需在客戶端部署。
在使用ansible前,還需要做2件事,第1件是創建目標主機列表,配置文件的位置在/etc/ansible/hosts。
# [test]表示組名,可以將不同類型或功能的服務器分在不同組,例如本例中的test組和test2組
[test]
1.1.1.1
2.2.2.2
[test2]
3.3.3.3
分好組後,第2件事是使用ssh證書,實現免密碼登錄。
假設安裝ansible軟件的服務器ip是192.168.1.100,免密碼登錄的服務器ip是192.168.1.200,首先在100上執行命令:
$ ssh-keygen -t rsa
該命令會生成2個文件,默認存放在/root/.ssh/目錄下,名為id_rsa,id_rsa.pub。接著我們要將公匙文件拷貝到目標機器。
$ ssh-copy-id -i /root/.ssh/id_rsa.pub -p22 [email protected]
如果ssh的端口默認是22的話,也可以不用指定 -p參數,經過以上2步,我們就可以使用ssh hostIP的方式直接登錄客戶機了,不再需要輸入密碼。
基本準備工作做完,可以開始做正事了。Ansible的提供的功能是模塊化的,我也只是根據工作需要使用了其中很小一部分,在此只是拋磚引玉,更多的功能,需要大家一起挖掘。
為了測試ansible是否能夠正常工作,我使用了ping模塊進行測試。
$ ansible test -m ping
測試結果
我們看到ansible正常的返回了ping結果。簡單解釋一下命令的構造,test是先前在/etc/ansible/hosts裡面建的組,-m(module)表示使用ansible提供的模塊,在這裡我使用了ping模塊,ping模塊不需要加額外的參數。
返回的結果裡面,SUCCESS表示模塊執行成功,changed表示對目標機器做了配置改變,很明顯ping命令不會修改目標機器的配置。
驗證了ansible能夠正常工作,我們繼續先前的任務,部署zabbix客戶端第一步是安裝zabbix安裝源rpm包。在管理主機上(192.168.1.100)下載好rpm包。(wget http://repo.zabbix.com/zabbix/3.4/rhel/7/x86_64/zabbix-release-3.4-1.el7.centos.noarch.rpm),然後需要在每臺機器上執行下列操作。
任務 1:將文件批量複製到所有目標機
$ ansible all -m copy -a "class="lazy" src="//p2.ttnews.xyz/loading.gif" data-original=/root/zabbix-release-3.4-1.el7.centos.noarch.rpm dest=/root/"
all表示對/etc/ansible/hosts下所有的機器執行操作,copy表示調用ansible的copy模塊,,-a(Argument)表示參數,copy模塊的作用是把本地指定位置的文件拷貝到目標機,常用的參數有2個,一是src,表示拷貝源路徑,dest表示目標路徑。
拷貝結果
看到success就表示命令執行成功了,但更重要的是看changed的值是否為true,只有為true的情況下才表示拷貝操作完成,因為你在目標機上增加了一個rpm文件,代表改變了目標機的配置。其它還有一些如文件權限及所有者的信息。
大家看到ansible的威力了嗎,只需要一個命令,就可以將需要的文件拷貝到所有目標機上。
接下來是安裝rpm包
$ ansible test -m shell -a "rpm -ivh /root/zabbix-release-3.4-1.el7.centos.noarch.rpm"
這次調用了shell模塊,參數就是安裝rpm包的命令,也是一步完成所有目標機的安裝。
再後面的安裝步驟也是大同小異,就不再一一列舉。
順利完成監控的部署後,老闆又給了新的任務,要求給所有機器加一個計劃任務,每天17:30定期增加一條防火牆策略,在每天23:30定期刪除該策略。這個任務本身不難,麻煩的是要部署到100臺服務器上,又該Ansible閃亮登場了。
做這個功能需要有一個判斷,首先要查看目標機是否已經設置了策略,如果沒設置則設置,如果設置過了則跳過。這裡我們就要用到ansible提供的一個新玩意兒playbook,開個玩笑,不知道和playboy有沒有什麼關係:P
言歸正題,playbook可以在某種程度上認為是一個shell腳本,不過它使用的的是YAML,一種標記性語言。不過我認為目前我接觸到的任務目標並不需要專門去學習它的語法格式,我們還是在實戰中總結經驗吧。
任務2:對所有目標機設置crontab策略,並在設置時檢查是否已經設置過策略,如設置過,則跳過。
#checkCrontab.yml
---
#固定格式,冒號後是自定義腳本名稱
- name: check80
#該策略應用到哪些組,組是在前面提過在/etc/ansible/hosts裡面定義的。
hosts: test
#讓ansible不去獲取目標機的常規信息以節省腳本檢測時間
gather_facts: false
#任務開始關鍵字
tasks:
#子任務名稱,可自定義。
- name: getCrontab
#調用ansible的shell模塊,並在目的機執行冒號後的命令,命令的目的是查看crontab裡面的任務是否有指定的策略。
shell: crontab -l |grep '30 17 \\* \\* \\* /sbin/iptables -A OUTPUT -p tcp --dport 80 -j DROP' | wc -l
#register是將上一條命令執行後的輸出結果存放到cronHave自定義變量中。
register: cronHave
//第2個子任務,在第1個子任務完成後才執行。
- name: add when absent.
//調用ansible的lineinfile模塊,其作用是根據dest指定的文件,修改文本的內容,默認是將Line冒號後的內容追加到最後一行。
lineinfile:
dest: /root/mytest
line: '30 17 * * * /sbin/iptables -A OUTPUT -p tcp --dport 80 -j DROP'
//when表示條件,意思只有第一個子任務的返回值是0,才執行第2個子任務。
when: cronHave.stdout | int == 0
這就是一個用YAML標記語言寫的文件,不要被嚇著了,整個文件就分為2個子任務,按順序執行,第1個子任務是查詢當前crontab裡面是否已配置指定的策略,第2個子任務根據第1個子任務的結果決定是否執行。
playbook是一個很強大的武器,可以設置各種條件來執行不同的任務,我在這裡也只是拋磚引玉,畢竟自己也才接觸一個多月。寫此文的目的,一是想記錄一些自己做過後,二是願和大家交流技術、交流看法,希望能一起進步。
閱讀更多 windbadboy 的文章