【运维进阶】Ansible 角色管理
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 !