自動化運維工具——ansible詳解(二)
目錄
正文
Ansible playbook 簡介
playbook 是 ansible 用於配置,部署,和管理被控節點的劇本。
透過 playbook 的詳細描述,執行其中的一系列 tasks ,可以讓遠端主機達到預期的狀態。playbook 就像 Ansible 控制器給被控節點列出的的一系列 to-do-list ,而被控節點必須要完成。
也可以這麼理解,playbook 字面意思,即劇本,現實中由演員按照劇本表演,在Ansible中,這次由計算機進行表演,由計算機安裝,部署應用,提供對外服務,以及組織計算機處理各種各樣的事情。
Ansible playbook使用場景
執行一些簡單的任務,使用ad-hoc命令可以方便的解決問題,但是有時一個設施過於複雜,需要大量的操作時候,執行的ad-hoc命令是不適合的,這時最好使用playbook。
就像執行shell命令與寫shell指令碼一樣,也可以理解為
批處理任務
,不過playbook有自己的語法格式。
使用playbook你可以方便的重用這些程式碼,可以移植到不同的機器上面,像函式一樣,最大化的利用程式碼。在你使用Ansible的過程中,你也會發現,你所處理的大部分操作都是編寫playbook。可以把常見的應用都編寫成playbook,之後管理伺服器會變得十分簡單。
Ansible playbook格式
1)格式簡介
playbook由YMAL語言編寫。
YAML( /ˈjæməl/ )參考了其他多種語言,包括:XML、C語言、Python、Perl以及電子郵件格式RFC2822,Clark Evans在2001年5月在首次發表了這種語言,另外Ingy döt Net與OrenBen-Kiki也是這語言的共同設計者。
YMAL格式是類似於JSON的檔案格式,便於人理解和閱讀,同時便於書寫。首先學習瞭解一下YMAL的格式,對我們後面書寫playbook很有幫助。以下為playbook常用到的YMAL格式:
1、檔案的第一行應該以 "---" (三個連字元)開始,表明YMAL檔案的開始。
2、在同一行中,#之後的內容表示註釋,類似於shell,python和ruby。
3、YMAL中的列表元素以”-”開頭然後緊跟著一個空格,後面為元素內容。
4、同一個列表中的元素應該保持相同的縮排。否則會被當做錯誤處理。
5、play中hosts,variables,roles,tasks等物件的表示方法都是鍵值中間以":"分隔表示,":"後面還要增加一個空格。
下面是一個舉例:
---#安裝與執行mysql服務- hosts: node1 remote_user: root tasks: - name: install mysql-server package yum: name=mysql-server state=present - name: starting mysqld service service: name=mysql state=started
我們的檔名稱應該以
.yml
結尾,像我們上面的例子就是
mysql.yml
。其中,有三個部分組成:
host部分
:使用 hosts 指示使用哪個主機或主機組來執行下面的 tasks , 每個 playbook 都必須指定 hosts ,hosts也 可以使用萬用字元格式 。主機或主機組在 inventory 清單中指定,可以使用系統預設的/etc/ansible/hosts
,也可以自己編輯,在執行的時候加上-i
選項,指定清單的位置即可。在執行清單檔案的時候,–list-hosts
選項會顯示那些主機將會參與執行 task 的過程中。
remote_user
:指定遠端主機中的哪個使用者來登入遠端系統,在遠端系統執行 task 的使用者,可以任意指定,也可以使用 sudo,但是使用者必須要有執行相應 task 的許可權。
tasks
: 指定遠端主機將要執行的一系列動作 。tasks 的核心為 ansible 的模組,前面已經提到模組的用法。tasks 包含name
和要執行的模組
, name 是可選的 ,只是為了便於使用者閱讀,不過還是建議加上去, 模組是必須的 ,同時也要給予模組相應的引數。
使用ansible-playbook執行playbook檔案,得到如下輸出資訊,輸出內容為JSON格式。並且由不同顏色組成,便於識別。一般而言
| 綠色代表執行成功,系統保持原樣
| 黃色代表系統代表系統狀態發生改變
| 紅色代表執行失敗,顯示錯誤輸出
執行有三個步驟:1、收集facts 2、執行tasks 3、報告結果
2)核心元素
Playbook的核心元素:
Hosts
:主機組;
Tasks
:任務列表;
Variables
:變數,設定方式有四種;
Templates
:包含了模板語法的文字檔案;
Handlers
:由特定條件觸發的任務;
3)基本元件
Playbooks配置檔案的基礎元件:
Hosts
:執行指定任務的目標主機
remoute_user
:在遠端主機上執行任務的使用者;
sudo_user
:
tasks
:任務列表格式:
tasks:
– name: TASK_NAME
module: arguments
notify: HANDLER_NAME
handlers:
– name: HANDLER_NAME
module: arguments
模組,模組引數
:格式:
(1) action: module arguments
(2) module: arguments
注意:shell和command模組後面直接跟命令,而非key=value類的引數列表;
handlers
:任務,在特定條件下觸發;接收到其它任務的通知時被觸發;
(1) 某任務的狀態在執行後為changed時,可透過“notify”通知給相應的handlers;
(2) 任務可以透過“tags“打標籤,而後可在ansible-playbook命令上使用-t指定進行呼叫;
舉例
① 定義playbook
[root@server ~]# cd /etc/ansible[root@server ansible]# vim nginx.yml---- hosts: web remote_user: root tasks: - name: install nginx yum: name=nginx state=present - name: copy nginx.conf copy: src=/tmp/nginx.conf dest=/etc/nginx/nginx.conf backup=yes notify: reload #當nginx.conf發生改變時,通知給相應的handlers tags: reloadnginx #打標籤 - name: start nginx service service: name=nginx state=started tags: startnginx #打標籤 handlers: #注意,前面沒有-,是兩個空格 - name: reload service: name=nginx state=restarted #為了在程式中能看出來
② 測試執行結果
寫完了以後,我們就可以執行了:
[root@server ansible]# ansible-playbook nginx.yml
現在我們可以看看兩臺機器的埠是否開啟:
[root@server ansible]# ansible web -m shell -a 'ss -nutlp |grep nginx'192.168.37.122 | SUCCESS | rc=0 >> tcp LISTEN 0 128 *:80 *:* users:(("nginx",pid=8304,fd=6),("nginx",pid=8303,fd=6))192.168.37.133 | SUCCESS | rc=0 >> tcp LISTEN 0 128 *:80 *:* users:(("nginx",pid=9671,fd=6),("nginx",pid=9670,fd=6))
③ 測試標籤
我們在裡面已經打上了一個標籤,所以可以直接引用標籤。但是我們需要先把服務關閉,再來執行劇本並引用標籤:
[root@server ansible]# ansible web -m shell -a 'systemctl stop nginx' [root@server ansible]# ansible-playbook nginx.yml -t startnginx
④ 測試notify
我們還做了一個
notify
,來測試一下:
首先,它的觸發條件是配置檔案被改變,所以我們去把配置檔案中的埠改一下:
[root@server ansible]# vim /tmp/nginx.conf listen 8080;
然後我們重新載入一下這個劇本:
發現我們執行的就是reload段以及我們定義的
notify
部分。
我們來看一看我們的埠號:
[root@server ansible]# ansible web -m shell -a 'ss -ntlp | grep nginx'192.168.37.122 | SUCCESS | rc=0 >> LISTEN 0 128 *:8080 *:* users:(("nginx",pid=2097,fd=6),("nginx",pid=2096,fd=6))192.168.37.133 | SUCCESS | rc=0 >> LISTEN 0 128 *:8080 *:* users:(("nginx",pid=3061,fd=6),("nginx",pid=3060,fd=6))
可以看出,我們的nginx埠已經變成了8080。
4)variables 部分
上文中,我們說到了
variables
是變數,有四種定義方法,現在我們就來說說這四種定義方法:
① facts :可直接呼叫
上一篇中,我們有說到
setup
這個模組,這個模組就是透過呼叫facts元件來實現的。我們這裡的
variables
也可以直接呼叫
facts
元件。
具體的
facters
我們可以使用
setup
模組來獲取,然後直接放入我們的劇本中呼叫即可。
② 使用者自定義變數
我們也可以直接使用使用者自定義變數,想要自定義變數有以下兩種方式:
透過命令列傳入
ansible-playbook
命令的命令列中的
-e VARS, --extra-vars=VARS
,這樣就可以直接把自定義的變數傳入。
在playbook中定義變數
我們也可以直接在playbook中定義我們的變數:
vars: - var1: value1 - - var2: value2
舉例
① 定義劇本
我們就使用全域性替換把我們剛剛編輯的檔案修改一下:
[root@server ansible]# vim nginx.yml
這樣一來,我們的劇本就定義完成了。
② 複製配置檔案
我們想要在被監管的機器上安裝什麼服務的話,就直接在我們的server端上把該服務的配置檔案複製到我們的
/tmp/
目錄下。這樣我們的劇本才能正常執行。
我們就以
keepalived
服務為例:
[root@server ansible]# cp /etc/keepalived/keepalived.conf /tmp/keepalived.conf
③ 執行劇本,變數由命令列傳入
[root@server ansible]# ansible-playbook nginx.yml -e rpmname=keepalived
④ 修改劇本,直接定義變數
同樣的,我們可以直接在劇本中把變數定義好,這樣就不需要在透過命令列傳入了。以後想要安裝不同的服務,直接在劇本里把變數修改一下即可。
[root@server ansible]# vim nginx.yml
⑤ 執行定義過變數的劇本
我們剛剛已經把變數定義在劇本里面了。現在我們來執行一下試試看:
[root@server ansible]# ansible-playbook nginx.yml
發現這樣也是可以的~
③ 透過roles傳遞變數
具體的,我們下文中說到 roles 的時候再詳細說明。這裡是
傳送帶
④ Host Inventory
我們也可以直接在主機清單中定義。
定義的方法如下:
向不同的主機傳遞不同的變數:
IP/HOSTNAME varaiable=value var2=value2
向組中的主機傳遞相同的變數:
[groupname:vars] variable=value
5)模板 templates
模板是一個文字檔案,巢狀有指令碼(使用模板程式語言編寫)。
Jinja2
:Jinja2是python的一種模板語言,以Django的模板語言為原本。
模板支援:
字串:使用單引號或雙引號;
數字:整數,浮點數;
列表:[item1, item2, ...]
元組:(item1, item2, ...)
字典:{key1:value1, key2:value2, ...}
布林型:true/false
算術運算:
+, -, *, /, //, %, **
比較操作:
==, !=, >, >=, <, <=
邏輯運算:
and, or, not
通常來說,模板都是透過引用變數來運用的。
舉例
① 定義模板
我們直接把之前定義的
/tmp/nginx.conf
改個名,然後編輯一下,就可以定義成我們的模板檔案了:
[root@server ansible]# cd /tmp [root@server tmp]# mv nginx.conf nginx.conf.j2 [root@server tmp]# vim nginx.conf.j2 worker_processes {{ ansible_processor_vcpus }}; listen {{ nginxport }};
② 修改劇本
我們現在需要去修改劇本來定義變數:
[root@server ansible]# vim nginx.yml
需要修改的部分如圖所示。
③ 執行劇本
上面的準備工作完成後,我們就可以去執行劇本了:
[root@server ansible]# ansible-playbook nginx.yml -t reloadnginx PLAY [web] ********************************************************************* TASK [setup] ******************************************************************* ok: [192.168.37.122] ok: [192.168.37.133] TASK [copy nginx.conf] ********************************************************* ok: [192.168.37.122] ok: [192.168.37.133] PLAY RECAP ********************************************************************* 192.168.37.122 : ok=2 changed=0 unreachable=0 failed=0 192.168.37.133 : ok=2 changed=0 unreachable=0 failed=0
6)條件測試
when語句:
在task中使用,jinja2的語法格式。
舉例如下:
tasks: - name: install conf file to centos7 template: src=files/nginx.conf.c7.j2 when: ansible_distribution_major_version == "7" - name: install conf file to centos6 template: src=files/nginx.conf.c6.j2 when: ansible_distribution_major_version == "6"
迴圈:
迭代,需要重複執行的任務;
對迭代項的引用,固定變數名為"item",而後,要在task中使用with_items給定要迭代的元素列表;
舉例如下:
tasks:- name: unstall web packages yum: name={{ item }} state=absent with_items: - httpd - php - php-mysql
7)字典
ansible playbook 還支援字典功能。舉例如下:
- name: install some packages yum: name={{ item }} state=present with_items: - nginx - memcached - php-fpm - name: add some groups group: name={{ item }} state=present with_items: - group11 - group12 - group13 - name: add some users user: name={{ item.name }} group={{ item.group }} state=present with_items: - { name: 'user11', group: 'group11' } - { name: 'user12', group: 'group12' } - { name: 'user13', group: 'group13' }
8)角色訂製:roles
① 簡介
對於以上所有的方式有個弊端就是無法實現複用假設在同時部署Web、db、ha 時或不同伺服器組合不同的應用就需要寫多個yml檔案。很難實現靈活的呼叫。
roles 用於層次性、結構化地組織playbook。roles 能夠根據層次型結構自動裝載變數檔案、tasks以及handlers等。
要使用roles只需要在playbook中使用include指令即可。簡單來講,roles就是透過分別將變數(vars)、檔案(file)、任務(tasks)、模組(modules)及處理器(handlers)放置於單獨的目錄中,並可以便捷地include它們的一種機制。角色一般用於基於主機構建服務的場景中,但也可以是用於構建守護程式等場景中。
② 角色集合
角色集合:roles/
mysql/
httpd/
nginx/
files/
:儲存由copy或script等模組呼叫的檔案;
tasks/
:此目錄中至少應該有一個名為main.yml的檔案,用於定義各task;其它的檔案需要由main.yml進行“包含”呼叫;
handlers/
:此目錄中至少應該有一個名為main.yml的檔案,用於定義各handler;其它的檔案需要由main.yml進行“包含”呼叫;
vars/
:此目錄中至少應該有一個名為main.yml的檔案,用於定義各variable;其它的檔案需要由main.yml進行“包含”呼叫;
templates/
:儲存由template模組呼叫的模板文字;
meta/
:此目錄中至少應該有一個名為main.yml的檔案,定義當前角色的特殊設定及其依賴關係;其它的檔案需要由main.yml進行“包含”呼叫;
default/
:此目錄中至少應該有一個名為main.yml的檔案,用於設定預設變數;
③ 角色定製例項
1. 在roles目錄下生成對應的目錄結構
[root@server ansible]# cd roles/ [root@server roles]# ls [root@server roles]# mkdir -pv ./{nginx,mysql,httpd}/{files,templates,vars,tasks,handlers,meta,default} [root@server roles]# tree . ├── httpd │ ├── default │ ├── files │ ├── handlers │ ├── meta │ ├── tasks │ ├── templates │ └── vars ├── mysql │ ├── default │ ├── files │ ├── handlers │ ├── meta │ ├── tasks │ ├── templates │ └── vars └── nginx ├── default ├── files ├── handlers ├── meta ├── tasks ├── templates └── vars24 directories, 0 files
2. 定義配置檔案
我們需要修改的配置檔案為
/tasks/main.yml
,下面,我們就來修改一下:
[root@server roles]# vim nginx/tasks/main.yml- name: cp copy: src=nginx-1.10.2-1.el7.ngx.x86_64.rpm dest=/tmp/nginx-1.10.2-1.el7.ngx.x86_64.rpm- name: install yum: name=/tmp/nginx-1.10.2-1.el7.ngx.x86_64.rpm state=latest- name: conf template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf tags: nginxconf notify: new conf to reload- name: start service service: name=nginx state=started enabled=true
3. 放置我們所需要的檔案到指定目錄
因為我們定義的角色已經有了新的組成方式,所以我們需要把檔案都放到指定的位置,這樣,才能讓配置檔案找到這些並進行載入。
rpm包放在
files
目錄下,模板放在
templates
目錄下:
[root@server nginx]# cp /tmp/nginx-1.10.2-1.el7.ngx.x86_64.rpm ./files/ [root@server nginx]# cp /tmp/nginx.conf.j2 ./templates/ [root@server nginx]# tree . ├── default ├── files │ └── nginx-1.10.2-1.el7.ngx.x86_64.rpm ├── handlers ├── meta ├── tasks │ └── main.yml ├── templates │ └── nginx.conf.j2 └── vars7 directories, 3 files
4. 修改變數檔案
我們在模板中定義的變數,也要去配置檔案中加上:
[root@server nginx]# vim vars/main.yml nginxprot: 9999
5. 定義handlers檔案
我們在配置檔案中定義了
notify
,所以我麼也需要定義
handlers
,我們來修改配置檔案:
[root@server nginx]# vim handlers/main.yml - name: new conf to reload service: name=nginx state=restarted
6. 定義劇本檔案
接下來,我們就來定義劇本檔案,由於大部分設定我們都單獨配置在了roles裡面,所以,接下來劇本就只需要寫一點點內容即可:
[root@server ansible]# vim roles.yml - hosts: web remote_user: root roles: - nginx
7. 啟動服務
劇本定義完成以後,我們就可以來啟動服務了:
[root@server ansible]# ansible-playbook roles.yml PLAY [web] ********************************************************************* TASK [setup] ******************************************************************* ok: [192.168.37.122] ok: [192.168.37.133] TASK [nginx : cp] ************************************************************** ok: [192.168.37.122] ok: [192.168.37.133] TASK [nginx : install] ********************************************************* changed: [192.168.37.122] changed: [192.168.37.133] TASK [nginx : conf] ************************************************************ changed: [192.168.37.122] changed: [192.168.37.133] TASK [nginx : start service] *************************************************** changed: [192.168.37.122] changed: [192.168.37.133] RUNNING HANDLER [nginx : new conf to reload] *********************************** changed: [192.168.37.122] changed: [192.168.37.133] PLAY RECAP ********************************************************************* 192.168.37.122 : ok=6 changed=4 unreachable=0 failed=0 192.168.37.133 : ok=6 changed=4 unreachable=0 failed=0
啟動過後照例檢視埠號:
[root@server ansible]# ansible web -m shell -a "ss -ntulp |grep 9999"192.168.37.122 | SUCCESS | rc=0 >> tcp LISTEN 0 128 *:9999 *:* users:(("nginx",pid=7831,fd=6),("nginx",pid=7830,fd=6),("nginx",pid=7829,fd=6))192.168.37.133 | SUCCESS | rc=0 >> tcp LISTEN 0 128 *:9999 *:* users:(("nginx",pid=9654,fd=6),("nginx",pid=9653,fd=6),("nginx",pid=9652,fd=6))
可以看出我們的劇本已經執行成功。
轉:https://www.cnblogs.com/keerya/p/8004566.html
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31383567/viewspace-2216420/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 自動化運維工具——ansible詳解(一)運維
- 自動化運維工具Ansible詳細部署運維
- Ansible自動化運維工具運維
- ansible自動化運維詳細教程及playbook詳解運維
- 自動化運維工具Ansible介紹運維
- 自動化運維 Ansible運維
- 自動化運維工具ansible的實踐運維
- [Linux]Ansible自動化運維② - 工具與模組Linux運維
- ansible自動化運維入門運維
- Ansible 運維自動化 ( 配置管理工具 )運維
- ansible自動化運維資料庫運維資料庫
- 自動化運維工具SaltStack詳細部署運維
- Ansible自動化配置詳解
- 用自動化運維工具解放IT運維運維
- Python+Django+Ansible Playbook自動化運維PythonDjango運維
- 自動化運維利器Ansible要點彙總運維
- 自動化運維工具之Puppet常用資源(二)運維
- 運維自動化工具Ansible的簡單介紹運維
- [Linux]Ansible自動化運維① - 入門知識Linux運維
- 自動化運維工具之Puppet模組運維
- 簡化IT運維工作,就要學會使用自動化運維工具!運維
- IT運維之自動化運維運維
- Python+Django+ansible playbook自動化運維專案實戰PythonDjango運維
- 自動化運維工具Saltstack學習筆記運維筆記
- 自動化運維 Expect運維
- 自動化運維工具之Puppet常用資源(一)運維
- 自動化運維工具之Puppet基礎入門運維
- Ansible自動部署工具
- 運維自動化工具對比運維
- 半自動化運維之動態新增資料檔案(二)運維
- 運維必會:基於 Ansible 的 Docker 自動化部署,小白也能看懂?運維Docker
- mysql-inception自動化運維MySql運維
- 什麼是自動化運維?為什麼選擇Python做自動化運維?運維Python
- 自動化批量管理工具pssh - 運維小結運維
- Python自動化運維工具-Fabric部署及使用總結Python運維
- 18頁PPT帶你深度解讀運維自動化運維
- 自動化運維的快速演進運維
- 自動化運維的發展方向運維