Ansible之playbook的使用
一. 為什麽引入playbook
我們完成一個任務,例如安裝部署一個httpd服務,我們需要多個模塊(一個模塊也可以稱之為task)提供功能來完成。而playbook就是組織多個task的容器,他的實質就是一個文件,有著特定的組織格式,它采用的語法格式是YAML(Yet Another Markup Language)。YAML語法能夠簡單的表示散列表,字典等數據結構。具體請參考YAML詳細語法
YAML基本語法
列表:每一個列表成員前面都要有一個短橫線和一個空格
fruits: - Apple - Orange - Strawberry - Mango 或者: fruits: [‘Apple‘, ‘Orange‘, ‘Strawberry‘, ‘Mango‘]
字典:每一個成員由鍵值對組成,註意冒號後面要有空格
martin:
name: Martin D‘vloper
job: Developer
skill: Elite
或者
martin: {name: Martin D‘vloper, job: Developer, skill: Elite}
列表和字典可以混合使用
- martin: name: Martin D‘vloper job: Developer skills: - python - perl - pascal - tabitha: name: Tabitha Bitumen job: Developer skills: - lisp - fortran - erlang
二. playbook基礎組件
- Hosts:運行執行任務(task)的目標主機
- remote_user:在遠程主機上執行任務的用戶
- tasks:任務列表
- handlers:任務,與tasks不同的是只有在接受到通知時才會被觸發
- templates:使用模板語言的文本文件,使用jinja2語法。
- variables:變量,變量替換{{ variable_name }}
整個playbook是以task為中心,表明要執行的任務。hosts和remote_user表明在哪些遠程主機以何種身份執行。其他組件讓其能夠更加靈活。
下面詳細介紹某些組件
1. variable
變量定義在資產(inventory)中:
主機變量:
192.168.200.136 http_port=808 maxRequestsPerChild=808
192.168.200.137 http_port=8080 maxRequestsPerChild=909
主機組變量:
[websers]
192.168.200.136
192.168.200.137
[websers:vars]
ntp_server=ntp.exampl.com
proxy=proxy.exampl.com
變量定義在playbook中
- hosts: webservers
vars:
http_port: 80
使用facts變量:
facts變量是由setup模塊獲取遠程主機的信息。
用法:
ansible 192.168.200.136 -m setup
在roles中定義變量
後面介紹
ansible-playbook 命令中傳入參數
使用 -e選項傳入參數
ansible-playbook 192.168.200.136 -e "httpd_port=808" httpd04.yml
變量的引用
{{ var_name }}
2. templates
它是一個模塊功能,與copy不同的是他的文本文件采用了jinga2語法,
jinga2基本語法如下,
字面量:
字符串:使用單引號或雙引號
數字:整型,浮點數
列表:{item1,item2,...}
字典:{key1:value1,key2:value2,...}
布爾型:true/false
算術運算:
+,-,*,/,//,%,**
比較運算:
==,!=,>,>=,<,<=
邏輯運算:
and,or,not
註意:template只能在palybook中使用。
3. tasks
執行的模塊命令
格式:
action:模塊參數(此種方式只在較新的版本中出現)
module:參數(已鍵值對的形式出現)
每一個task都有一個名稱,用於標記此任務。任務示例:
name: install httpd
yum: name=httpd state=present
註意:shell和command沒有參數,可在後面直接跟命令
shell: ss -tnl | grep :80
(1)某任務的運行狀態為changed後,可通過相應的notify通知相應的handlers
(2)任務可以通過tags打標簽,然後通過palybook命令-t選項調用.
三. playbook調用方式
用法:
ansible-playbook <filename.yml> ... [options]
<filename.yml>:yaml格式的playbook文件路徑,必須指明
[options]: 選項
-C, --check:並不在遠程主機上執行,只是測試。
-i PATH, --inventory=PATH:資產的文件路徑
--flush-cache:清楚fact緩存
--list-hosts:列出匹配的遠程主機,並不執行任何動作
-t, TAGS, --tags=TAGS:運行指定的標簽任務
--skip-tags:跳過指定的notify,後面詳細介紹。
四. palybook示例文件解析
1. 安裝部署httpd服務-version1
資產文件
~] cat /etc/ansible/Hosts
[webservers]
192.168.200.136 httpd_port=808
192.168.200.137 httpd_port=8088
[test]
192.168.200.13[6:7]
httpd配置文件
~] grep ^Listen /etc/httpd/conf/httpd.conf
Listen 808
palybook文件
~] cat /root/httpd01.yml
- hosts: webservers
remote_user: root
tasks:
- name: install httpd
yum: name=httpd state=present
- name: install configure file
copy: src=httpd.conf dest=/etc/httpd/conf/
- name: start httpd service
service: name=httpd state=started
測試playbook
運行playbook
再次執行playbook
~]# yum install libselinux-python
從上圖可以看出,192.168.200.136執行成功,而192.168.200.137啟動服務時配置文件錯誤,這是因為拷貝過去的配置文件是centos7上的,而137這臺主機是centos6,它安裝的是httpd-2.2配置文件不兼容。此問題後面解決。
查看服務啟動時的端口
2. 安裝部署httpd服務-version2
copy命令拷貝配置文件時,無法對配置文件進行修改,不夠靈活。接下來我們使用template拷貝文件,並使用主機變量設置httpd端口號
資產文件
~]# cat /etc/ansible/hosts
[webservers]
192.168.200.136 httpd_port=8088
[test]
192.168.200.13[6:7]
配置文件
~]# grep ^Listen httpd.conf.j2
Listen {{ httpd_port }}
palybook文件
~]# cat httpd02.yml
- hosts: 192.168.200.136
remote_user: root
tasks:
- name: install httpd
yum: name=httpd state=present
- name: install configure file
template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
- name: start httpd service
service: name=httpd state=started
運行playbook
由圖可以看出,playbook中只將文件拷貝過去了,並沒有重啟服務,所以我們可以看到端口監聽的依然是808而不是8088。此時我們需要在配置文件修改時觸發一個任務,這就是handlers的用法,重新修改playbook文件。
重新修改YAML文件
~]# cat httpd02.yml
- hosts: 192.168.200.136
remote_user: root
tasks:
- name: install httpd
yum: name=httpd state=present
- name: install configure file
notify: restart httpd service
template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
- name: start httpd service
service: name=httpd state=started
handlers:
- name: restart httpd servcie
service: name=httpd state=restarted
notify表明此task改變時,它會觸發一個事件,此事件會調用name為restart httpd service的handlers task。
再次運行playbook
可以看到,此playbook執行了兩個任務,一個是拷貝文件,一個是重啟服務。也可以看到此時監聽的端口不在是808而是8088
我們修改配置文件並重啟服務,這是一個非常常見的操作。由上面我們看到,盡管我們只需執行兩個task但我們把所有的任務都執行一遍,這會降低效率,我們可以使用tags來指定執行那個任務。
3. 指定執行任務
資產文件
註意,修改了端口號
~] cat /etc/ansibele/hosts
[webservers]
192.168.200.136 httpd_port=8080
[test]
192.168.200.13[6:7]
修改playbook文件
~]# cat httpd03.yml
- hosts: 192.168.200.136
remote_user: root
tasks:
- name: install httpd
yum: name=httpd state=present
- name: install configure file
notify: restart httpd service
tags: reinstall configure file
template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
- name: start httpd service
service: name=httpd state=started
handlers:
- name: restart httpd service
service: name=httpd state=restarted
執行playbook
由圖可以看到,playbook只執行了拷貝文件,以及拷貝文件觸發的重啟服務事件。也可以看到服務開啟的是8080端口。
五. ansible特性--判斷和循環
在前面有一個問題沒有解決就是centos6和centos7配置文件不兼容的問題,我們需要對其進行判斷,不同的版本拷貝同的文件。
我們將lamp放在一臺主機上時,我們需要安裝多個程序包,寫成一個一個的task顯得效率不高,寫的臃腫。我們可以使用循環來進行安裝。
1 判斷
以解決上面遺留的問題為例,如何讓centos6的主機拷貝centos6的文件,讓centos7的主機拷貝centos7的文件。
也可以使用變量來實現,此處不做演示
資產文件
~]# cat /etc/ansible/hosts
[webservers]
192.168.200.136 httpd_port=8088
192.168.200.137 httpd_port=8080
[test]
192.168.200.13[6:7]
playbook文件
其中的ansible_distribution_major_version是ansible收集的facts
測試playbook文件
跳過notify,讓其不執行重啟服務的操作,在執行playbook時使用 --skip-tags選項
值得註意的是,雖然沒有執行重啟,但拷貝配置文件也沒有執行。
執行playbook
註意:他的語法格式類似jinja2。
2. 循環
playbook文件
執行playbook文件並查看
判斷和循環的詳細請點擊這
Ansible之playbook的使用