Ansible 角色管理
實驗環境
[lth@controller ~ 21:47:45]$ mkdir web && cd web[lth@controller web 21:47:50]$ cat > ansible.cfg <<'EOF'
[defaults]
remote_user = lth
inventory = ./inventory[privilege_escalation]
become = True
become_user = root
become_method = sudo
become_ask_pass = False
EOF[lth@controller web 21:47:58]$ cat > inventory <<'EOF'
controller
node1
node2
node3
node4
EOF
Ansible 角色
Ansible 角色介紹
Ansible 角色(Role)是一種用于組織和復用 Ansible 代碼的結構化方式,能將復雜的任務、變量、模板等按功能模塊拆分,提高劇本的可維護性和復用性。以下是其核心特點和組成部分的分點介紹:
角色的核心作用
- 代碼復用:將常用功能(如安裝 Web 服務器、配置數據庫)封裝為角色,可在多個劇本(Playbook)中重復調用,避免重復編寫代碼。
- 結構標準化:通過固定的目錄結構,使 Ansible 項目更清晰,便于團隊協作和后期維護。
- 簡化 Playbook:在 Playbook 中只需通過
roles
關鍵字引用角色,無需編寫冗長的任務列表,提升劇本可讀性。
Ansible 角色結構
一個典型的角色目錄包含以下子目錄和文件(按功能分類):
tasks/
:存放核心任務文件(main.yml
是入口,可通過它引入其他任務文件),定義角色要執行的操作(如安裝軟件、修改配置)。handlers/
:存放 handlers(觸發器)文件(main.yml
為入口),用于響應任務中的notify
指令(如服務重啟、配置重載)。vars/
:存放角色專屬變量(main.yml
為入口),優先級低于 Playbook 中定義的變量,用于角色內部參數配置。defaults/
:存放默認變量(main.yml
為入口),優先級最低,可被其他地方的變量覆蓋,適合定義角色的默認參數。templates/
:存放 Jinja2 模板文件(如配置文件模板),可通過變量動態生成內容。files/
:存放靜態文件(如腳本、證書),可直接被任務引用或復制到目標主機。meta/
:存放角色元數據(main.yml
為入口),如作者、版本、依賴角色等,用于角色管理和依賴處理。tests/
:存放測試相關文件(如測試用 Playbook),用于驗證角色功能。README.md
:提供人類可讀的基本角色描述、有關如何使用該角色的文檔和示例,以及其發揮作用所需要滿足的任何非Ansible要求。
說明:并非每個角色都擁有所有目錄,部分目錄可以省略。
示例:
[lth@controller web 22:10:07]$ ansible-galaxy init lth
- lth was created successfully
[lth@controller web 22:10:10]$ tree lth
lth
├── 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
Ansible 角色目錄位置
默認role使用以下三個目錄:
- ~/.ansible/roles
- /usr/share/ansible/roles
- /etc/ansible/roles
優先級從上到下依次降低。
可以在ansible.cfg配置文件[defaults]塊中通過變量roles_path定義role位置:
[defaults]
roles_path = ./roles
......
多個路徑使用冒號分隔:
roles_path = /etc/ansible/roles:/home/student/web/roles
創建角色
[lth@controller web 22:19:32]$ mkdir roles
[lth@controller web 22:19:34]$ ansible-galaxy init apache
- apache was created successfully
[lth@controller web 22:19:39]$ mv apache/ roles
# 也可以直接使用以下命令將角色放置到指定目錄
[lth@controller web 22:19:47]$ ansible-galaxy init apache --init-path=./roles# 查看角色列表
[lth@controller web 22:19:52]$ ansible-galaxy list
# /home/student/web/roles
- apache, (unknown version)
[lth@controller web 22:19:58]$ cd roles/apache/
[lth@controller apache 22:20:10]$
# 核心任務邏輯:安裝、啟動、配置、創建目錄和首頁
[lth@controller apache 22:20:20]$ vim tasks/main.yml
[lth@controller apache 22:20:23]$ cat tasks/main.yml
---
# tasks file for apache
# 1. 安裝 Apache 軟件包(默認為 httpd)
- name: install webyum:name: "{{ web_package }}" # 使用變量,便于修改state: latest # 確保安裝最新版本# 2. 啟動并設置 Apache 開機自啟
- name: "start {{ web_service }}"service:name: "{{ web_service }}" # 服務名(默認為 httpd)state: started # 確保服務已啟動enabled: yes # 開機自動啟動# 3. 渲染 motd 模板,更新 /etc/motd 歡迎信息
- name: prepare motdtemplate:src: motd.j2 # 模板文件路徑(位于 templates/)dest: /etc/motd # 渲染后生成的目標文件# 4. 渲染 Apache 虛擬主機配置
- name: prepare lth sitetemplate:src: lth.conf.j2 # 虛擬主機配置模板dest: /etc/httpd/conf.d/lth.confnotify: # 如果文件有變化,觸發 handlers- restart_web# 5. 創建站點目錄(以主機名區分,避免沖突)
- name: prepare DocumentRoot file:path: "/var/www/html/{{ ansible_hostname }}" # 每臺主機單獨目錄state: directory # 確保存在目錄# 6. 渲染首頁 index.html
- name: prepare index.htmltemplate:src: index.html.j2 # 首頁模板dest: "/var/www/html/{{ ansible_hostname }}/index.html"
# 定義默認變量defaults/main.yml,便于在 tasks 中引用
[lth@controller apache 22:31:14]$ vim defaults/main.yml
[lth@controller apache 22:31:24]$ cat defaults/main.yml
---
# defaults file for apache
# 定義默認軟件包和服務名稱,方便在 tasks 中調用
web_package: httpd # Apache 軟件包
web_service: httpd # Apache 服務名# 編寫templates/motd.j2
[lth@controller apache 22:32:12]$ vim templates/motd.j2
[lth@controller apache 22:32:16]$ cat templates/motd.j2
hello guys!
Welcome to {{ ansible_fqdn }}!# 編寫templates/lth.conf.j2
[lth@controller apache 22:32:18]$ vim templates/lth.conf.j2
[lth@controller apache 22:32:24]$ cat templates/lth.conf.j2
# {{ ansible_managed }}
<VirtualHost *:80>ServerAdmin lth@{{ 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># 定義handlers/main.yml ,當配置文件變化時執行
[lth@controller apache 22:34:26]$ vim handlers/main.yml
[lth@controller apache 22:34:29]$ cat handlers/main.yml
---
# handlers file for apache
- name: restart_webservice:name: "{{ web_service }}" # 使用變量,默認為 httpdstate: restarted # 重啟 Apache 服務# 模板文件:系統歡迎信息(motd):templates/index.html.j2
[lth@controller apache 22:34:43]$ vim templates/index.html.j2
[lth@controller apache 22:34:47]$ cat templates/index.html.j2
Welcome to {{ ansible_fqdn }} !# 定義meta/main.yml
[lth@controller apache 22:34:54]$ vim meta/main.yml
[lth@controller apache 22:34:59]$ cat meta/main.yml
---
galaxy_info:author: lthdescription: lth webcompany: lth worldlicense: license (GPLv2, CC-BY, etc)min_ansible_version: 2.4platforms:- name: Fedoraversions:- all- 25- name: SomePlatformversions:- allgalaxy_tags: [apache,web]
dependencies: []
調用角色
[lth@controller web 22:38:39]$ vim playbook.yml
[lth@controller web 22:38:49]$ cat playbook.yml
---
- name: deploy apachehosts: node2roles:- apache# 執行
[lth@controller web 22:38:57]$ ansible-playbook playbook.yml PLAY [deploy apache] ********************************************************************************TASK [Gathering Facts] ******************************************************************************
ok: [node2]TASK [apache : install web] *************************************************************************
ok: [node2]TASK [apache : start httpd] *************************************************************************
ok: [node2]TASK [apache : prepare motd] ************************************************************************
changed: [node2]TASK [apache : prepare lth site] *******************************************************************
changed: [node2]TASK [apache : prepare DocumentRoot] ****************************************************************
changed: [node2]TASK [apache : prepare index.html] ******************************************************************
changed: [node2]RUNNING HANDLER [apache : restart_web] **************************************************************
changed: [node2]PLAY RECAP ******************************************************************************************
node2 : ok=8 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 # 驗證motd文件
[lth@controller web 22:40:58]$ ssh root@node1
Last login: Tue Aug 22:40:58 2025 from 10.1.8.10
hello guys!
Welcome to node1.xiexin.cloud !# 驗證web
[root@node1 ~]# curl http://node1/
Welcome to node1.xiexin.cloud !
使用系統角色
系統角色介紹
RHEL 系統角色(由 rhel-system-roles
軟件包提供)是 Red Hat 為標準化 RHEL 主機配置推出的 Ansible 角色集合,核心要點如下:
- 版本支持:自 RHEL 7.4 起引入,RHEL 8 中可從 AppStream 頻道獲取,適用于 RHEL 6.10 及以上版本的所有主機。
- 核心價值:通過統一的角色抽象,解決不同 RHEL 版本間的配置差異。例如,RHEL 6 推薦 ntpd 服務、RHEL 7 推薦 chronyd 服務,管理員無需分別維護兩種配置文件,只需通過
rhel-system-roles.timesync
角色,即可用同一套 YAML 變量為混合版本環境定義時間同步規則。 - 本質作用:以標準化方式簡化跨版本 RHEL 主機的系統配置(如時間同步、網絡、防火墻等),減少版本差異帶來的運維復雜度,提升配置一致性和效率。
系統角色安裝和說明
[lth@controller web 22:46:33]$ sudo yum install -y rhel-system-roles# RHEL系統角色位于/usr/share/ansible/roles/
[lth@controller web 22:46:39]$ ls -1 /usr/share/ansible/roles/# Ansible默認roles_path包含/usr/share/ansible/roles,可以直接引用這些角色。# 系統角色的文檔位于/usr/share/doc/rhel-system-roles
[lth@controller web 22:46:46]$ ls /usr/share/doc/rhel-system-roles# 每個角色的文檔目錄均包含一個README.md文件。
# README.md文件含有角色的說明,以及角色用法信息。
# README.md文件也會說明影響角色行為的角色變量。
# README.md文件中含有playbook代碼片段,用于演示常見配置場景的變量設置。
角色使用案例-timesync
使用 Ansible 的系統角色(system roles)來管理 NTP 時間同步服務。
[lth@controller web 22:46:58]$ vim ansible.cfg
[lth@controller web 22:47:16]$ cat ansible.cfg
[defaults]
inventory = ./inventory
remote_user = lth
vault_password_file = ./password-for-vault
roles_path = ./roles:/usr/share/ansible/roles/
#設置了角色搜索路徑,保證 Ansible 可以找到系統角色和本地自定義角色。
#ask_pass = True
#module_name = command
#private_key_file = /opt/id_rsa
#host_key_checking = False[privilege_escalation]
become=True
become_method=sudo
become_user=root
become_ask_pass=False# playbook內容取自如下
[lth@controller web 22:48:34]$ vim /usr/share/ansible/roles/rhel-system-roles.timesync/README.md # 調用了 rhel-system-roles.timesync 角色,自動配置時間同步服務。
# 通過變量 timesync_ntp_servers 指定 NTP 服務器(這里是 ntp.aliyun.com)。
# 角色內部會根據變量去修改系統配置(如 /etc/chrony.conf 或 /etc/ntp.conf),啟動時間同步服務,并確保服務開機自啟。
[lth@controller web 22:49:44]$ vim playbook.yml
[lth@controller web 22:49:48]$ cat playbook.yml
- name: Manage timesync with 1 servershosts: allvars:timesync_ntp_servers:- hostname: ntp.aliyun.comiburst: trueroles:- rhel-system-roles.timesync# 執行
# Ansible 會在所有目標主機上執行系統角色 tasks,實現 自動化時間同步配置。
[lth@controller web 22:50:54]$ ansible-playbook playbook.yml
使用 ANSIBLE GALAXY 部署角色
ANSIBLE GALAXY
Ansible Galaxy 是 Ansible 官方提供的一個角色(Roles)管理平臺和社區生態系統,主要用于分享、發現和管理 Ansible 角色,核心功能和特點如下:
- 核心定位
- 作為 Ansible 角色的 “倉庫”,匯集了由官方、企業及社區開發者貢獻的大量預定義角色,涵蓋從基礎服務配置(如 Web 服務器、數據庫)到復雜應用部署(如 Kubernetes、監控系統)等場景。
- 提供標準化的角色管理機制,方便用戶查找、下載、共享和版本控制角色。
- 主要功能
-
角色發現與下載:用戶可通過關鍵詞搜索(如 “nginx”“mysql”)找到所需角色,通過ansible-galaxy install命令直接下載到本地使用。
# 示例:安裝社區維護的 nginx 角色 ansible-galaxy install geerlingguy.nginx
-
角色發布與分享:開發者可將自己編寫的角色上傳至 Galaxy,供社區復用,支持版本管理和更新。
-
依賴管理:角色可在元數據(
meta/main.yml
)中定義依賴關系,安裝時會自動下載依賴的角色。 -
評分與質量標識:社區用戶可對角色評分,平臺會通過 “質量分數” 標識角色的標準化程度(如是否包含文檔、測試用例等),幫助用戶選擇高質量角色。
- 優勢與價值
- 降低開發成本:無需從零編寫角色,直接復用社區成熟角色,加速 Playbook 開發。
- 促進最佳實踐:優質角色通常遵循 Ansible 最佳實踐和行業標準配置,提升自動化腳本的可靠性。
- 社區協作:連接全球 Ansible 用戶和開發者,形成活躍的生態,推動角色迭代和問題解決。
- 與 RHEL 系統角色的關系
- Ansible Galaxy 是通用的角色社區平臺,包含各類場景的角色;而 RHEL 系統角色是 Red Hat 官方針對 RHEL 系統推出的專用角色,通常也會在 Galaxy 上發布。
- 用戶可同時使用 Galaxy 社區角色和 RHEL 系統角色,根據場景靈活選擇。
通過 Ansible Galaxy,用戶可以快速構建基于角色的自動化體系,充分利用社區資源提升運維效率。
ansible-galaxy 命令
[lth@controller web 22:54:49]$ ansible-galaxy -h
usage: ansible-galaxy [-h] [--version] [-v] TYPE ...Perform various Role and Collection related operations.positional arguments:TYPEcollection Manage an Ansible Galaxy collection.role Manage an Ansible Galaxy role.options:--version show program's version number, config file location, configuredmodule search path, module location, executable location and exit-h, --help show this help message and exit-v, --verbose Causes Ansible to print more debug messages. Adding multiple -vwill increase the verbosity, the builtin plugins currentlyevaluate up to -vvvvvv. A reasonable level to start is -vvv,connection debugging might require -vvvv. This argument may bespecified multiple times.
[lth@controller web 22:55:36]$ ansible-galaxy role -h
usage: ansible-galaxy role [-h] ROLE_ACTION ...positional arguments:ROLE_ACTIONinit Initialize new role with the base structure of a role.remove Delete roles from roles_path.delete Removes the role from Galaxy. It does not remove or alter the actualGitHub repository.list Show the name and version of each role installed in the roles_path.search Search the Galaxy database by tags, platforms, author and multiplekeywords.import Import a role into a galaxy serversetup Manage the integration between Galaxy and the given source.info View more details about a specific role.install Install role(s) from file(s), URL(s) or Ansible Galaxyoptions:-h, --help show this help message and exit
ansible-galaxy role
命令可以簡寫為 ansible-galaxy
。以下示例采用簡寫格式。
綜合案例:部署 web 集群
- 準備自動化工具:通過 Ansible Galaxy 獲取現成角色,包括用于一鍵部署 Apache Web 服務的
geerlingguy.apache
和用于安裝配置 HAProxy 負載均衡器的 haproxy 角色。使用ansible-galaxy install
命令下載到本地后,對 haproxy 角色文件夾進行重命名,方便后續在劇本中引用。 - 明確機器分組與分工:在 inventory(“通訊錄”)文件中,將機器分為兩組——LBs 組(僅 controller 機器,作為負載均衡器)和 WEBs 組(node1 到 node4 四臺機器,作為 Web 服務器節點),使 Ansible 能清晰區分任務執行對象。
- 編寫任務劇本(Playbook): - 針對 LBs 組(controller):通過 haproxy 角色部署負載均衡,并配置后端 4 個 Web 節點的地址(10.1.8.11 至 10.1.8.14,端口均為 80)。 - 針對 WEBs 組(node1 - node4):通過 apache 角色在每臺機器上安裝配置 Apache 服務,確保其能提供網站服務。
- 預處理與執行任務:先通過
ansible
命令批量關閉并禁用目標機器上的 nginx 服務,避免沖突;再運行ansible-playbook playbook.yml
,Ansible 會自動按劇本在對應機器上執行部署任務,無需手動登錄操作。 - 驗證負載均衡效果:多次訪問
http://controller
(負載均衡器地址),可見請求被 HAProxy 自動分發到不同 Web 節點,分別顯示 node1 至 node4 的歡迎語,說明負載均衡生效,實現了訪問請求的均勻分配。 整個過程體現了 Ansible 自動化的優勢:復用現成角色,配合簡單的劇本和清單配置,即可快速搭建復雜服務架構,減少人工操作和出錯概率。
演示:
[lth@controller web 23:02:22]$ ansible-galaxy role search --author geerlingguy apacheFound 2 roles matching your search:Name Description---- -----------geerlingguy.apache Apache 2.x for Linux.geerlingguy.apache-php-fpm Apache 2.4+ PHP-FPM support for Linux.# 安裝角色
[lth@controller web 23:02:31]$ ansible-galaxy role install geerlingguy.apache
- downloading role 'apache', owned by geerlingguy
- downloading role from https://github.com/geerlingguy/ansible-role-apache/archive/4.0.0.tar.gz
- extracting geerlingguy.apache to /home/lth/web/roles/geerlingguy.apache
- geerlingguy.apache (4.0.0) was installed successfully
[lth@controller web 23:03:03]$ ls roles/
apache geerlingguy.apache
[lth@controller web 23:03:22]$ ansible-galaxy install http://192.168.42.100/%E8%BD%AF%E4%BB%B6/ansible-role-haproxy-1.3.1.tar.gz
- downloading role from http://192.168.42.100/%E8%BD%AF%E4%BB%B6/ansible-role-haproxy-1.3.1.tar.gz
- extracting ansible-role-haproxy-1.3.1 to /home/lth/web/roles/ansible-role-haproxy-1.3.1
- ansible-role-haproxy-1.3.1 was installed successfully[lth@controller web 23:03:30]$ mv roles/ansible-role-haproxy-1.3.1/ roles/haproxy
[lth@controller web 23:03:44]$ ls roles/
apache geerlingguy.apache haproxy# 查看haproxy角色使用說明,獲取關鍵變量信息
[lth@controller web 23:04:24]$ vim roles/geerlingguy.haproxy/README.md
......
HAProxy backend configuration directives.haproxy_backend_servers:- name: app1address: 192.168.0.1:80- name: app2address: 192.168.0.2:80
......# 查看apache角色使用說明,不需要配置變量
[lth@controller web 23:04:29]$ vim roles/geerlingguy.apache/README.md# 編寫playbook
[lth@controller web 23:05:36]$ vim playbook.yml
[lth@controller web 23:05:59]$ cat playbook.yml
- name: deploy LBhosts: LBsvars:haproxy_backend_servers:- name: node1address: 10.1.8.11:80- name: node2address: 10.1.8.12:80- name: node3address: 10.1.8.13:80- name: node4address: 10.1.8.14:80roles:- haproxy
- name: deploy apachehosts: WEBsroles:- apache # 查看清單文件
[lth@controller web 23:06:33]$ vim inventory
[lth@controller web 23:06:38]$ cat inventory
[LBs]
controller[WEBs]s 674321`234CXa
node[1:4]# 執行劇本
[lth@controller web 23:08:01]$ ansible-playbook playbook.yml # 測試結果
[lth@controller web 23:09:20]$ curl http://controllerWelcome to node2.xiexin.cloud !
[lth@controller web 23:09:24]$ curl http://controllerWelcome to node3.xiexin.cloud !
[lth@controller web 23:09:26]$ curl http://controllerWelcome to node4.xiexin.cloud !
[lth@controller web 23:09:31]$ curl http://controllerWelcome to node1.xiexin.cloud !