Ansible是一個系列文章,我會盡量以通俗易懂、詼諧幽默的總結方式給大家呈現這些枯燥的知識點,讓學習變的有趣一些。
Ansible系列博文直達連結:Ansible入門系列
前言
在上一篇文章中說到Ansible有兩種玩法,一種是Ansible Ad-Hoc,另一種是就是這裡要說的playbook。playbook是Ansible進行配置管理的元件,雖然Ansible的日常Ad-Hoc命令功能很強大,能完成一些基本的配置管理工作,但是Ad-Hoc命令無法支撐複雜環境的配置管理工作。在我們實際使用Ansible的工作中,大部分時間都是在編寫playbook,接下來就重點說說如何玩轉這個playbook。
執行playbook命令
我們都是按照yaml語法規則來編寫playbook,至於yaml怎麼玩,後面的文章我會總結一下的。在我們按照要求編寫好了yaml檔案後,如何來執行這個yaml檔案呢?
Ansible提供了一個單獨的命令:ansible-playbook
命令,我們可以通過這個命令來執行yaml指令碼。常見的ansible-playbook
的使用方法如下:
最簡單的使用方法:
ansible-playbook copyDemo.yaml
我們還可以使用以下命令檢視輸出的細節:
ansible-playbook copyDemo.yaml --verbose
我們也可以使用以下命令檢視該yaml指令碼將影響的主機列表:
ansible-playbook copyDemo.yaml --list-hosts
還可以使用以下命令檢查yaml指令碼語法是否正確:
ansible-playbook copyDemo.yaml --syntax-check
上面的幾種使用方法基本就涵蓋了我們日常工作中80%的場景了,剩餘的20%場景,比如並行、非同步等,很少用到,等真正用到的時候再去查閱相關資料也來的及。而工作中,更多的時候,我們不是在編寫playbook,就是在編寫playbook的路上。所以,接下來我重點說說如何寫這個playbook,也就是playbook的基本語法。
playbook基本語法
最基本的playbook指令碼分為三個部分:
- 在哪些機器上以什麼身份執行
- 執行的任務有哪些
- 善後任務有哪些
我們在編寫playbook指令碼的時候,總是離不開上面的三個部分的。下面先來一個稍微有點複雜的playbook指令碼,讓大家先有一個整體的認識。
---
- hosts: server1
user: root
vars:
http_port: 80
max_clients: 200
tasks:
- name: Write apache config file
template: src=/home/test1/httpd.j2 dest=/home/test2/httpd.conf
notify:
- restart apache
- name: Ensure apache is running
service: name=httpd state=started
handlers:
- name: restart apache
service: name=httpd state=restarted
現在就對上述三部分稍作詳細總結。
主機和使用者
上面的yaml指令碼,我們一開始就會看到hosts
、user
和vars
,其中vars
在後面的文章進行專門總結。而這裡的hosts
和user
就是表示我們這個yaml將要在哪些主機上用哪個使用者身份去操作。而這裡的深一層次的關係如下表所示:
key | 含義 |
---|---|
hosts | 為主機的IP,或者主機組名,或者關鍵字all |
user | 在遠端以哪個身份執行 |
become | 切換成其他使用者身份執行,值為yes或者no |
become_method | 與become一起使用,值可以為sudo /su 等 |
become_user | 與become一起使用,可以是root或者其它使用者名稱 |
在實際工作中,如果我們不指定user
時,則預設使用連線遠端主機的使用者進行操作,如果指定了執行使用者而與ansible_ssh_user
指定使用者不一致時,則需要開啟become
操作,這裡的become
配置與ansible.cfg中配置將相互配合完成工作,yaml中的become優先順序高於ansible.cfg中配置中的優先順序。
任務列表
任務列表是整個playbook的核心,對於任務列表,我們首先需要知道以下三點內容:
- 任務是從上到下順序執行的,如果中間發生錯誤,那麼整個playbook會中止;
- 每一個任務都是對模組的一次呼叫,只是使用不同的引數和變數而已;
- 每一個任務最好有一個name屬性,這樣在執行yaml指令碼時,可以看到執行進度資訊。
對於任務的引數有兩種不同的寫法,我們在編寫yaml指令碼時,可以按照自己的喜好進行選擇。
寫法一:
- name: Write apache config file
template: src=/home/test1/httpd.j2 dest=/home/test2/httpd.conf
寫法二:
- name: Write apache config file
template:
src: /home/test1/httpd.j2
dest: /home/test2/httpd.conf
這兩種寫法都是OK的,我一般喜歡第二種寫法。
最後,對於任務我們還需要特別一個點,那就是任務的執行狀態。我們在執行Ansible Ad-Hoc或者ansible-playbook的時候,在輸出中都會有一個changed
欄位,比如:
192.168.1.3 : ok=2 changed=0 unreachable=0 failed=0
或者
192.168.1.3 : ok=2 changed=1 unreachable=0 failed=0
這裡的這個changed
就是人物的執行狀態,但是它為什麼一會是0,一會有是1呢?這就要說到Ansible中一個叫做“冪等性”的概念。
冪等性
冪等性是數學和電腦科學上一個常見的概念,多次執行產生的結果不會發生改變,這樣的特性就被成為冪等性。
大多數的Ansible模組在設計時保證了冪等性,冪等性保證了Ansible指令碼多次執行情況下的相同結果,儘可能的避免使用那些不能滿足冪等性的模組。比如我們經常使用的
shell
模組就是非冪等性的。
我們要明白Ansible是以“結果為導向的”,我們指定了一個“目標狀態”,Ansible會自動判斷“當前狀態”是否與“目標狀態”一致,如果一致,則不進行任何操作;如果不一致,那麼就將“當前狀態”變成“目標狀態”,這就是“冪等性”,“冪等性”可以保證我們重複的執行同一項操作時,得到的結果是一樣的。
那這個冪等性與上面的changed
又有什麼關係呢?且聽我下面慢慢道來!
- 當
changed
為false或者0時,表示Ansible沒有進行任何操作,沒有“改變什麼”; - 當
changed
為true或者大於0時,表示Ansible執行了操作,“當前狀態”已經被Ansible改變成了“目標狀態”。
拿copy
這個模組來舉例子說明,當我們準備將一個檔案通過Ansible拷貝到遠端主機時,copy
模組首先檢查遠端是否已經存在了該檔案,如果不存在,則把檔案拷貝過去,返回changed
為大於0;如果存在時,則開始比對兩個檔案的md5值,如果md5值一致,則說明兩個檔案是一樣的,則不需要拷貝,此時copy
模組則什麼都不幹,返回changed
為0。
總結
通過三篇文章總結了Ansible中的常用模組、Ansible Ad-Hoc和ansible-playbook的一些慣用用法,從我的實際學習經驗來說,學到這裡,你可以將這三塊內容結合起來使用了,至少可以在你們生產環境鼓搗一下了。生來就是折騰,更何況我們這麼拼命、努力的學習呢!
果凍想,認真玩技術的地方。
2019年5月18日,於內蒙古呼和浩特。