Ansible 角色管理指南
實驗環境設置
以下命令用于準備實驗環境,創建一個工作目錄并配置基本的Ansible設置:
# 創建web工作目錄并進入
[azurewhisky@controller ~]$ mkdir web && cd web# 創建Ansible配置文件
[azurewhisky@controller web]$ cat > ansible.cfg <<'EOF'
[defaults]
remote_user = azurewhisky # 設置遠程登錄用戶名
inventory = ./inventory # 指定清單文件位置[privilege_escalation]
become = True # 啟用權限提升
become_user = root # 提升到root用戶
become_method = sudo # 使用sudo方法
become_ask_pass = False # 不詢問密碼
EOF# 創建主機清單文件
[azurewhisky@controller web]$ cat > inventory <<'EOF'
controller
node1
node2
node3
node4
EOF
Ansible 角色詳解
什么是Ansible角色?
在實際生產環境中,Playbook往往會變得很長且復雜,包含許多文件、任務和處理程序。隨著編寫的Playbook越來越多,我們會發現有很多機會可以復用之前編寫的代碼。
Ansible角色提供了一種標準化方式來打包和復用自動化代碼。它將任務、變量、文件、模板等資源組織在一個標準化的目錄結構中,只需將角色從一個項目復制到另一個項目,然后在Playbook中調用即可。
Ansible角色結構
通過以下命令可以初始化一個標準的Ansible角色:
[azurewhisky@controller web]$ ansible-galaxy init azurewhisky
- azurewhisky was created successfully# 查看角色目錄結構
[azurewhisky@controller web]$ tree azurewhisky
azurewhisky
├── defaults # 默認變量目錄(低優先級)
│ └── main.yml
├── files # 靜態文件目錄
├── handlers # 處理程序目錄
│ └── main.yml
├── meta # 元數據目錄
│ └── main.yml
├── README.md # 角色說明文檔
├── tasks # 任務目錄
│ └── main.yml
├── templates # 模板目錄
├── tests # 測試目錄
│ ├── inventory
│ └── test.yml
└── vars # 變量目錄(高優先級)└── main.yml8 directories, 8 files
各目錄用途說明:
- defaults:包含角色變量的默認值(低優先級,易被覆蓋)
- files:存放角色任務引用的靜態文件
- handlers:包含角色的處理程序定義
- meta:包含角色元信息(作者、許可證、依賴等)
- tasks:包含角色的主要任務定義
- templates:存放Jinja2模板文件
- tests:包含測試用的清單和Playbook
- vars:定義角色變量(高優先級,用于內部功能)
- README.md:角色使用說明文檔
角色存放位置
Ansible默認在以下位置查找角色:
~/.ansible/roles
/usr/share/ansible/roles
/etc/ansible/roles
優先級從上到下遞減。可以通過配置文件自定義角色路徑:
# 在ansible.cfg中設置角色路徑
[defaults]
roles_path = ./roles # 相對路徑示例# 多個路徑用冒號分隔
roles_path = /etc/ansible/roles:/home/azurewhisky/web/roles
創建自定義角色
下面創建一個Apache Web服務器角色的完整示例:
# 創建角色目錄并初始化Apache角色
[azurewhisky@controller web]$ mkdir roles
[azurewhisky@controller web]$ ansible-galaxy init apache --init-path=./roles
配置任務文件
# roles/apache/tasks/main.yml
---
# Apache角色任務文件
- name: 安裝Web服務器yum:name: "{{ web_package }}" # 使用變量指定軟件包名state: latest- name: "啟動{{ web_service }}服務"service:name: "{{ web_service }}" # 使用變量指定服務名state: startedenabled: yes # 設置開機自啟- name: 配置登錄提示信息template:src: motd.j2 # 源模板文件dest: /etc/motd # 目標文件位置- name: 配置AzureWhisky站點template:src: azurewhisky.conf.j2 # 虛擬主機配置模板dest: /etc/httpd/conf.d/azurewhisky.confnotify:- 重啟Web服務 # 觸發處理程序- name: 創建網站根目錄file:path: "/var/www/html/{{ ansible_hostname }}" # 使用主機名創建目錄state: directory- name: 創建首頁文件template:src: index.html.j2 # 首頁模板dest: "/var/www/html/{{ ansible_hostname }}/index.html"
配置默認變量
# roles/apache/defaults/main.yml
---
# Apache角色默認變量
web_package: httpd # Web服務器軟件包名
web_service: httpd # Web服務名稱
創建模板文件
{# roles/apache/templates/motd.j2 #}
hello guys!
Welcome to {{ ansible_fqdn }}! {# 使用事實變量填充完全限定域名 #}
{# roles/apache/templates/azurewhisky.conf.j2 #}
# {{ ansible_managed }} {# Ansible管理標記 #}
<VirtualHost *:80>ServerAdmin azurewhisky@{{ ansible_fqdn }}ServerName {{ ansible_fqdn }}ErrorLog logs/{{ ansible_hostname }}-error.logCustomLog logs/{{ ansible_hostname }}-common.log commonDocumentRoot /var/www/html/{{ ansible_hostname }}/<Directory /var/www/html/{{ ansible_hostname }}/>Options +Indexes +FollowSymlinks +IncludesOrder allow,denyAllow from all</Directory>
</VirtualHost>
配置處理程序
# roles/apache/handlers/main.yml
---
# Apache角色處理程序
- name: 重啟Web服務service:name: "{{ web_service }}"state: restarted
創建首頁模板
{# roles/apache/templates/index.html.j2 #}
Welcome to {{ ansible_fqdn }} !
配置角色元數據
---
galaxy_info:author: azurewhiskydescription: azurewhisky的Web服務器角色company: azurewhisky世界license: GPLv2min_ansible_version: 2.4platforms:- name: Fedoraversions:- all- 25galaxy_tags: [apache, web] # 角色標簽
dependencies: [] # 角色依賴項
調用角色
在Playbook中調用角色非常簡單:
# 基本調用方式
---
- name: 部署Apachehosts: node1roles:- apache # 直接引用角色名# 帶參數調用方式
---
- name: 部署Apachehosts: node1roles:- role: apache # 明確指定角色web_package: httpd # 傳遞參數web_service: httpd- { role: apache, web_package: httpd, web_service: httpd } # 簡寫格式
執行Playbook并驗證結果:
# 驗證motd配置
[azurewhisky@controller web]$ ssh root@node1
hello guys!
Welcome to node1.lab.example.com!# 驗證網站訪問
[root@node1 ~]$ curl http://node1/
Welcome to node1.azurewhisky.top !
角色依賴關系
角色可以聲明依賴其他角色,例如Web服務器角色可能依賴防火墻角色:
# roles/apache/meta/main.yml
dependencies:
- role: firewallservice: http # 傳遞參數給依賴角色
創建防火墻角色:
[azurewhisky@controller web]$ ansible-galaxy init firewall --init-path=./roles
配置防火墻角色任務:
# roles/firewall/tasks/main.yml
---
# 防火墻角色任務
- name: 安裝firewalldyum:name: firewalldstate: latest- name: 啟動并啟用firewalld服務service:name: firewalldstate: startedenabled: true- name: 配置防火墻服務firewalld:state: enabled # 啟用規則immediate: true # 立即生效permanent: true # 永久生效service: "{{ service }}" # 使用變量指定服務
配置防火墻默認變量:
# roles/firewall/defaults/main.yml
---
# 防火墻默認變量
service: ssh # 默認允許SSH服務
任務執行順序
Ansible按照特定順序執行任務:
pre_tasks
- 前置任務roles
- 角色任務tasks
- 普通任務post_tasks
- 后置任務
注意:劇本中的書寫順序不影響實際執行順序。
示例演示:
---
- name: 測試任務執行順序hosts: node1gather_facts: false # 禁用事實收集pre_tasks:- name: 前置任務shell: echo '這是前置任務'roles:- test_task_exec_order # 調用測試角色tasks:- name: 普通任務shell: echo '這是普通任務'post_tasks:- name: 后置任務shell: echo '這是后置任務'
處理程序執行順序
處理程序按照以下順序執行:
- pre_tasks通知的處理程序
- roles任務
- roles通知的處理程序
- tasks任務
- tasks通知的處理程序
- post_tasks任務
- post_tasks通知的處理程序
重要:劇本中的處理程序具有全局作用域,可以被任何任務通知。
動態角色調用
使用include_role
和import_role
在任務中動態調用角色:
---
- hosts: node1tasks:- shell: echo '第一個任務'- name: 在任務中調用角色import_role: # 或使用include_rolename: hellowhen: condition_met # 條件判斷
區別說明:
import_role
:執行前解析角色,語法錯誤會立即終止include_role
:執行時解析角色,條件為false時不解析
Ansible角色的優勢
- 標準化:為系統類型(Web服務器、數據庫等)定義標準配置
- 并行開發:多個管理員可以同時開發不同角色
- 代碼復用:輕松共享和復用自動化代碼
- 易于管理:使大型項目更易于維護和組織
角色開發最佳實踐
- 避免敏感信息:不要將密碼或密鑰存儲在角色中,使用變量參數化
- 精簡結構:使用
ansible-galaxy init
創建角色,刪除不需要的目錄 - 完善文檔:維護README.md和meta/main.yml文件說明角色用途
- 功能專注:每個角色應專注于特定功能,避免過于復雜
- 代碼重構:經常重用和重構角色,避免為邊緣情況創建新角色
- 版本控制:使用版本控制系統管理角色演變
使用系統角色
系統角色介紹
RHEL從7.4開始提供預打包的系統角色,這些角色可以幫助標準化RHEL主機的配置。例如,使用timesync角色可以統一配置RHEL6和7的時間同步,無需關心底層是ntpd還是chronyd服務。
安裝系統角色
[azurewhisky@controller ~]$ sudo yum install -y rhel-system-roles# 系統角色安裝在標準位置
[azurewhisky@controller ~]$ ls -1 /usr/share/ansible/roles/# 文檔位于
[azurewhisky@controller ~]$ ls /usr/share/doc/rhel-system-roles
時間同步角色示例
---
- name: 時間同步配置hosts: node1vars:timesync_ntp_servers:- hostname: classroom.example.comiburst: yes # 啟用快速初始同步timezone: "Asia/Shanghai" # 設置時區roles:- rhel-system-roles.timesync # 調用系統角色tasks:- name: 設置時區timezone:name: "{{ timezone }}"
SELinux角色示例
---
- name: SELinux配置hosts: node1vars:selinux_state: enforcing # 設置強制模式selinux_booleans:- name: 'httpd_enable_homedirs'state: 'on'persistent: 'yes' # 永久生效selinux_fcontexts:- target: '/srv/www(/.*)?'setype: 'httpd_sys_content_t'state: 'present'roles:- rhel-system-roles.selinux
處理需要重啟的SELinux配置
---
- hosts: node1,node2vars:selinux_state: enforcingtasks:- block: # 塊錯誤處理- name: 應用SELinux角色include_role:name: rhel-system-roles.selinuxrescue: # 救援塊- name: 檢查是否需要重啟以外的錯誤fail:when: not selinux_reboot_required- name: 重啟受管主機reboot:- name: 重新應用SELinux角色include_role:name: rhel-system-roles.selinux
使用Ansible Galaxy部署角色
Ansible Galaxy介紹
Ansible Galaxy是一個由社區維護的角色倉庫,包含大量可重用的角色,幫助用戶快速實現自動化任務。
ansible-galaxy命令使用
# 查看已安裝角色
[azurewhisky@controller web]$ ansible-galaxy list# 搜索角色(需要網絡連接)
[azurewhisky@controller ~]$ ansible-galaxy search --platforms=EL haproxy# 查看角色詳細信息
[azurewhisky@controller ~]$ ansible-galaxy info geerlingguy.docker# 查看本地角色信息
[azurewhisky@controller web]$ ansible-galaxy info apache --offline# 安裝角色
[azurewhisky@controller ~]$ ansible-galaxy install geerlingguy.haproxy
批量安裝角色
創建requirements.yml文件:
# requires.yml
- name: dockersrc: https://github.com/geerlingguy/ansible-role-docker/archive/2.7.0.tar.gz
- name: haproxysrc: https://github.com/geerlingguy/ansible-role-haproxy/archive/1.1.2.tar.gz
批量安裝:
[azurewhisky@controller ~]$ ansible-galaxy install -r requires.yml
其他管理命令
# 登錄Galaxy
[azurewhisky@controller ~]$ ansible-galaxy login# 刪除角色
[azurewhisky@controller ~]$ ansible-galaxy remove role_name# 登出
[azurewhisky@controller ~]$ ansible-galaxy logout
綜合案例:部署Web集群
需求說明
- node3作為負載均衡器(HAProxy)
- node1和node2作為Web服務器
實施步驟
# 創建清單文件
[azurewhisky@controller web]$ cat > inventory <<EOF
[loadbalancers]
loadbalancer ansible_host=node3[webservers]
node1
node2
EOF# 安裝所需角色
[azurewhisky@controller web]$ ansible-galaxy install geerlingguy.haproxy
[azurewhisky@controller web]$ ansible-galaxy install geerlingguy.apache# 查看HAProxy角色文檔了解配置參數
[azurewhisky@controller web]$ less roles/geerlingguy.haproxy/README.md
編寫部署劇本
# deploy_web_cluster.yaml
---
- name: 部署負載均衡器hosts: loadbalancersvars:haproxy_backend_servers: # 配置后端服務器- name: node1address: 10.1.8.11:80 # node1的IP和端口- name: node2address: 10.1.8.12:80 # node2的IP和端口roles:- geerlingguy.haproxy # 調用HAProxy角色- name: 部署Web服務器hosts: webserversroles:- geerlingguy.apache # 調用Apache角色tasks:- name: 創建首頁內容copy:content: "Welcome to {{ ansible_fqdn }}.\n" # 動態生成內容dest: /var/www/html/index.html
執行部署并驗證
# 運行部署劇本
[azurewhisky@controller web]$ ansible-playbook deploy_web_cluster.yaml# 測試負載均衡效果
[azurewhisky@controller web]$ curl http://node3/
Welcome to node1.azurewhisky.top.
[azurewhisky@controller web]$ curl http://node3/
Welcome to node2.azurewhisky.top.
通過這個完整的指南,您應該對Ansible角色管理有了深入的理解,能夠創建、使用和管理角色,以及利用Ansible Galaxy中的社區資源來加速自動化部署。