ansible基礎-roles


一 簡介

注:本文demo使用ansible2.7穩定版

在我看來,role是task文件、變量文件、handlers文件的集合體,這個集合體的顯著特點是:可移植性和可重復執行性。

實踐中,通常我們以部署某個服務為單元作為一個role ,然后將這些服務單元(role)放在一個roles目錄下。主playbook文件通過調用roles目錄下的role,來實現各種靈活多變的部署需求。

本節主要為大家介紹下roles的目錄結構、引用方法及其他特性。

二 創建與目錄結構

2.1 創建roles

通常創建一個role的方法有兩種:

  • 命令mkdir和touch行手動創建

  • 使用ansible-galaxy自動初始化一個role

命令行手動創建方式就無需多說了,即需要哪個目錄和文件就用「mkdir」和「touch」命令創建出來。

我個人比較喜歡使用「ansible-galaxy」命令創建,創建完后再刪除我不需要的目錄,這樣可以避免因手誤創建出錯的問題。

例如,我想使用「ansible-galaxy init」命令創建一個名字為role_A 的role,可以這樣寫:

➜  lab-ansible ansible-galaxy init role_A - role_A was created successfully

創建后的目錄結構如下:

➜  lab-ansible tree role_A role_A ├── defaults │ └── main.yml ├── files ├── handlers │ └── main.yml ├── meta │ └── main.yml ├── README.md ├── tasks │ └── main.yml ├── templates ├── tests │ ├── inventory │ └── test.yml └── vars └── main.yml 8 directories, 8 files

使用「ansible-galaxy」命令自動創建的role是最全的目錄結構,根據需求,可以刪除不用的目錄文件。

2.2 目錄結構

我們以上面創建的「role_A」為例,介紹下各目錄文件的作用:

  • tasks : 用於存放role_A的主要任務,也可以添加其他task文件,供main.yaml調用,從而實現更加復雜的部署功能。
  • handlers : 用於存放觸發執行( hanlders )的任務。
  • defaults : 用於存放默認變量,優先級最低,變量優先級可參考《ansible基礎-變量》。
  • vars : 用於存放變量文件,role_A中任務和模版里用到的變量可以在這里定義。
  • files :用於存放需要拷貝到目的主機的文件,例如,作為「copy」模塊src參數的默認根目錄。
  • template : 用於存放模版文件,格式為.j2,文件內容要符合Jinja2語法規則,通常使用「template」模塊部署服務的配置文件。
  • meta : 用於存放role依賴列表,這個知識點后面會詳細闡述。
  • tests : 用於存放測試role本身功能的playbook和主機定義文件,在開發測試階段比較常用。

 role中各個目錄下的main.yaml文件很重要,這是ansible默認加載的YAML文件。

三 role的引用與執行

3.1 roles語句引用

比較常用的方法,我們可以使用「roles:」語句引用role :

---
- hosts: node1 roles: - role_A

或者

---
- hosts: node1 roles: - name: role_A - name: role_A

或者

---
- hosts: node1 roles: - role: role_A - role: role_A

或者使用絕對路徑:

--- # playbooks/test.yaml - hosts: node1 roles: - role: /root/lab-ansible/roles/role_A

引入的同時添加變量參數:

--- # playbooks/test.yaml - hosts: node1 roles: - role: role_A vars: name: Maurice age: 100

引入的同時添加tag參數:

--- # playbooks/test.yaml - hosts: node1 roles: - role: role_B tags: - tag_one - tag_two # 等價於上面 - { role: role_B, tags:['tag_one','tag_two'] }

根據需求,我們在playbook中引用不同的role,引用后的效果也很好理解:ansible會把role所包含的任務、變量、handlers、依賴等加載到playbook中,順次執行。

檢索路徑

上面介紹了使用「roles」語句的引用方法,那么ansible去哪找這些role呢?

在不使用絕對路徑的情況下,ansible檢索role的默認路徑有:

  • 執行ansible-playbook命令時所在的當前目錄
  • playbook文件所在的目錄及playbook文件所在目錄的roles目錄
  • 當前系統用戶下的~/.ansible/roles目錄
  • /usr/share/ansible/roles目錄
  • ansible.cfg 中「roles_path」指定的目錄,默認值為/etc/ansible/roles目錄

注:上面的檢索路徑是在centos操作系統下測試出來的結果。

3.2 include和import引用

在后來版本(ansible>=2.4)中,ansible引入了「import_role」(靜態)和「include_role」(動態)方法:

--- # playbooks/test.yaml - hosts: node1 tasks: - include_role: name: role_A vars: name: maurice age: 100
    - import_role: name: role_B

比較於「roles」語句,「import_role」和「include_role」的優點如下:

  • 可以在task之間穿插導入某些role,這點是「roles」沒有的特性。
  • 更加靈活,可以使用「when」語句等判斷是否導入。

關於include_role(動態)和import_role(靜態)的區別,可以參考筆者之前的文章《ansible中include_tasks和import_tasks》。

也正是因為「include_task」是動態導入,當我們給「include_role」導入的role打tag時,實際並不會執行該role的task。

舉個🌰,當我們使用include導入role_A,使用import導入role_B時:

--- # playbooks/test.yaml - hosts: node1 tasks: - include_role: name: role_A tags: maurice - import_role: name: role_B tags: maurice

role_A內容如下:

--- # tasks file for role_A - debug: msg: "age"

- debug: msg: "maurice"

執行結果顯示,role_A雖然被引用,但里面的task並沒有執行: 

PLAY [node1] ************************************************************* TASK [Gathering Facts] ************************************************************* ok: [node1] TASK [include_role : role_A] ************************************************************* TASK [role_B : debug] ************************************************************* ok: [node1] => { "msg": "I'm just role_B" } PLAY RECAP ************************************************************* node1 : ok=2    changed=0    unreachable=0    failed=0

3.3 重復引用

不添加其他變量、tag等的情況下,一個playbook中對同一個role引入多次時,實際ansible只會執行一次。

例如:

--- # playbooks/test.yaml - hosts: node1 roles: - role_A - role_A

當然,我們也可以讓其運行多次,方法如下:

  • 引用role的同時定義不同的變量
  • 在meta/main.yaml中添加「allow_duplicates: true」(這個特性筆者實測未生效……)

兩種情況示例分別如下:

---
- hosts: webservers roles: - role: foo vars: message: "first"
  - { role: foo, vars: { message: "second" } }
# playbook.yml ---
- hosts: webservers roles: - foo - foo # roles/foo/meta/main.yml --- allow_duplicates: true

3.4 執行順序

筆者之前的文章《ansible基礎-playbooks》「5.執行順序」中提到,如果playbook中只有「tasks」和「roles」,ansible總是會先執行「roles」語句部分。此時可以使用「per_tasks」和「post_tasks」來規范執行順序。

在使用「per_tasks」+「roles」+「tasks」+「post_tasks」結構下,task的執行順序為:

  • per_task包含的play
  • per_task中handlers任務
  • roles語句中role列表依次執行,每個role優先執行依賴的play及任務
  • tasks語句中的所有play
  • 前兩步所觸發的handlers
  • post_tasks包含的play
  • post_tasks觸發的handlers 

四 role的依賴

role的依賴指role_A可以引入其他的role,例如role_B。

roles的依賴知識點總結如下:

  • 配置的路徑在role_A的meta/main.yaml
  • 引入role列表的方式只能使用類似「roles」語句的方法,只需將「roles」換為「dependencies」語句,不能用新版本的include和import語句
  • 在meta/main.yaml文件內可以引入多個role,且必須以列表的形式引入
  • 在引入role的同時,可以添加變量,方法同「roles」語句 

多層依賴

被引入的role總是優先執行,即便是同一個 role 被引入了多次(遵循3.3重復引用規則)。

舉個🌰:

role「car」引入了role「wheel」:

--- # roles/car/meta/main.yml dependencies: - role: wheel vars: n: 1
- role: wheel vars: n: 2
- role: wheel vars: n: 3
- role: wheel vars: n: 4

同時,role「wheel」引入了role「tire」和「brake」:

--- # roles/wheel/meta/main.yml dependencies: - role: tire - role: brake

最終的執行結果為:

tire(n=1) brake(n=1) wheel(n=1) tire(n=2) brake(n=2) wheel(n=2) ... car

五 插件和模塊

我們可以為一個role自定義模塊和插件,這部分屬於高級特性,在以后的「ansible進階」系列文章中會詳細闡述,這里只簡單介紹下。

模塊

給某個role自定義模塊,需要在這個role的目錄下創建「library」目錄,然后將自定義模塊放在該目錄下。

創建自定義模塊目錄結構示例:

roles/ my_custom_modules/ library/ module1 module2

引用的時候在「my_custom_modules」后被引用的role也可以使用該自定義模塊:

- hosts: webservers roles: - my_custom_modules - some_other_role_using_my_custom_modules - yet_another_role_using_my_custom_modules

插件

自定義插件的方法與模塊類似,需要創建的目錄為「filter_plugins」。

創建自定義插件目錄結構示例:

roles/ my_custom_filter/ filter_plugins filter1 filter2

與模塊一樣,自定義插件可以在本身role的task和模版內使用,也可以在 role「my_custom_filter」之后被引用的role內使用。

六 Ansible Galaxy

Ansible Galaxy是一個免費的roles倉庫,里面有很多社區里現成穩定的role,在生產中的部署項目中,可以直接下載下來使用。

Ansible Galaxy客戶端是「ansible-galaxy」,「ansible-galaxy」命令行可以用來初始化一個role(本文2.1 創建roles有提),也可以用來從Ansible Galaxy下載role。

關於Ansible Galaxy的詳細介紹,因篇幅原因,這里不再擴展,有興趣的同學可以去官網<https://galaxy.ansible.com/docs/>加深學習下。 

七 本節應該掌握的技能

  • 掌握role的目錄結構及其含義
  • 掌握引用role的方法
  • 掌握role的依賴及執行順序
  • 了解自定義模版和插件
  • 了解Ansible Galaxy

八 參考鏈接

  • https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html

 

歡迎大家關注我的公眾號:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM