Playbook是Ansible的配置,部署和編排語言。 他們可以描述您希望遠程系統執行的策略,或一般IT流程中的一組步驟。
如果Ansible modules是您workshop的工具,則playbooks是您的說明手冊,您的主機inventory是您的原材料。
在基本層面上,可以使用playbooks來管理遠程機器的配置和部署。 在更高級別,他們可以對涉及滾動更新的多層次推出進行排序,並可以將操作委派給其他主機,與監控服務器進行交互,同時加載平衡器。
雖然這里有很多信息,但是不需要一次就可以學習所有的東西。 隨着時間的推移,您可以開始小型化,隨時隨地選擇更多功能。
playbooks旨在讓人可讀,並以基本的文字語言開發。 可以通過多種方法來組織playbooks和他們包含的文件,我們將提供一些建議,並充分利用“可復制”。
建議您閱讀“ Playbook ”文檔,同時閱讀“ 示例手冊” 。 這些說明了最佳實踐以及如何將許多各種概念集中在一起。
關於Playbooks
Playbook是一種與adhoc任務執行模式完全不同的方式,而且特別強大。
簡單地說,Playbooks是一個非常簡單的配置管理和多機器部署系統的基礎,不像任何已經存在的那樣,而且非常適合部署復雜的應用程序。
Playbook可以聲明配置,但它們也可以協調任何手動訂購過程的步驟,即使不同的步驟必須在特定訂單的機器組之間來回彈起。 他們可以同步或異步地啟動任務。
雖然您可以運行主/usr/bin/ansible
程序來進行自組織任務,但是Playbook更有可能被保留在源代碼管理中,並用於推出配置或確保遠程系統的配置符合規范。
還有一些完整的劇本可以在ansible-examples存儲庫中說明很多這些技術。 我們建議您在另一個標簽中查看這些內容。
在學習劇本之后,還有很多跳躍點,所以在完成本節之后,請回到文檔索引。
Playbook Language Example
Playbook以YAML格式(見YAML Syntax )表示,並具有最少的語法,它有意嘗試不是編程語言或腳本,而是一個配置或進程的模型。
每個playbook由一個或多個“plays”組成。
一個play的目標是將一組主機映射到一些明確定義的roles,由事件可調用的任務代表。 在基本層面上,一個任務只不過是對一個可以粘貼的模塊的調用(參見關於模塊 )。
通過編寫多個“plays”的playbook,可以協調多機器部署,在Web服務器組中的所有計算機上運行某些步驟,然后在數據庫服務器組上執行某些步驟,然后在Web服務器組等上再次執行命令。
“plays”或多或少是體育比喻。 你可以有很多戲劇影響你的系統做不同的事情。 它不像你只是定義一個特定的狀態或模型,你可以在不同的時間運行不同的play。
對於初學者來說,這是一個僅包含一個play的playbook:
---
- hosts: webservers vars: http_port: 80 max_clients: 200 remote_user: root tasks: - name: ensure apache is at the latest version yum: name=httpd state=latest - name: write the apache config file template: src=/srv/httpd.j2 dest=/etc/httpd.conf notify: - restart apache - name: ensure apache is running (and enable it at boot) service: name=httpd state=started enabled=yes handlers: - name: restart apache service: name=httpd state=restarted
當使用具有很長參數的任務或具有許多參數的模塊時,可以通過多行將任務項目中斷以改進結構。 以下是上述示例的另一個版本,但是使用YAML字典為它們的key=value
參數提供模塊:
---
- hosts: webservers vars: http_port: 80 max_clients: 200 remote_user: root tasks: - name: ensure apache is at the latest version yum: name: httpd state: latest - name: write the apache config file template: src: /srv/httpd.j2 dest: /etc/httpd.conf notify: - restart apache - name: ensure apache is running service: name: httpd state: started handlers: - name: restart apache service: name: httpd state: restarted
Playbook可以包含多個play。 您可能有一個Playbook首先定位到Web服務器,然后是數據庫服務器。 例如:
---
- hosts: webservers remote_user: root tasks: - name: ensure apache is at the latest version yum: name=httpd state=latest - name: write the apache config file template: src=/srv/httpd.j2 dest=/etc/httpd.conf - hosts: databases remote_user: root tasks: - name: ensure postgresql is at the latest version yum: name=postgresql state=latest - name: ensure that postgresql is started service: name=postgresql state=started
您可以使用此方法在您要定位的主機組,登錄到遠程服務器的用戶名,是否要sudo之間進行切換。 play,像任務一樣,按照playbook中指定的順序運行:從上到下。
Basics
Hosts and Users
對於Playbook中的每個play,您可以選擇您的基礎設施中的哪些機器進行定位,以及什么遠程用戶完成步驟(稱為任務)。
hosts
行是一個或多個組或主機模式的列表,以冒號分隔,如“ 模式”文檔中所述。 remote_user
只是用戶帳戶的名稱:
--- - hosts: webservers remote_user: root
還可以為每個任務定義遠程用戶:
---
- hosts: webservers remote_user: root tasks: - name: test connection ping: remote_user: yourname
支持作為其他用戶來運行(請參閱Become (Privilege Escalation) ):
--- - hosts: webservers remote_user: yourname become: yes
您也可以使用成為特定任務而不是整個play:
---
- hosts: webservers remote_user: yourname tasks: - service: name=nginx state=started become: yes become_method: sudo
您也可以登錄,然后成為與root不同的用戶:
--- - hosts: webservers remote_user: yourname become: yes become_user: postgres
您還可以使用其他權限升級方法,如su:
---
- hosts: webservers remote_user: yourname become: yes become_method: su
如果需要指定sudo的密碼,請使用--ask-become-pass
或使用舊的sudo語法--ask-sudo-pass
( -K
)運行ansible-playbook
。
如果你運行成為playbook,並且playbook似乎掛起,它可能會停留在特權升級提示符下。 只要控制C來殺死它並再次運行,添加相應的密碼。
您還可以控制運行主機的順序。 默認是按照inventory提供的順序:
- hosts: all order: sorted gather_facts: False tasks: - debug: var=inventory_hostname
order的可能值為:
- inventory:
- 默認值。 該order是由“inventory”提供的
- reverse_inventory:
- 顧名思義,將inventory提供的順序反過來了
- sorted:
- 主機按名稱的字母順序排列
- reverse_sorted:
- 反向
- shuffle:
- Hosts are randomly ordered each run 主機每次運行隨機順序
-
Tasks list
每個play包含一個任務列表。 任務按順序執行,一次一個地執行與主機模式匹配的所有計算機,然后再轉到下一個任務。 重要的是要明白,在一個playbook中,所有的主機都要得到相同的任務指令。 play的目的是將選擇的主機映射到任務。
當運行從上到下運行的playbook時,失敗任務的主機將從整個playbook的旋轉中取出。 如果事情失敗,只需更正playbook文件並重新運行。
每個任務的目標是執行一個非常具體的參數的模塊。 如上所述,變量可以在模塊的參數中使用。
模塊應該是冪等的,也就是說,按順序運行一個模塊多次應該具有一樣的運行效果。 實現冪等的一種方法是使模塊檢查其所期望的最終狀態是否已經實現,並且如果該狀態已經實現,
則在不執行任何動作的情況下退出。 如果一個playbook所使用的所有模塊都是冪等的,那么這個playbook本身就有可能是冪等的,所以重新運行這個playbook應該是安全的。
command和shell模塊通常會重新運行相同的命令,如果命令類似於chmod
或setsebool
等,則完全可以。盡管有一個可用於創建這些模塊的creates
標志也是冪等的。
每個任務都應該有一個name
,它包含在運行該play的輸出中。 這是人類可讀的輸出,因此提供每個任務步驟的良好描述是有用的。 如果沒有提供名稱,則將“feed”的字符串用作輸出。
可以使用舊版action: module options
格式聲明任務,但建議您使用更常規的module: options
格式。 在整個文檔中使用了這種推薦的格式,但是您可能會在某些playbook中遇到較舊的格式。
這是一個基本的任務。 與大多數模塊一樣,服務模塊采用key=value
參數:
tasks: - name: make sure apache is running service: name=httpd state=started
command和shell模塊是唯一獲取參數列表而不使用key=value
表單的模塊。 這使得他們按照你所期望的方式工作:
tasks: - name: enable selinux command: /sbin/setenforce 1
command和shell模塊關心返回代碼,所以如果你有一個成功的退出代碼不為零的命令,你可能希望這樣做:
tasks: - name: run this command and ignore the result shell: /usr/bin/somecommand || /bin/true
或這個:
tasks: - name: run this command and ignore the result shell: /usr/bin/somecommand ignore_errors: True
如果行動線太長了,你可以在一個空間上打破它,並縮進任何延續線:
tasks: - name: Copy ansible inventory file to client copy: src=/etc/ansible/hosts dest=/etc/ansible/hosts owner=root group=root mode=0644
變量可以在動作行中使用。 假設您在vars
部分中定義了一個名為vhost
的vars
,您可以這樣做:
tasks: - name: create a virtual host file for {{ vhost }} template: src=somefile.j2 dest=/etc/httpd/conf.d/{{ vhost }}
Action Shorthand
可選擇在0.8及更高版本中列出這樣的模塊:
template : src = templates / foo.j2 dest = / etc / foo.conf
您會注意到在早期版本中,這只能用作:
action : template src = templates / foo.j2 dest = / etc / foo.conf
舊的表單繼續在較新的版本中工作,沒有任何棄用的計划。
Handlers: Running Operations On Change
如上所述,模塊應該是冪等的,並且可以在遠程系統上進行更改時進行中繼。 Playbook認識到這一點,並有一個基本的事件系統可以用來響應變化。
這些“通知”動作在play中每個任務塊的末尾觸發,只有在多個不同任務通知時才會被觸發一次。
例如,多個資源可能表明apache需要重新啟動,因為它們已經更改了一個配置文件,但apache只會被triggered一次以避免不必要的重新啟動。
以下是當文件內容更改時重新啟動兩個服務的示例,但僅當文件更改時:
- name: template configuration file template: src=template.j2 dest=/etc/foo.conf notify: - restart memcached - restart apache
任務notify
部分列出的內容稱為處理程序。
處理程序是由全局唯一名稱引用的任務列表,與常規任務完全沒有任何區別,並由通知程序通知。 如果沒有通知處理程序,它將不會運行。 無論通過處理程序有多少任務,在所有任務在特定的play中完成后,它將只運行一次。
這是一個示例處理程序部分:
handlers: - name: restart memcached service: name=memcached state=restarted - name: restart apache service: name=apache state=restarted
至於Ansible 2.2,處理程序也可以“listen”通用主題,任務可以通知這些主題如下:
handlers: - name: restart memcached service: name=memcached state=restarted listen: "restart web services" - name: restart apache service: name=apache state=restarted listen: "restart web services" tasks: - name: restart everything command: echo "this task will restart the web services" notify: "restart web services"
這種使用可以更容易地觸發多個處理程序。 它也使處理程序與名稱分離,從而更容易在劇本和角色之間共享處理程序(特別是當使用像Galaxy這樣的共享源的第三方角色時)。
角色將在后面描述,但值得指出的是:
- 在
pre_tasks
,tasks
和post_tasks
部分內通知的處理程序將在通知的部分的末尾自動刷新; - 在
roles
部分內通知的處理程序將在roles
部分結束時自動刷新,但在任何tasks
處理程序之前。
如果您想要立即刷新所有處理程序命令,在1.2及更高版本中,您可以:
tasks: - shell: some tasks go here - meta: flush_handlers - shell: some other tasks
在上述示例中,任何排隊處理程序將在達到meta
語句時提前處理。 這是一個niche的例子,但可以不時地派上用場。
Executing A Playbook
現在你已經學會了Playbook的語法,你如何運行一個playbook? 這很簡單。 讓我們用10級的並行度來運行一個playbook:
ansible-playbook playbook.yml -f 10
Ansible-Pull
如果你想反轉Ansible的架構,那么節點就可以檢查到一個中央位置,而不是把配置推送給他們,你可以。
ansible-pull
是一個小腳本,可以從git檢出配置指令的備份,然后針對該內容運行ansible-playbook
。
假設您負載平衡您的checkout位置,基本無限可ansible-pull
秤。
運行ansible-pull --help
幫助詳細信息。
還有一個clever playbook可以通過推送模式下的crontab來配置安全性。
Tips and Tricks
要檢查playbook的語法,請使用帶有--syntax-check
標志的--syntax-check
ansible-playbook
。 這將通過解析器運行playbook文件,以確保其包含的文件,角色等沒有語法問題。
查看playbook執行的底部以獲取目標節點的總結以及它們的執行情況。 一般失敗和致命的“不可達到”的通信嘗試在計數中保持分開。
如果您想查看成功模塊以及不成功模塊的詳細輸出,請使用--verbose
標志。 這在可用0.5和更高版本中可用。
如果安裝了cowsay包,可靠的劇本輸出將大大提升。 嘗試一下!
在運行它之前,要查看playbook會受到哪些主機的影響,您可以執行以下操作:
ansible-playbook playbook.yml --list-hosts