1. 程式人生 > 其它 >三、Ansible之playbook

三、Ansible之playbook

目錄

一、Ad-Hoc問題

通過對AD-HOC的學習,我們發現AD-HOC每次只能在被管理節點上執行簡單的命令。

而日常的工作中,我們往往面臨的是一系列的複製的操作,例如我們有可能需要安裝軟體、更新配置、啟動服務等等一系列的操作的結合。此時再通過AD-HOC去完成任務就力不從心了。

在這種場景下,Ansible引入了playbook來幫我們解決這個問題。

二、playbook是什麼?

PlayBook 也被大家翻譯成劇本。

可以認為它是Ansible自定義的一門語言(可以將playbook比作Linux中的shell,而Ansible中的Module可以比作Linux中的各種命令)。

三、YAML 學習

Playbook遵循YAML語法格式。

因此在學校Playbook前,我們必須弄清楚yaml的語法。

1.YAML特點

YAML 檔案以 # 為註釋符
YAML 檔案以 .yml 或者.yaml 結尾
YAML 檔案以 --- 開始,以 ... 結束 但是開始和結束的標識都是可選的

2.基本語法

  • 大小寫敏感
  • 使用縮排表示層級關係
  • 縮排時使用Tab鍵還是空格要一定要一致,建議使用空格
  • 相同層次的元素必須左側對齊即可

YAML 支援的資料結構有三種

  • 字串
  • 列表
  • 字典

2.1 字串

---
# YAML 中的字串可以不使用引號,即使裡面存在空格的時候,當然了使用單引號和雙引號也沒有錯
this is a string
'this is a string'
"this is a string"

# YAML 中如果一行寫不下你要表述的內容的時候,可以進行折行。寫法如下:
long_line: |
    Example 1
	Example 2
	Example 3

# 或者
long_line: >
    Example 1
	Example 2
	Example 3

2.2 列表

---
# 若熟悉python的話,可以認為它就是python中的list,若熟悉 C語言的話,可以認為它是 c中的陣列
# 如何定義:以短橫線開頭 + 空格 + 具體的值
- red
- green
- blue
# 以上的值假如轉換成python中的list會是這樣:
# ['red','green','blue']

2.3 字典

---
# 若熟悉python的話,可以認為它就是python中的Dict
# 如何定義:key + 冒號(:) + 空格 + 值(value),即 key: value

name: Using Ansible
code: D1234

# 轉換為 python 的 Dict
# {'name': 'Using Ansible', 'code': 'D1234'}

2.4 混合結構

以上,針對 YAML 的所有基礎知識點就介紹完了,但日常生活中,往往需要的資料結構會特別複雜,有可能會是字串、列表、字典組合形式。

例如:
所有人都上過學,都知道學校是以班級為單位。我們去使用列表和字典的形式去描述一個班的組成。

---
class: 
  - name: stu1
    num: 001
  - name: stu2
    num: 002
  - name: stu3
    num: 003

# {'class': [{'name': 'stu1', 'num': 1 }, {'name': 'stu2', 'num':2}, ...]}

2.5 驗證 YAML 語法

# YAML 檔案,通過 python 的 YAML 模組驗證,若不正確則報錯,若正確則會輸出 YAML 裡的內容。
# 注意使用時,一定確保安裝了yaml的安裝包
python -c 'import yaml,sys; print yaml.load(sys.stdin)' < myyaml.yml
python3 -c 'import yaml,sys; print (yaml.load(sys.stdin))' < myyaml.yml

練習

# 正確的情況
# cat myyaml.yml
---
- red
- green
- blue

...
[root@ansible-01 ~]# python -c 'import yaml,sys; print yaml.safe_load(sys.stdin)' < myyaml.yml
['red', 'green', 'blue']

# 錯誤的情況下
# cat myyaml.yml
---
- red
- green
-blue

[root@ansible-01 ~]# python -c 'import yaml,sys; print yaml.safe_load(sys.stdin)' < myyaml.yml
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib64/python2.7/site-packages/yaml/__init__.py", line 93, in safe_load
    return load(stream, SafeLoader)
  File "/usr/lib64/python2.7/site-packages/yaml/__init__.py", line 71, in load
    return loader.get_single_data()
  File "/usr/lib64/python2.7/site-packages/yaml/constructor.py", line 37, in get_single_data
    node = self.get_single_node()
  File "/usr/lib64/python2.7/site-packages/yaml/composer.py", line 36, in get_single_node
...

四、playbook的編寫

1. play的定義

由於playbook是由一個或者多個play組成,那麼如果我們熟悉play的寫法,就自然掌握了我們這章內容

那麼如何定義play呢?
1、每個play都是以短橫槓開始的
2、每一個play都是一個YAML字典格式

根據上面兩條play的規則,一個假象的play應該是下面的樣子

---
- key1: value1
- key2: value2
- key3: value3
....

由於一個playbook是由一個或者多個play構成,那麼一個含有多個play的playbook 結構上應該是如下的樣子

---
# 一個含有3個play的偽playbook構成
- key1: value1
  key2: value2
  key3: value3
- key4: value1
  key5: value2
  key6: value3
- key1: value1
  key2: value2
  key3: calue3
  ...

2. play的屬性

常用屬性

  • name 屬性:每個play的名字
  • hosts 屬性:每個play涉及的被管理伺服器,同ad hoc 中的資產選擇器
  • tasks 屬性:每個play中具體要完成的任務,以列表形式表達
  • become 屬性:如果需要提權,則加上become屬性
  • become_user 屬性:若提權的話,提到哪個使用者
  • remote_user 屬性:指定連線到遠端節點的使用者,就是在遠端伺服器上執行具體操作的使用者,若不指定,則預設使用當前執行ansible playbook的使用者

3. 一個完整劇本

下面來看一個含有play的playbook應該是下面這樣的

---
- name: the first play example
  hosts: all
  remote_user: root
  tasks:
    - name: install nginx package
	  yum : name=nginx state=present
	- name: copy nginx.conf to remote server
	  copy: src=nginx.conf dest=/etc/nginx/nginx.conf
	- name: start nginx server
	  service: 
	    name: nginx 
		enabled: true/yes
		state: started

4. tasks 屬性中任務的多種寫法

# 以啟動 nginx 服務,並加入開機自啟為例

# 一行的形式
service: name=nginx enabled=true statu=started

# 多行形式
service: name=nginx
         enalbed=true
		 state=started
 
# 多行寫成字典的形式
service:
  name: nginx
  enabled: true
  state: started

5. 具有多個play的playbook

---
- name: manage web servers
  hosts: webservers
  remote_user: root
  tasks:
    - name: install nginx package
	  yum: name=nginx state=present
	- name: copy nginx.conf to remote server
	  copy: src=nginx.conf dest=/tmp/nginx/nginx.conf
	- name: start nginx server
	  service:
	    name: nginx
		enabled: yes|true
		state: started

- name: manager db servers
  hosts: db_servers
  tasks:
    -name: update database confg
	  copy: src=my.conf dest=/etc/my.conf
...

6. 如何對playbook進行語法校驗

# ansible-playbook - hosts myplaybook.yml --syntax-check

因為Playbook屬於YAML格式,我們同樣可以檢查YAML語法格式的方法進行檢查playbook的語法的正確性

7. 如何允許playbook

# ansible-playbook -i hosts myyaml.yml

8. 如何單步跟從除錯playbook

# 執行task中的任務,需要手動確認是否往下執行
ansible-playbook -i hosts  my_nginx.yml --step

9. 如何測試允許playbook

# 執行完整的playbook,但是使用Task上的行為都不會在遠端伺服器上執行,所有執行都是模擬行為
ansible-playbook -i hosts  my_nginx.yml -C
-C 為大寫字母C