附上前兩篇關於Ansible的博客地址,以供查閱,歡迎學習交流!
自動化運維之Ansible概述及Ansible部署
Ansible命令應用之經常使用模塊python
playbook是ansible用於配置,部署,和管理被控節點的劇本。mysql
經過playbook的詳細描述,執行其中的一系列tasks,可讓遠端主機達到預期的狀態。playbook就像Ansible控制器給被控節點列出的的一系列to-do-list,而被控節點必需要完成。 linux
也能夠這麼理解,playbook 字面意思,即劇本,現實中由演員按照劇本表演,在Ansible中,此次由計算機進行表演,由計算機安裝,部署應用,提供對外服務,以及組織計算機處理各類各樣的事情。nginx
執行一些簡單的任務,使用ad-hoc命令能夠方便的解決問題,可是有時一個設施過於複雜,須要大量的操做時候,執行的ad-hoc命令是不適合的,這時最好使用playbook。web
就像執行shell命令與寫shell腳本同樣,也能夠理解爲批處理任務,不過playbook有本身的語法格式。sql
使用playbook你能夠方便的重用這些代碼,能夠移植到不一樣的機器上面,像函數同樣,最大化的利用代碼。在你使用Ansible的過程當中,你也會發現,你所處理的大部分操做都是編寫playbook。能夠把常見的應用都編寫成playbook,以後管理服務器會變得十分簡單。shell
playbook由YMAL語言編寫。YAML( /ˈjæməl/ )參考了其餘多種語言,包括:XML、C語言、Python、Perl以及電子郵件格式RFC2822,Clark Evans在2001年5月在首次發表了這種語言,另外Ingy döt Net與Oren Ben-Kiki也是這語言的共同設計者。apache
YMAL格式是相似於JSON的文件格式,便於人理解和閱讀,同時便於書寫。首先學習瞭解一下YMAL的格式,對咱們後面書寫playbook頗有幫助。如下爲playbook經常使用到的YMAL格式。vim
文件的第一行應該以 」—」 (三個連字符)開始,代表YMAL文件的開始。
在同一行中,#以後的內容表示註釋,相似於shell,python和ruby。
YMAL中的列表元素以」-」開頭而後緊跟着一個空格,後面爲元素內容。就像這樣:安全
- apple - banana - orange等價於JSON的這種格式
[ 「apple」, 「banana」, 「orange」 ]
同一個列表中的元素應該保持相同的縮進。不然會被當作錯誤處理。
Playbook自己由如下各部分組成:
playbook中hosts,variables,roles,tasks等對象的表示方法都是鍵值中間以」:」分隔表示,」:」後面還要增長一個空格。
house: family: { name: Doe, parents: [John, Jane], children: [Paul, Mark, Simone] } address: { number: 34, street: Main Street, city: Nowheretown, zipcode: 12345 }
使用ansible-playbook運行playbook文件,獲得以下輸出信息,輸出內容爲JSON格式。而且由不一樣顏色組成,便於識別。通常而言
| 綠色表明執行成功,系統保持原樣
| ×××表明系統表明系統狀態發生改變
| 紅色表明執行失敗,顯示錯誤輸出。
執行有三個步驟:一、收集facts 二、執行tasks 三、報告結果
[root@CentOS7-master ~]# ansible-playbook mariadb.yml ---------------------------一、收集facts------------------------------------------ PLAY [webservers] ************************************************************** TASK [setup] ******************************************************************* ok: [172.17.254.165] ok: [172.17.254.180] ---------------------------二、執行tasks------------------------------------------ TASK [Install mariadb-server package] ****************************************** changed: [172.17.254.165] changed: [172.17.254.180] TASK [Starting mysqld service] ************************************************* changed: [172.17.254.165] changed: [172.17.254.180] ---------------------------三、報告結果------------------------------------------- PLAY RECAP ********************************************************************* 172.17.254.165 : ok=3 changed=2 unreachable=0 failed=0 172.17.254.180 : ok=3 changed=2 unreachable=0 failed=0
Playbook的設計目的是爲了讓某個或某些主機以某個用戶的身份去執行相應的任務。其中用於指定要執行指定任務的主機用hosts定義,能夠是一個主機也能夠是由冒號分隔的多個主機組;用於指定被管理主機上執行任務的用戶用remote_user來定義。
remote_user也可定義指定用戶經過sudo的方法在被管理主機上運行指令,甚至能夠在使用sudo時用sudo_user指定sudo切換的用戶。
Hosts:運行指定任務的目標主機; remoute_user: 在遠程主機上執行任務的用戶; sudo_user:指定sudo切換的用戶 tasks:任務列表 模塊,模塊參數; 格式: (1) action: module arguments (2) module: arguments
每個play包含了一個task列表(任務列表)。一個task在其所對應的全部主機上(經過host pattern匹配的全部主機)執行完畢以後,下一個task纔會執行。有一點須要明白的是(很重要),在一個play之中,全部hosts會獲取相同的任務指令,這是play的一個目的所在,也就是將一組選出的hosts映射到task。
在運行playbook時(從上到下執行),若是一個host執行task失敗,這個host將會從整個 playbook的rotation中移除. 若是發生執行失敗的狀況,請修正playbook中的錯誤,而後從新執行便可。
每一個task的目標在於執行一個moudle, 一般是帶有特定的參數來執行.在參數中可使用變量(variables)。
modules具備」冪等」性,意思是若是你再一次地執行 moudle(譯者注:好比遇到遠端系統被意外改動,須要恢復原狀),moudle只會執行必要的改動,只會改變須要改變的地方。因此重複屢次執行playbook也很安全。
對於command module和shell module,重複執行 playbook,其實是重複運行一樣的命令。若是執行的命令相似於‘chmod’或者‘setsebool’這種命令,這沒有任何問題。也可使用一個叫作 ‘creates’ 的 flag 使得這兩個module變得具備」冪等」特性(不是必要的)。
每個task必須有一個名稱name,這樣在運行playbook時,從其輸出的任務執行信息中能夠很好的辨別出是屬於哪個task 的。若是沒有定義name,‘action’ 的值將會用做輸出信息中標記特定的task。
若是要聲明一個task,之前有一種格式:「action: module options」。可能在一些老的playbooks 中還能見到)。如今推薦使用更常見的格式:」module: options」,本文檔使用的就是這種格式。
下面是一種基本的task 的定義,service moudle使用key=value格式的參數,這也是大多數 module 使用的參數格式:
tasks: - name: make sure apache is running service: name=httpd state=running
比較特別的兩個modudle是command和shell,它們不使用key=value格式的參數,而是這樣:
tasks: - name: disable selinux command: /sbin/setenforce 0
或者是這樣:
tasks: - name: run this command and ignore the result shell: /usr/bin/somecommand ignore_errors: True
若是action行看起來太長,你可使用space(空格)或者indent(縮進)隔開連續的一行:
tasks: - name: Copy ansible inventory file to client copy: src=/etc/ansible/hosts dest=/etc/ansible/hosts owner=root group=root mode=0644
在action行中可使用變量.假設在‘vars’那裏定義了一個變量‘vhost’,能夠這樣使用它:
tasks: - name: create a virtual host file for {{ vhost }} template: src=somefile.j2 dest=/etc/httpd/conf.d/{{ vhost }}
這些變量在 tempates 中也是可用的,稍後會講到。
Handlers用於當關注的資源發生變化時所採起的操做。在notify中列出的操做便稱爲handler,也就是在notify中須要調用handler中定義的操做。而notify這個動做在每一個play的最後被觸發,僅在全部的變化發生完成後一次性的執行指定操做。
tasks: – name: TASK_NAME module: arguments notify: HANDLER_NAME handlers: – name: HANDLER_NAME module: arguments
這裏是一個handlers的示例:
- name: template configuration file template: src=template.j2 dest=/etc/foo.conf notify: - restart memcached - restart apache
handler也是task列表格式,如:
handlers: - name: restart memcached service: name=memcached state=restarted - name: restart apache service: name=apache state=restarted
簡單示例以下:
[root@CentOS7-master ~]# vim mariadb.yml - hosts: webservers remote_user: root tasks: - name: Install mariadb-server package yum: name=mariadb-server state=present - name: copy my.cnf copy: src=/etc/my.cnf dest=/etc/ backup=yes notify: start tags: startmariadb - name: Stopping mysqld service service: name=mariadb state=stopped tags: stopmariadb handlers: - name: start service: name=mariadb state=started
(1) facts:可直接調用; 注意:可以使用setup模塊直接獲取目標主機的facters; (2) 用戶自定義變量: (a) ansible-playbook命令的命令行中的 -e VARS, --extra-vars=VARS (b) 在playbook中定義變量的方法: vars: - var1: value1 - - var2: value2 (3) 經過roles傳遞變量; (4) Host Inventory (a) 用戶自定義變量 (i) 向不一樣的主機傳遞不一樣的變量; IP/HOSTNAME varaiable=value var2=value2 (ii) 向組中的主機傳遞相同的變量; [groupname:vars] variable=value eg: [web] 172.17.251.188 172.17.250.209 [web:vars] rpmname=samba
Jinja是基於Python的模板引擎。Template類是Jinja的另外一個重要組件,能夠看做是一個編譯過的模板文件,用來產生目標文本,傳遞Python的變量給模板去替換模板中的標記。
Jinja:Jinja2是python的一種模板語言,以Django的模板語言爲本來。 Jinja文件的建立能夠直接將本身建立好的文本文件的後綴改爲以「.j2」結尾的便可! 下面用到的nginx.conf.j2文件就是將nginx.conf文件修改好後將其重命名爲nginx.conf.j2的! 支持: 字符串:使用單引號或雙引號; 數字:整數,浮點數; 列表:[item1, item2, ...] 元組:(item1, item2, ...) 字典:{key1:value1, key2:value2, ...} 布爾型:true/false 算術運算: +, -, *, /, //, %, ** 比較操做: ==, !=, >, >=, <, <= 邏輯運算: and, or, not
示例:
[root@CentOS7-master ~]# vim nginx.yml - hosts: webservers remote_user: root vars: - rpmname: nginx nginxport: 8888 tasks: - name: yum install {{ rpmname }} yum: name={{ rpmname }} state=present - name: copy {{ rpmname }}.conf template: src=/tmp/{{ rpmname }}.conf.j2 dest=/etc/nginx/{{ rpmname }}.c onf backup=yes notify: reload tags: reload{{ rpmname }} - name: start service service: name={{ rpmname }} state=started tags: start{{ rpmname }} handlers: - name: reload service: name={{ rpmname }} state=restarted
模板配置文件:
[root@CentOS7-master ~]# cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.j2 [root@CentOS7-master ~]# vim nginx.conf.j2 worker_processes {{ ansible_processor_vcpus }}; listen {{ http_port }};
若是屢次執行修改Playbook會涉及到一些沒有變化的代碼,可使用tags讓用戶選擇跳過沒有變化的代碼,只運行Playbook中發生變化的部分代碼。能夠在Playbook中爲某個或某些任務定義「標籤」,在執行此Playbook時經過ansible-playbook命令使用--tags選項能實現僅運行指定的tasks。
簡單示例以下:
[root@CentOS7-master ~]# vi hosts.yml --- - hosts: webserver remote_user: root tasks: - name: Copy hosts file copy: src=/etc/hosts dest=/etc/hosts tags: - only - name: touch file file: path=/opt/hosts state=touch
分別執行ansible-playbook hosts.yml --tags="only"和ansible-playbook hosts.yml能夠發現,有--tags="only"的命令只運行了Copy hosts file部分。
事實上,不光能夠爲單個或多個task指定同一個tags。playbook還提供了一個特殊的tags爲always。做用就是當使用always當tags的task時,不管執行哪個tags時,定義有always的tags都會執行。
vi hosts.yml --- - hosts: webserver remote_user: root tasks: - name: Copy hosts file copy: src=/etc/hosts dest=/etc/hosts tags: - only - name: touch file file: path=/opt/hosts state=touch tags: - always