RHCE备考
目录
1、安装并配置 Ansible
题目:
在控制节点 workstation.lab.example.com 上安装和配置 Ansible:安装所需的软件包创建静态清单文件 /home/devops/ansible/inventory 的,要求如下: servera 是 dev 主机组的成员 serverb 是 test 和 balancers serverc 和 serverd 是 prod 主机组的成员 prod 组是 webservers 主机组的成员创建名为 /home/devops/ansible/ansible.cfg 的配置文件,要求如下: 主机清单文件为 /home/devops/ansible/inventory 默认内容集合目录为 /home/devops/ansible/mycollections 默认角色目录为 /home/devops/ansible/roles核心知识点
ansible vs ansible-navigator
两者在考试中的定位与区别如下:
| 比较维度 | ansible (传统 CLI) | ansible-navigator (新一代 TUI/CLI) |
|---|---|---|
| 运行依赖环境 | 直接依赖宿主机上安装的 Python 及 Ansible 包 | 依赖容器执行环境(Execution Environment, EE) |
| 主要交互方式 | 纯命令行终端输出 (stdout) | 支持文本用户界面 (TUI) 交互,也可通过 -m stdout 输出到标准终端 |
| 考场核心使用场景 | 快速 Ad-hoc 连通性测试(如 ansible all -m ping) |
查看图形化主机清单(inventory --graph)、调试与运行 Playbook |
| 常用命令示例 | ansible all -m pingansible-doc <module> |
ansible-navigator run site.yml -m stdoutansible-navigator inventory -m stdout --graph |
podman login
在 RHCE 考试环境中,执行 podman login <镜像仓库地址> 是绝对不能遗漏的初始化步骤,其背后的核心逻辑如下:
- 执行环境(EE)容器化:
ansible-navigator运行 Playbook 时,默认不会直接在控制节点宿主机上跑 Python 脚本,而是会启动一个预装了特定 Python 版本、Ansible Core 以及各类 Collection 的 Podman 容器 来执行任务。 - 私有镜像仓库鉴权:考场环境中的 EE 容器镜像存放于内部私有镜像仓库(例如
utility.lab.example.com)。如果未事先使用podman login完成身份认证,ansible-navigator在拉取或校验 EE 镜像时会因鉴权失败(401 Unauthorized)而无法运行任何自动化任务。
主机清单文件(inventory)语法与结构
主机清单用于定义 Ansible 管理的目标节点。考试中常用 INI 格式 编写,其核心语法规则如下表所示:
| 结构 / 语法类型 | INI 格式写法示例 | 考点与细节解析 |
|---|---|---|
| 单主机指定 | servera |
直接填写主机的 FQDN 或已解析的主机名/IP。 |
| 基础主机组 | [dev]servera |
使用 [组名] 声明,下方列出该组包含的主机。 |
| 多组归属(重叠) | [test]serverb[balancers]serverb |
同一台主机可同时属于多个组(例如 serverb 既属于 test 也属于 balancers)。 |
| 组嵌套(父子组) | [webservers:children]prod |
考场必考:声明父组时必须加上 :children 后缀;下方只填写子组组名(prod),不能直接写主机名。 |
| 保留组名 | all / ungrouped |
all 代表清单中的所有主机;ungrouped 代表没有归属于任何自定义组的主机。 |
主配置文件(ansible.cfg)参数拆解
ansible.cfg 控制着 Ansible 的核心运行行为(包括读取哪个清单、以谁的身份连接、如何提权等)。
| 配置节点 (Section) | 参数项 (Key) | 考场常用设定值 | 作用与配置逻辑 |
|---|---|---|---|
[defaults] |
inventory |
/home/devops/ansible/inventory |
指定默认的主机清单路径(建议使用绝对路径)。 |
remote_user |
devops |
指定 SSH 连接受控节点时使用的远端用户名。 | |
roles_path |
/home/devops/ansible/roles |
指定 Ansible 查找角色(Role)的默认目录。 | |
collections_path |
/home/devops/ansible/mycollections |
指定 Ansible 查找集合(Collection)的默认目录。 | |
[privilege_escalation] |
become |
true |
开启提权功能(连接到受控节点后切换身份)。 |
become_method |
sudo |
指定提权方式(Linux 环境下固定为 sudo)。 |
|
become_user |
root |
指定提权目标用户(通常提权至最高权限 root)。 |
|
become_ask_pass |
false |
关闭提权密码询问(因为受控节点已对 devops 配置了 sudo 免密)。 |
解答:
# 安装 Ansible 核心工具及系统角色包(需 sudo 权限)sudo dnf install ansible ansible-navigator rhel-system-roles -y# 登录考试环境提供的镜像仓库(账号密码以考场题目提示为准,通常为 admin/redhat)podman login utility.lab.example.com# 创建并进入工作目录mkdir -p /home/devops/ansiblecd /home/devops/ansible# 编辑主机清单文件vim /home/devops/ansible/inventory# 内容[dev]servera
[test]serverb
[balancers]serverb
[prod]servercserverd
[webservers:children]prod# 编写主配置文件vim /home/devops/ansible/ansible.cfg# ansible.cfg示例配置文件ansible-config init --disabled > /tmp/ansible.cfg# 写入内容[defaults]remote_user=devopsinventory=/home/devops/ansible/inventorycollections=/home/devops/ansible/mycollectionsroles=/home/devops/ansible/roles[privilege_csalation]become=truebecome_ask_pass=false# 创建集合目录mkdir /home/devops/ansible/mycollections# 创建角色目录mkdir /home/devops/ansible/roles# 检测tree /home/devops/ansible/# 登录容器podman login utility.lab.example.com# 查看主机清单是否正确ansible-navigator inventory -m stdout -- graph# 测试环境ansible all -m ping2、创建 yum 仓库
题目:
作为系统管理员,需在受管节点上安装软件。创建 playbook /home/devops/ansible/yum_repo.yml,该 playbook 将在各个受管节点上创建以 下 yum 仓库: 仓库 1: 仓库的名称为 RH294_BASE 描述为 RH294 base software BaseURL 为 http://content.example.com/rhel9.0/x86_64/dvd/BaseOS GPG 签名检查为启用状态 GPG 密钥 URL 为http://content.example.com/rhel9.0/x86_64/dvd/RPM-GPG- KEY-red hat-release 仓库为启用状态 仓库 2: 仓库的名称为 RH294_STREAM 描述为 RH294 stream software BaseURL 为 http://content.example.com/rhel9.0/x86_64/dvd/AppStream GPG 签名检查为启用状态 GPG 密钥 URL 为http://content.example.com/rhel9.0/x86_64/dvd/RPM-GPG-KEY-red hat-release 仓库为启用状态核心模块:ansible.builtin.yum_repository
yum_repository 模块用于在受控主机的 /etc/yum.repos.d/ 目录下自动生成和维护 .repo 配置文件。
模块常用参数表
| 参数项 | 数据类型 | 考场常用值/示例 | 作用与对应 .repo 字段 |
|---|---|---|---|
name |
String | RH294_BASE |
必填。仓库的 ID,对应 .repo 文件中的 [RH294_BASE] 节点名。 |
description |
String | RH294 base software |
仓库的文字描述,对应 .repo 中的 name = ... 字段。 |
baseurl |
String | http://.../BaseOS |
软件源的 HTTP/FTP/FILE 路径,对应 baseurl = ...。 |
gpgcheck |
Boolean | yes / no |
是否开启 GPG 签名校验,对应 gpgcheck = 1 或 0。 |
gpgkey |
String | http://.../RPM-GPG-KEY-... |
GPG 公钥的 URL 地址,对应 gpgkey = ...。 |
enabled |
Boolean | yes / no |
是否启用该软件源,默认为 yes。 |
file |
String | (可选,如 rh294) |
指定生成的 .repo 文件名(不含后缀)。若不填,默认将配置写入 [name].repo 中。 |
ansible-doc 查阅模块参数
考场上如果记不清模块参数的拼写(如 baseurl 还是 base_url),不要硬记,直接通过命令行自带的帮助文档查询:
# 查询配置 YUM 源对应的模块名称ansible-doc -l | grep repo# 查看 yum_repository 模块的详细说明与使用示例ansible-doc ansible.builtin.yum_repository在打开的文档界面中:
- 按
/键输入/EXAMPLES并回车,直达示例章节。 - 复制官方提供的标准 YAML 结构进行修改即可。
解答:
# 编辑Playbook文件(yaml格式)vim yum_repo.yml配置文件如下:
---- name: install repo hosts: all tasks: - name: RH294_BASE repository ansible.builtin.yum_repository: name: RH294_BASE description: RH294 base software baseurl: http://content.example.com/rhel9.0/x86_64/dvd/BaseOS gpgcheck: yes gpgkey: http://content.example.com/rhel9.0/x86_64/dvd/RPM-GPG-KEY-redhat-release enabled: yes
- name: RH294_STREAM repository ansible.builtin.yum_repository: name: RH294_STREAM description: RH294 stream software baseurl: http://content.example.com/rhel9.0/x86_64/dvd/AppStream gpgcheck: yes gpgkey: http://content.example.com/rhel9.0/x86_64/dvd/RPM-GPG-KEY-redhat-release enabled: yes验证:
#运行playbook验证ansible-navigator run yum_repo.yml -m stdout#只要看到playbook中的两个task(任务)在所有主机上执行即可(任务状态是ok或者changed都是可以的)
#所有的主机都必须有RH294_BASE和RH294_STREAM两个仓库ansible all -m shell -a "yum repolist"3、安装 Collections
题目:
以 devops 身份将以下 collections 从 files/3/目录中安装到workstation.lab.example.comredhat-rhel_system_roles-1.16.2.tar.gzansible-posix-1.4.0.tar.gzcommunity-general-4.3.0.tar.gz集合应安装到默认集合目录 /home/devops/ansible/mycollectionsAnsible Collection(集合)
ansible-galaxy collection
ansible-galaxy 是管理 Ansible Roles 和 Collections 的官方 CLI 工具。
常用命令与选项速查表:
| 命令 / 选项 | 功能与说明 | 考场常用示例 |
|---|---|---|
install |
安装指定的 Collection(支持本地 .tar.gz 包或远端 Galaxy 仓库) |
ansible-galaxy collection install xxx.tar.gz |
list |
列出当前配置路径下所有已安装的 Collection | ansible-galaxy collection list |
-p / --collections-path |
显式指定安装目标路径(覆盖 ansible.cfg 中的默认值) |
ansible-galaxy collection install xxx.tar.gz -p /path/to/dir |
--force / -f |
强制覆盖安装(若已存在同名集合) | ansible-galaxy collection install xxx.tar.gz --force |
Collection 目录架构规范
Collection 解压安装后遵循严格的目录组织规范: $$\text{collections_path} \longrightarrow \mathbf{ansible_collections/} \longrightarrow \mathbf{\langle Namespace \rangle /} \longrightarrow \mathbf{\langle Collection_Name \rangle /}$$
- Namespace (命名空间):标识开发者或组织(如
redhat、community、ansible)。 - Collection Name (集合名称):具体的功能集合(如
rhel_system_roles、general、posix)。 - Playbook 调用方式:使用全限定集合名称(FQCN)调用模块,例如
ansible.posix.synchronize或community.general.ini_file。
极速安装与验证指令
# 切入工作目录cd /home/devops/ansible
# 一键离线安装当前目录下所有 Collection 包ansible-galaxy collection install *.tar.gz --force -p /home/devops/ansible/mycollections
# 验证安装列表ansible-galaxy collection list解答:
# 将文件拷贝到/home/devops/ansible/目录,考试时需要自己用wget命令从网站下载cp /home/devops/files/3/* .# 安装集合ansible-galaxy collection install ansibleposix-1.4.0.tar.gz --forceansible-galaxy collection install communitygeneral-4.3.0.tar.gz --forceansible-galaxy collection install redhatrhel_system_roles-1.16.2.tar.gz --force# 也可以使用一条命令安装三个集合ansible-galaxy collection install *.tar.gz --force# 验证(会生成三个目录)ls /home/devops/ansible/mycollections/ansible_collections/ansible community redhat4、安装软件包
题目:
创建名为 packages.yml 的 playbook: 将 php 和 mariadb 软件包安装到 dev、 test 和 prod 组中的主机上 将 RPM Development Tools 包组安装到 dev 组中的主机上 将 dev 组中主机上的所有软件包更新为最新版本本题示例查看
# 查找dnf模块ansible-doc -l | grep dnf# 查看示例ansible-doc dnf# 输入/EXAMPLE然后回车进行搜索,即可看到相应模块的示例解答:
# 编辑配置文件vim packages.yml配置文件如下:
---- name: install php and mariadb hosts: dev,test,prod tasks: - name: install php and mariadb ansible.builtin.dnf: name: - php - mariadb state: latest
- name: install development tools and update hosts: dev tasks: - name: install development tools ansible.builtin.dnf: name: "@Development Tools" state: latest
- name: update ansible.builtin.dnf: name: '*' state: latest验证:
#运行playbook验证ansible-navigator run packages.yml -m stdout#只要看到playbook中的task(任务)在对应主机上执行即可(任务状态是ok或者changed都是可以的)5、使用角色
题目:
根据以下要求创建名为 selinux.yml 的 playbook:在所有受管节点上运行,使用 selinux 角色,将 SELinux 策略为 targeted,将 SELinux 状态为 enforcing核心技术点
1. 系统角色 (RHEL System Roles) 机制
- 红帽官方预先编写并经过严格测试的各种系统管理角色(如 SELinux、Network、Timesync、Storage 等)。
- 在 Ansible 2.9 及后续版本中,系统角色已整合到 Collection 中,其 FQCN(全限定角色名) 为:$$\mathbf{redhat.rhel_system_roles.selinux}$$
2. SELinux 角色核心变量对照
selinux 角色提供了多个预定义的控制变量,最常考的两个如下:
| 角色变量名 | 可选值示例 | 作用对应的配置文件位置 |
|---|---|---|
selinux_state |
enforcing / permissive / disabled |
修改 /etc/selinux/config 中的 SELINUX= |
selinux_policy |
targeted / mls |
修改 /etc/selinux/config 中的 SELINUXTYPE= |
解答:
# 编辑配置文件vim selinux.ymlyml配置文件内容如下:
---- name: selinux hosts: all vars: selinux_policy: targeted # 策略:targeted / mls selinux_state: enforcing # 状态:enforcing / permissive / disabled roles: - redhat.rhel_system_roles.selinux# 验证测试ansible-navigator run selinux.yml -m stdout6、使用Timesync RHEL系统角色
题目:
安装 RHEL 系统角色软件包,并创建符合以下条件的playbook, /home/devops/ansible/timesync.yml:1. 在所有受管节点上运行2. 使用 timesync 角色3. 配置该角色,以使用当前有效的 NTP 提供4. 配置该角色,以使用时间服务器 classroom.example.com模块 vs 角色 vs 角色变量
在编写 Playbook 时,首先需要分清以下三个核心概念:
| 概念名称 | 英文名称 | 本质定位 | 本例中的代表 | 核心作用与运行机制 |
|---|---|---|---|---|
| 模块 | Module | 最小执行单元 | ansible.builtin.dnfansible.builtin.copy |
Ansible 的“原子工具”,负责直接在远端主机上执行具体的单步操作。 |
| 角色 | Role | 自动化配置大礼包 | redhat.rhel_system_roles.timesync |
官方或第三方预先封装好的复杂任务集合,内部包含了完整的逻辑、执行任务与配置模板。 |
| 角色变量 | Role Variable | 角色配置开关/入参 | timesync_ntp_servers |
角色暴露给外部调用的“配置接口”,用来给角色传递具体的运行参数。 |
解答:
# 确保已经安装了rhel-system-rolesdnf install -y rhel-system-roles# 将系统 timesync 角色拷贝到当前 ansible 工作目录下的 roles 目录中sudo cp -r /usr/share/ansible/roles/rhelsystem-roles.timesync/ roles/timesync# 修正拷贝后的目录所有权为 devops 用户sudo chown -R devops:devops /home/devops/ansible/roles/timesync编辑playbook:
---- name: timesync hosts: all vars: timesync_ntp_servers: - hostname: classroom.example.com iburst: yes roles: - timesync# 运行playbook测试ansible-navigator run -m stdout timesync.yml7、使用 Ansible Galaxy 安装角色
题目:
创 建 /home/devops/ansible/roles/requirements.yaml 文件用以下载并安装角色 到/home/devops/ansible/roles/ 目录中: 角色名:balancer,来自于 files/6/haproxy.tar(考试写的是http://materials.example.com/t ools/haproxy.tar) 角色名:phpinfo,来自于 files/6/phpinfo.tar(考试写的是http://materials.example.com/to ols/phpinfo.tar)ansible-galaxy
| 命令片段 | 全称 / 参数 | 本质作用 | 考场与生产解释 |
|---|---|---|---|
ansible-galaxy |
工具名称 | Ansible 官方提供的角色/集合管理 CLI 工具 | 专门用来搜索、下载、创建和管理 Role 及 Collection。 |
install |
子命令 | 执行“安装”动作 | 告诉工具接下来要进行下载与解压安装。 |
-r |
--role-file(或 --requirements-file) |
指定依赖清单文件 | 告诉工具:“不要让我一个个手动输入角色链接,请按照这个文件里写的列表去批量下载。” |
roles/requirements.yaml |
文件路径 | 清单文件的相对路径 | 存放角色 src(下载源)和 name(重命名)的 YAML 文件。 |
-p |
--roles-path |
指定安装目标目录 | 告诉工具:“下载解压后的角色文件夹,必须存放到这个指定的目录下。” |
roles/ |
目录路径 | 目标保存目录 | 即当前工作目录下的 roles/ 文件夹(对应绝对路径 /home/devops/ansible/roles/)。 |
解答:
# src在考试时应为网址---- src: file:///home/devops/ansible/haproxy.tar name: balancer- src: file:///home/devops/ansible/phpinfo.tar name: phpinfo# 安装测试ansible-galaxy install -r roles/requirements.yaml -p roles/8、创建和使用角色
题目:
根据下列要求,在 /home/devops/ansible/roles 中创建名为 apache 的角色: 安装 httpd 软件包,开机启动并立即运行 开启防火墙并允许 web 服务通信 模板文件 index.html.j2 用于创建/var/www/html/index.html,含有以下内容 Welcome to HOSTNAME on IPADDRESS,其中 HOSTNAME 和 IPADDRESS 来自于事实 变量创建名为 newrole.yml 的 playbook,并使用此角色,这个 playbook 运行于 webservers 主机组解答:
# 初始化角色目录结构cd /home/devops/ansible/roles/ansible-galaxy init apache# 编辑Jinja2 模板文件vim /home/devops/ansible/roles/apache/template/index.html.j2# 写入Welcome to {{ ansible_fqdn }} on {{ ansible_default_ipv4.address }}# 编写角色的主任务逻辑 (tasks/main.yml)vim apache/apache/tasks/main.yml主角色逻辑:
---# 1. 安装 HTTPD 软件包- name: install httpd rpm ansible.builtin.dnf: name: httpd state: present
# 2. 安装 Firewalld 防火墙(部分系统可能默认没装,加上更保险)- name: install firewalld ansible.builtin.dnf: name: firewalld state: present
# 3. 启动 HTTPD 并设置开机自启- name: Start service httpd, if not started ansible.builtin.service: name: httpd state: started enabled: true
# 4. 启动 防火墙 并设置开机自启- name: Start service firewalld, if not started ansible.builtin.service: name: firewalld state: started enabled: true
# 5. 配置防火墙放行 Web 服务 (http)- name: firewall rule ansible.posix.firewalld: service: http permanent: yes state: enabled immediate: yes
# 6. 使用 Jinja2 模板生成 index.html- name: Create a index.html ansible.builtin.template: src: index.html.j2 dest: /var/www/html/index.html编辑ansible目录下的playbook:
---- name: httpd service hosts: webservers roles: - apache9、从 Ansible Galaxy 使用角色
题目:
创建名为 roles.yml 的 playbook,满足以下要求:Playbook 运行在 balancers 主机组上,并使用 balancer 角色,这个角色为 webservers 主机组配 置负载均衡 web 服务器,配置完成后,当访问 http://serverb.lab.example.com 将显示以下输出信息: Welcome to serverc.lab.example.com on 172.25.250.12 Welcome to serverd.lab.example.com on 172.25.250.13 (刷新网页后)这个 playbook 中另一个 play 使用 phpinfo 角色在 webservers 主机组上,执行完毕后,访问主 机组内每台主机的/hello.php 显示以下信息: Hello World from FQDN FQDN 来自于事实变量页面同时显示每台受控主机的 PHP 配置解答:
编辑playbook:
- name: phpinfo hosts: webservers roles: - phpinfo
- name: balancers hosts: balancers roles: - balancer tasks: - name: permit port 80 ansible.posix.firewalld: service: http permanent: yes state: enabled immediate: yes测试:
curl http://serverb.lab.example.comWelcome to serverc.lab.example.com on 172.25.250.1curl http://serverb.lab.example.comWelcome to serverd.lab.example.com on 172.25.250.1310、创建和使用分区
题目:
根据下列要求,创建名为 partition.yml 的 playbook:playbook 中包含一个 play,该 play 在 balancers 主机组中的主机上运行: 在设备 vdb 上创建单个主分区,编号为 1,大小为 1500 MiB, 使用 ext4 文件系统格式化分区 将文件系统永久挂载到 /newpart 如果无法创建请求的分区大小,应显示错误消息: Could not create partition of that size 并且应改为使用大小 800 MiB 如果设备 vdb 不存在,应显示错误消息 Disk does not exist思路:
整个 Playbook 的设计思路可以分为三个层级:
┌─────────────────────────────────────────────────────┐ │ 1. 检查磁盘 vdb 是否存在 │ │ 若不存在 -> 仅输出 "Disk does not exist" │ └──────────────────────────┬──────────────────────────┘ │ ▼ (若 vdb 存在) ┌─────────────────────────────────────────────────────┐ │ 2. block 块:尝试创建 1500 MiB 分区 │ └──────────────────────────┬──────────────────────────┘ │ ┌───────────┴───────────┐ 成功 │ │ 失败(磁盘小于 1500 MiB) ▼ ▼ │ ┌─────────────────────────────────┐ │ │ 3. rescue 块: │ │ │ - 输出错误提示 │ │ │ - 降级创建 800 MiB 分区 │ │ └─────────────────┬───────────────┘ │ │ └───────────────┬───────────────┘ │ ▼ ┌─────────────────────────────────────────────────────┐ │ 4. always 块:统一进行收尾 │ │ - 格式化为 ext4 │ │ - 创建 /newpart 目录 │ │ - 挂载并写入 /etc/fstab │ └─────────────────────────────────────────────────────4 个核心模块:
| 场景 | 模块名称 | 关键参数解释 |
|---|---|---|
| 创建分区 | community.general.parted |
device: /dev/vdbnumber: 1 (分区号)part_end: 1500MiB (分区结束位置/大小)state: present |
| 格式化 | community.general.filesystem |
fstype: ext4 (文件系统类型)dev: /dev/vdb1 (注意是第一个分区 vdb1) |
| 创建目录 | ansible.builtin.file |
path: /newpartstate: directory |
| 持久化挂载 | ansible.posix.mount |
path: /newpart (挂载点)src: /dev/vdb1 (设备)fstype: ext4state: mounted (自动写入 /etc/fstab 并立即挂载) |
| 查看示例: |
ansible-doc debugansible-doc partedansible-doc filesystemansible-doc fileansible-doc mount解答:
编辑playbook:
---- name: partition hosts: balancers tasks: - name: check device vdb ansible.builtin.debug: msg: Disk does not exist when: ansible_facts['devices']['vdb'] is not defined
- name: creat part block: - name: 1500MiB community.general.parted: device: /dev/vdb number: 1 state: present part_end: 1500MiB when: ansible_facts['devices']['vdb'] is defined
rescue: - name: dis err ansible.builtin.debug: msg: Could not create partition of that size
- name: 800MiB community.general.parted: device: /dev/vdb number: 1 state: present part_end: 800MiB when: ansible_facts['devices']['vdb'] is defined
always: - name: fstype ext4 community.general.filesystem: fstype: ext4 dev: /dev/vdb1 when: ansible_facts['devices']['vdb'] is defined
- name: create dir ansible.builtin.file: path: /newpart state: directory when: ansible_facts['devices']['vdb'] is defined
- name: Mount device ansible.posix.mount: path: /newpart src: /dev/vdb1 fstype: ext4 state: mounted when: ansible_facts['devices']['vdb'] is defined测试:
ansible balancers -m shell -a 'df -h /newpart'11、创建和使用逻辑卷
题目:
创建一个名为/home/devops/ansible/lv.yml 的playbook,它将在所有受管节点上运行以执行下列任务1. 创建符合以下要求的逻辑卷: 逻辑卷创建在 research 卷组中 逻辑卷名称为 data 逻辑卷大小为 600MiB2. 使用 ext4 文件系统格式化逻辑卷3. 如果无法创建请求的逻辑卷大小,应显示错误消息 Could not create logical volume of that size,并且应改为使用大小 400MiB。4. 如果卷组research 不存在 ,应显示错误消息 Volume group does not exist。5. 不要以任何方式挂载逻辑卷LVM 与文件系统模块详解
community.general.lvol模块:vg: 目标卷组名称(如research)。lv: 目标逻辑卷名称(如data)。size: 逻辑卷大小。在lvol模块中,直接填写数字(如600或400)默认单位即为 MB/MiB。
community.general.filesystem模块:fstype: 文件系统类型,填写ext4。dev: 逻辑卷设备在 Linux 中的绝对路径,规则为/dev/<VG名称>/<LV名称>(即/dev/research/data)。
# 环境准备(考试不需要)---- name: lvm_pre hosts: dev tasks: - name: create partition for LVM community.general.parted: device: /dev/vdb number: 1 flags: [ lvm ] state: present part_start: 1MiB part_end: 800MiB
- name: create research vg community.general.lvg: vg: research pvs: /dev/vdb1
- hosts: prod tasks: - name: create partition for LVM community.general.parted: device: /dev/vdb number: 1 flags: [ lvm ] state: present part_start: 1MiB part_end: 600MiB
- name: create research vg community.general.lvg: vg: research pvs: /dev/vdb1---- name: lvm hosts: dev,prod tasks: - name: check lvm ansible.builtin.debug: msg: Volunme group does not exist when: "'research' not in ansible_lvm.vgs"
- name: create lvm block: - name: create lvm 600Mib community.general.lvol: vg: research lv: data size: 600 when: "'research' in ansible_lvm.vgs"
rescue: - name: dis err ansible.builtin.debug: msg: Could not create logical volume of that size when: "'research' in ansible_lvm.vgs"
- name: create lvm 400Mib community.general.lvol: vg: research lv: data size: 400 when: "'research' in ansible_lvm.vgs"
always: - name: format ext4 community.general.filesystem: fstype: ext4 dev: /dev/research/data when: "'research' in ansible_lvm.vgs"12、生成主机文件
题目:
将 files/10/hosts.j2 模板文件拷贝到/home/devops/ansible 目录中,完善此模板文件,用以生成受控节点的/etc/myhosts文件创建名为 hosts.yml 的 playbook 对 dev 主机组使用此模板文件,/etc/myhosts 文件内容最终如下:127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 172.25.250.10 servera.lab.example.com servera172.25.250.11 serverb.lab.example.com serverb172.25.250.12 serverc.lab.example.com serverc172.25.250.13 servera.lab.example.com serverd.j2 文件
- 后缀含义:
.j2代表 Jinja2,它是 Python 中最流行的一种动态模板引擎。 - 作用:在 Linux 中,配置(如
/etc/hosts、/etc/nginx.conf)平时都是静态文本。但在自动化运维中,服务器的 IP 或主机名是动态变化的。 - 工作方式:Ansible 结合 Jinja2 模板,可以在模板里写变量、循环、判断语句。当 Ansible 执行时,会将实际数据填入模板,生成一份标准的纯文本配置文件,再发放到受控主机上。
Jinja2 的三大核心语法符号
在 .j2 文件中,只有三种固定的标记语法:
| 语法符号 | 名称 | 作用 / 示例 |
|---|---|---|
{{ ... }} |
变量取值/表达式 | 输出具体内容,如 {{ hostvars[item]['ansible_hostname'] }} |
{% ... %} |
逻辑控制 | 写循环或条件判断,如 {% for ... %}、{% if ... %} |
{# ... #} |
注释 | 仅在 .j2 中可见,生成最终文件时会被自动忽略 |
groups.all :Ansible 的主机组字典
groups 是 Ansible 系统内部维护的一个特殊变量(魔术变量),它的本质是一个 Python 字典(Dictionary)。
数据结构
当你在 inventory(主机清单文件)中定义了主机和组之后,Ansible 会自动生成 groups 字典:
假设你的主机清单是这样的:
[dev]servera
[test]serverbservercAnsible 在后台自动解析生成的 groups 变量结构其实长这样:
{ "all": ["servera", "serverb", "serverc", "serverd"], "dev": ["servera"], "test": ["serverb", "serverc"], "ungrouped": ["serverd"]}groups.all 的含义
groups:代表整个主机组字典。all:Ansible 的预留组,代表清单里的所有主机。groups.all:就是提取all这个 Key 对应的列表,最终得到:['servera', 'serverb', 'serverc', 'serverd']。
['ansible_default_ipv4']['address'] :嵌套字典取值
本质上是 Python 提取多层嵌套字典(Nested Dictionary)数据的标准语法。
ansible_default_ipv4
在 Ansible 运行剧本时(TASK [Gathering Facts] 阶段),它会在受控机器上执行系统探测,搜集到大量系统信息(称为 Facts)。
其中,ansible_default_ipv4 就是搜集到的默认 IPv4 网卡信息。它本身是一个包含了多项属性的子字典:
"ansible_default_ipv4": { "address": "172.25.250.10", "netmask": "255.255.255.0", "gateway": "172.25.250.254", "interface": "eth0", "macaddress": "52:54:00:00:00:0a", "type": "ipv4"}两对 ['...']
一层层定位到最里面的数据:
- 第一层
['ansible_default_ipv4']: 从整台机器收集到的庞大 Fact 数据库中,锁定默认网卡这个对象。 - 第二层
['address']: 在网卡对象内部,进一步精确定位到address属性,提取出纯文本的 IP 地址字符串(如"172.25.250.10")。 如果你写['ansible_default_ipv4']['gateway'],拿到的就是网关地址172.25.250.254。
解答:
# 拷贝文件cp /home/devops/files/10/hosts.j2 .# 编辑.j2模板文件# 添加以下内容{% for item in groups.all %}{{ hostvars[item]['ansible_default_ipv4']['address'] }} {{ hostvars[item]['ansible_fqdn'] }} {{ hostvars[item]['ansible_hostname'] }}{% endfor %}编辑playbook:
---- name: update /etc/myhosts on dev hosts: all tasks: - name: generate file ansible.builtin.template: src: hosts.j2 dest: /etc/myhosts when: inventory_hostname in groups.dev# 运行playbookansible-navigator run hosts.yml -m stdout# 测试ansible dev -m shell -a 'cat /etc/myhosts'13、修改文件内容
题目:
创建名为 issue.yml 的 playbook,要求如下:此 playbook 运行到所有受控节点此 playbook 覆盖/etc/issue 文件中的内容:在 dev 主机组的主机中,内容是: Development在 test 主机组的主机中,内容是: Test在 prod 主机组的主机中,内容是: Production解答:
编辑playbook:
---- name: update issue hosts: all tasks: - name: update /etc/issue ansible.builtin.copy: content: Development dest: /etc/issue when: inventory_hostname in groups.dev
- name: update /etc/issue ansible.builtin.copy: content: Test dest: /etc/issue when: inventory_hostname in groups.test
- name: update /etc/issue ansible.builtin.copy: content: Production dest: /etc/issue when: inventory_hostname in groups.prod14、创建 Web 内容目录
题目:
按照下方所述,创建名为 webcontent.yml 的 playbook:该 playbook 在 dev 主机组中的受管节点上运行 创建目录 /webdev: 所有者为 webdev 组 具有常规权限: owner=read+write+execute, group=read+write+execute, other=read+execute 具有特殊权限: set group ID 用软链接将 /var/www/html/webdev 链接到 /webdev 创建文件 /webdev/index.html,内容为: Red Hat Ansible 在 dev 主机组中主机上浏览此目录(http://servera.lab.example.com/webdev/index.h tml )将生成以下输出: Red Hat Ansible核心模块
ansible.builtin.user (用户管理)
- 场景:创建或管理系统用户。
- 常用参数:
name: 用户名。- 保持幂等性:若用户已存在,执行该 Task 不会产生变更(显示
ok)。
ansible.builtin.file (文件/目录与权限管理)
- 场景:创建目录、创建软链接、修改权限及 SELinux 上下文。
- 常用参数:
path: 目标路径(创建目录时使用)。state: 类型标识。directory(目录)、link(软链接)、absent(删除)等。mode: 权限代码(建议字符串形式,如'2775')。- SGID 特殊权限:首位
2表示设置 SGID(Set Group ID),在该目录下新建的文件/子目录会自动继承父目录的所属组。
- SGID 特殊权限:首位
src/dest: 创建软链接时的对应路径:src: 真实物理源路径(例如/webdev)。dest: 生成的快捷方式/软链接路径(例如/var/www/html/webdev)。
setype: 指定文件/目录的 SELinux 安全上下文类型(例如httpd_sys_content_t),防止 Web 报 403 错误。
ansible.builtin.copy (文件复制与内联生成)
- 场景:将本地文件拷贝至受控端,或直接生成文本内容。
- 常用参数:
content: 直接写入字符串内容(无需准备本地源文件)。dest: 生成文件的绝对路径。setype: 同样支持在生成文件时赋予 SELinux 标签。
ansible.posix.firewalld (防火墙策略管理)
- 场景:配置系统防火墙放行策略。
- 常用参数:
service: 预定义的网络服务名称(例如http、https)。permanent: yes: 写入持久化配置,确保重启节点后依然有效。state: enabled: 启用规则。immediate: yes: 立即应用规则至当前运行中的防火墙,无需重启firewalld。
ansible.builtin.service (Systemd 服务控制)
- 场景:管理系统服务的运行状态(启动、停止、重启等)。
- 常用参数:
name: 系统服务进程名(例如httpd、sshd)。state: 服务状态,包含started、stopped、restarted、reloaded。
解答:
编辑playbook:
---- name: webcontent hosts: dev tasks: - name: create user ansible.builtin.user: name: webdev
- name: create webdev file ansible.builtin.file: path: /webdev state: directory owner: webdev group: root mode: '2775' setype: httpd_sys_content_t
- name: create a symbolic link ansible.builtin.file: src: /webdev dest: /var/www/html/webdev state: link
- name: copy using inline content ansible.builtin.copy: content: Red Hat Ansible dest: /webdev/index.html setype: httpd_sys_content_t
- name: permit traffic in default zone for http service ansible.posix.firewalld: service: http permanent: yes state: enabled immediate: yes
- name: restart httpd ansible.builtin.service: name: httpd state: restarted检测:
# 运行playbookansible-navigator run webcontent.yml -m stdout# 检测curl http://servera.lab.example.com/webdev/index.html# 应输出Red Hat Ansible15、生成硬件报告
题目:
创建名为 hwreport.yml 的 playbook,在所有受控主机上生成/root/hwreport.txt 文件,内容包含: 清单主机名称 以 MB 表示的总内存大小 BIOS 版本 磁盘设备 vda 的大小 磁盘设备 vdb 的大小 输出文件中的每一行含有一个 key=value 对 playbook 应当来自 files/13/hwreport.empty 模板文件,并将它保存为 /root/hwreport.txt 使用正确的值修改 /root/hwreport.txt 如果硬件项不存在,相关的值应设为 NONE解答:
# 将模板文件复制到目录下cp /home/devops/files/13/hwreport.empty .# 查看模板文件cat hwreport.empty# Hardware reportHOST=inventoryhostnameMEMORY=memory_in_MBBIOS=BIOS_versionDISK_SIZE_VDA=disk_vda_sizeDISK_SIZE_VDB=disk_vdb_size编辑playbook:
---- name: dis report hosts: all vars: hw_all: - hw_name: HOST hw_cont: "{{ inventory_hostname | default('NONE', true) }}" - hw_name: MEMORY hw_cont: "{{ ansible_memtotal_mb | default('NONE', true) }}" - hw_name: BIOS hw_cont: "{{ ansible_bios_version | default('NONE', true) }}" - hw_name: DISK_SIZE_VDA hw_cont: "{{ ansible_devices.vda.size | default('NONE', true) }}" - hw_name: DISK_SIZE_VDB hw_cont: "{{ ansible_devices.vdb.size | default('NONE', true) }}"
tasks: - name: copy template hwreport file ansible.builtin.copy: src: /home/devops/files/13/hwreport.empty dest: /root/hwreport.txt
- name: replace hardware info in hwreport.txt ansible.builtin.lineinfile: path: /root/hwreport.txt regexp: "^{{ item.hw_name }}=" line: "{{ item.hw_name }}={{ item.hw_cont }}" loop: "{{ hw_all }}"验证:
# 运行playbookansible-navigator run hwreport.yml -m stdout# 测试ansible all -m shell -a 'cat /root/hwreport'16、创建 password vault
题目:
创建一个名为 locker.yml 的 ansible vault 文件存储用户密码:Vault 文件中含有两个变量,名称如下: pw_developer: Imadev pw_manager: Imamgr 加解密密码为 redhat 密码存储在 /home/devops/ansible/secret.txt 中解答:
# 创建密码文件secret.txt并写入密码,修改文件权限echo "redhat" > secret.txtchmod 600 secret.txt# 修改ansible配置文件,写入新配置vim ansible.cfg# 在defaults下添加vault_password_file=/home/devops/ansible/secret.txt# 执行命令创建locker.yml文件,写入题目给出的变量信息ansible-vault create locker.ymlpw_developer: Imadevpw_manager: Imamgr# 执行命令查看内容cat locker.yml # 密文ansible-vault view locker.yml # 明文17、创建用户帐户
题目:
需要创建的用户账户清单来自于 files/15/user_list.yml,请拷贝到/home/devops/ansible/中,配合上一题的 locker.yml,创建名为 users.yml 的 playbook,要求如下: 用户的 job description 为 developer 的用户,创建到 dev 和 test 主机组中,用户密码来自于 pw_developer 变量,用户的附属组是 devops 用户的 job description 为 manager 的用户,创建到 prod 主机组中,用户密码来自于 pw_manager 变量,用户的附属组是opsmgr 用户密码使用 SHA512 hash解答:
# 拷贝用户文件cp /home/devops/files/15/user_list.yml .编辑playbook:
---- name: create developer users hosts: dev,test vars_files: - user_list.yml - locker.yml tasks: - name: create devops group ansible.builtin.group: name: devops state: present
- name: create users ansible.builtin.user: name: "{{ item.name }}" uid: "{{ item.uid }}" groups: devops append: yes password: "{{ pw_developer | password_hash('sha512') }}" loop: "{{ users }}" when: item.job == "developer"
- name: create manager users hosts: prod vars_files: - user_list.yml - locker.yml tasks: - name: create opsmgr group ansible.builtin.group: name: opsmgr state: present
- name: create users ansible.builtin.user: name: "{{ item.name }}" uid: "{{ item.uid }}" groups: opsmgr append: yes password: "{{ pw_manager | password_hash('sha512') }}" loop: "{{ users }}" when: item.job == "manager"验证:
# 运行playbookansible-navigator run user.yml -m stdout# 查看各个主机的用户信息ansible all -m shell -a "id bob"ansible all -m shell -a "id sally"ansible all -m shell -a "id fred"18、更新 Ansible 库的密钥
题目:
请为 expense.yml 文件修改 vault 密码,要求如下: 请将 files/16/expense.yml 文件保存到 /home/devops/ansible/expense.yml 当前密码为 ibmibm 新密码为 redhatredhat解答:
# 先将ansible.cfg文件中的vault_password_file注释掉,修改密码后再改回来# 拷贝文件cp /home/devops/files/16/expense.yml .# 修改 vault 密码ansible-vault rekey expense.yml --ask-vault-pass# 输出 Rekey successful 就成功了19、配置 cron 作业
题目:
在所有受管节点上创建名为 /home/devops/ansible/cron.yml 的 Playbook,为 natasha 用户创建 cron 作业: 用户 natasha 每隔 2 分钟执行 logger “RH294 in progress”解答:
编辑playbook:
---- name: create cron for natasha hosts: all tasks: - name: create user natasha ansible.builtin.user: name: natasha
- name: create cron for natasha ansible.builtin.cron: name: "natasha cronjob" weekday: "*" minute: "*/2" hour: "*" month: "*" day: "*" user: natasha job: '/bin/logger "RH294 in progress"'验证:
# 运行playbookansible-navigator run cron.yml -m stdout# 测试ansible all -m shell -a "crontab -u natasha - l"