32. RHCE 考点总结
本章系统梳理 RHCE(Red Hat Certified Engineer,EX294)考试的核心考点与快速操作参考。RHCE 考试以 Ansible 自动化为核心,同时覆盖 RHEL 系统管理的关键运维技能。本章以速查和验证为重点,辅助备考冲刺。
32.1 前提条件
- RHEL 9 已完成全部基础配置(第 1–31 章)。
- 通过 SecureCRT(SSH 端口 2222)以
ops用户、密钥认证方式登录192.168.1.100,执行sudo -i切换至 root 环境。 - 系统已注册订阅,官方仓库已启用。
32.2 Ansible 核心考点
RHCE(EX294)以 Ansible 为核心,以下为高频考点。
32.2.1 环境配置
dnf install -y ansible-core
# 配置 inventory(主机清单)
vim /etc/ansible/hosts
[webservers]
192.168.1.100 ansible_user=ops ansible_ssh_private_key_file=~/.ssh/id_ed25519 ansible_port=2222
[dbservers]
192.168.1.101 ansible_user=ops ansible_ssh_private_key_file=~/.ssh/id_ed25519 ansible_port=2222
[all:vars]
ansible_python_interpreter=/usr/bin/python3
# 验证连通性
ansible all -m ping
# 列出所有受管主机
ansible all --list-hosts
32.2.2 常用 Playbook 模式
安装软件并启动服务:
---
- name: 部署 Web 服务
hosts: webservers
become: yes
tasks:
- name: 安装 httpd
dnf:
name: httpd
state: present
- name: 启动并开机自启
systemd:
name: httpd
state: started
enabled: yes
- name: 防火墙放行 HTTP
firewalld:
service: http
permanent: yes
state: enabled
immediate: yes
用户与权限管理:
---
- name: 用户管理
hosts: all
become: yes
tasks:
- name: 创建运维用户
user:
name: ops
groups: wheel
append: yes
state: present
- name: 配置 SSH 公钥
authorized_key:
user: ops
key: "{{ lookup('file', '~/.ssh/id_ed25519.pub') }}"
state: present
SELinux 管理:
---
- name: SELinux 配置
hosts: all
become: yes
tasks:
- name: 确保 SELinux 为 Enforcing
selinux:
policy: targeted
state: enforcing
- name: 启用 httpd 网络连接布尔值
seboolean:
name: httpd_can_network_connect
state: yes
persistent: yes
LVM 存储管理:
---
- name: LVM 配置
hosts: all
become: yes
tasks:
- name: 创建卷组
lvg:
vg: datavg
pvs: /dev/sdb1
- name: 创建逻辑卷
lvol:
vg: datavg
lv: datalv
size: 10g
- name: 格式化为 XFS
filesystem:
fstype: xfs
dev: /dev/datavg/datalv
- name: 永久挂载
mount:
path: /mnt/data
src: /dev/datavg/datalv
fstype: xfs
state: mounted
Podman 容器管理:
---
- name: Podman 容器部署
hosts: all
become: yes
tasks:
- name: 拉取镜像
containers.podman.podman_image:
name: registry.access.redhat.com/ubi9/httpd-24
- name: 运行容器
containers.podman.podman_container:
name: web01
image: registry.access.redhat.com/ubi9/httpd-24
state: started
ports:
- "8080:8080"
32.2.3 Ansible 进阶考点
# 变量文件(group_vars)
mkdir -p group_vars
tee group_vars/webservers.yml << 'EOF'
http_port: 80
app_name: myapp
EOF
# ansible-vault 加密敏感变量
ansible-vault create vault/secrets.yml
# 执行时提供密码
ansible-playbook site.yml --ask-vault-pass
# 角色初始化
ansible-galaxy init roles/webserver
# 执行前检查(语法 + 模拟)
ansible-playbook site.yml --syntax-check
ansible-playbook site.yml --check --diff
# 按标签执行
ansible-playbook site.yml --tags install
# 限定目标主机
ansible-playbook site.yml --limit webservers
32.3 系统管理核心考点速查
32.3.1 用户与权限
# 创建用户并加入 wheel 组
useradd -m -G wheel ops
passwd ops
# sudo 免密配置
visudo -f /etc/sudoers.d/ops
# ops ALL=(ALL) NOPASSWD: ALL
# 设置密码策略
chage -M 90 -W 14 ops
chage -l ops
32.3.2 SELinux
# 状态确认
getenforce # 应返回 Enforcing
sestatus
# 添加端口上下文(修改 SSH 端口必须执行)
semanage port -a -t ssh_port_t -p tcp 2222
semanage port -l | grep ssh
# 布尔值管理
setsebool -P httpd_can_network_connect on
getsebool httpd_can_network_connect
# 文件上下文修复
restorecon -Rv /var/www/html/
# 分析拒绝日志
ausearch -m avc -ts recent
sealert -a /var/log/audit/audit.log
32.3.3 systemd 服务管理
# 创建自定义 unit 文件
tee /etc/systemd/system/myservice.service << 'EOF'
[Unit]
Description=My Custom Service
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/myscript.sh
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now myservice
systemctl status myservice
# 设置系统默认 target
systemctl set-default multi-user.target
systemctl get-default
32.3.4 LVM 存储
# 完整 LVM 创建流程(四步)
pvcreate /dev/sdb1
vgcreate datavg /dev/sdb1
lvcreate -L 10G -n datalv datavg
mkfs.xfs /dev/datavg/datalv
# 挂载并永久化
mkdir -p /mnt/data
mount /dev/datavg/datalv /mnt/data
echo '/dev/datavg/datalv /mnt/data xfs defaults 0 0' >> /etc/fstab
# 验证
pvs && vgs && lvs
df -hT /mnt/data
# 在线扩容(两步缺一不可)
lvextend -L +5G /dev/datavg/datalv
xfs_growfs /mnt/data
32.3.5 防火墙
# 开放服务(推荐,语义清晰)
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
# 开放自定义端口
firewall-cmd --permanent --add-port=2222/tcp
firewall-cmd --reload
# 查看所有规则
firewall-cmd --list-all
32.3.6 SSH 安全配置(三步联动)
# 第一步:修改 sshd_config
vim /etc/ssh/sshd_config
# Port 2222
# PermitRootLogin no
# PasswordAuthentication no
# 第二步:SELinux 放行新端口
semanage port -a -t ssh_port_t -p tcp 2222
# 第三步:防火墙放行新端口
firewall-cmd --permanent --add-port=2222/tcp
firewall-cmd --reload
# 验证语法后重启
sshd -t && systemctl restart sshd
32.3.7 Podman 容器与 systemd 集成
# 运行容器(:Z 修复 SELinux 上下文)
podman run -d --name web01 \
-p 8080:8080 \
-v /data/html:/var/www/html:Z \
registry.access.redhat.com/ubi9/httpd-24
# 容器管理
podman ps -a
podman logs web01
podman exec -it web01 bash
# 配置开机自启(systemd 集成)
podman generate systemd --name web01 --files --new
cp container-web01.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable --now container-web01
32.4 考试易失分点速查
| 考点 | 常见错误 | 正确做法 |
|---|---|---|
| SELinux | 修改 SSH 端口后忘记添加端口上下文 | 端口变更必须同步 semanage port -a |
| 防火墙 | 永久规则不加 --reload |
加了 --permanent 必须 --reload 才生效 |
| systemd | 修改 unit 文件后忘记 daemon-reload |
任何 unit 文件变更后必须执行 |
| LVM 扩容 | lvextend 后忘记扩展文件系统 |
必须再执行 xfs_growfs 或 resize2fs |
| fstab | 使用设备名(/dev/sdb1)而非 UUID |
用 blkid 获取 UUID 写入 fstab |
| Ansible | Playbook 不幂等(裸 command/shell) | 使用带 state: 的声明式模块 |
| 容器挂载 | 挂载卷忘记加 :Z |
SELinux 环境下挂载必须加 :Z |
| SSH 改端口 | 只改了 sshd_config,未同步 SELinux 和防火墙 | 三步必须同时完成 |
32.5 实践任务(模拟考试场景)
完成以下任务,每项完成后立即验证:
- 在
192.168.1.100创建用户devops,加入wheel组,设置 90 天密码有效期,验证:id devops和chage -l devops。 - 将 SSH 端口改为 2222,禁止 root 登录,禁用密码认证(三步联动),验证:
ss -tuln | grep 2222。 - 创建 10 GB LVM 逻辑卷(卷组
datavg,逻辑卷datalv),格式化为 XFS,永久挂载到/mnt/data,验证:df -hT /mnt/data。 - 编写 Ansible Playbook,在
192.168.1.101上安装 httpd,开放防火墙 80 端口,启动服务,验证:curl http://192.168.1.101。 - 运行 httpd 容器(端口 8080),生成 systemd 服务并配置开机自启,验证:
systemctl is-active container-web01。
32.6 自测问题
Q1:修改 SSH 端口后服务启动失败,最可能的原因和解决步骤是什么?
最常见原因是 SELinux 未更新端口上下文。ausearch -m avc -ts recent | grep sshd 确认 AVC 拒绝,然后执行 semanage port -a -t ssh_port_t -p tcp <新端口> 添加上下文,再 systemctl restart sshd。同时确认防火墙已放行新端口:firewall-cmd --list-ports | grep <端口>。
Q2:Ansible Playbook 执行时提示 changed 但重复执行仍然 changed,说明什么问题?
Playbook 不具备幂等性。通常原因是使用了 command/shell 模块执行每次都产生输出变化的命令,或缺少状态检查条件。解决方案:改用具备状态管理的声明式模块(dnf、systemd、file、copy 等);若必须使用 command/shell,添加 creates、removes 参数或 when 条件判断,确保只在必要时执行。
Q3:LVM 在线扩容后 df -h 显示大小没有变化,原因是什么?
lvextend 只扩展了 LVM 层的块设备大小,但上层文件系统的元数据(超级块中记录的块总数)未更新,应用程序看到的可用空间不变。XFS 需执行 xfs_growfs /mnt/data(在线扩容,无需卸载);ext4 需执行 resize2fs /dev/datavg/datalv(也支持在线扩容)。两步必须都完成,缺一不可。
32.7 章节总结
本章系统梳理了 RHCE(EX294)的核心考点:Ansible 自动化(Playbook 编写规范、变量管理、vault 加密、角色结构)和 RHEL 系统管理(用户权限、SELinux、systemd、LVM、防火墙、SSH 三步联动、Podman 容器)。重点整理了高频失分点对照表,建议结合第 33 章学习计划,以 8–12 周系统备考,确保每个考点都有充分的动手实操经验。