RHCSA课程接近尾声的时候,那种感觉我记得很清楚:每节课的知识点单独拎出来都懂,用户管理、LVM扩容、SELinux、firewalld、配个HTTP服务,单项操作也练得挺熟,但结课综合作业一拿到手,面对一张写满十来个子任务的题卡,整个人还是有点发懵。综合题把课程里所有核心模块打散之后重新串成一条链,做完一项可能就要回到前面调整配置,前后之间的互相干扰远比想象中多。这篇博文就聊一聊我当时是怎么拆解RHCSA结课综合作业、怎么搭实验环境、怎么逐项完成并最终验收的,希望给正在做同样作业或者准备认证的读者一些可以照着做的思路。
1. 结课综合作业的全貌:不是考单点,而是考串联能力
1.1 综合作业与平时练习题的本质区别
平时练习的时候,每道题都是设定好范围的,比如“给某用户一个sudo权限”或者“把某个目录做成SELinux允许的Web根目录”,范围很窄,一次只碰一个模块。结课综合作业不是这样,它通常模拟一个真实运维场景:给你一台刚装好系统的实验机,要求从零开始把它配置成一台符合各项要求的生产服务器。任务之间是有先后依赖的,而且经常互相影响。
比如作业里可能同时出现这样几条需求:某用户要能通过sudo执行重启命令;某服务发布在自定义端口上;SELinux保持强制模式;服务必须开机自启。单独看都不难,但合在一起就有连锁反应了——如果端口改了,firewalld要放行;如果SELinux是强制模式,服务监听自定义端口时可能还要配置布尔值或者自定义端口标签。这种“牵一发而动全身”的体验,平时分段练习根本碰不到。
1.2 作业背后对应的RHCSA知识点域
为了理清思路,我当时把课程内容整理成了一张知识域对照表,每次动手前先对照这张表确认这次改动会影响哪些模块:
| 知识域 | 典型操作 | 综合作业里常见的落地点 |
|---|---|---|
| 用户与权限 | useradd、groupadd、chage、sudoer配置 | 创建用户组、设置密码策略、分配sudo权限、设置账户有效期 |
| 存储管理 | LVM创建与扩容、文件系统挂载 | 新增磁盘、建PV/VG/LV、扩容逻辑卷、配置fstab永久挂载 |
| 网络配置 | nmcli连接配置、主机名、路由 | 配置静态IP、设置主机名、允许某端口通过防火墙 |
| 服务管理 | systemd服务单元、HTTP/FTP服务 | 安装并配置httpd或vsftpd、自定义根目录、开机自启 |
| 安全模块 | SELinux状态与文件上下文、firewalld富规则 | 保持enforcing、为服务放行端口、设置文件上下文 |
| 日志与排错 | journalctl、/var/log/messages、sshd日志 | 根据日志定位服务启动失败、验证配置效果 |
有了这张表之后,综合作业在我眼里就不是一堵墙,而是六个需要依次攻克的房间。每个房间内部的命令都是学过的,我真正要练的是怎么在房间之间走通。
1.3 拿到作业题卡后的第一件事:先做减法
很多同学拿到综合作业第一反应是马上动手敲命令,这其实是最容易翻车的。正确做法是先通读一遍题卡,把自己已经非常熟练的项先划掉,把没有把握的项圈出来。我的习惯是给每个任务标注三个状态:A代表完全会做且能独立演示,B代表会做但容易出错,C代表需要查资料才能搞定。动手之前,凡是B和C状态的项,先单独花半小时补一轮专项练习,等有把握了再进综合环境做。C状态的任务如果时间实在不够,我会尽量把它们排在最后去做,避免开头就卡住导致整个节奏崩掉。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 实验环境搭建:多台虚拟机和网络拓扑的前期准备
2.1 用三台虚拟机模拟真实运维拓扑
结课综合作业虽然大多是单机任务,但有些任务(比如网络配置、跨主机访问验证)在单台虚拟机上是没法完整验证的。我自己准备了一个固定的实验拓扑,三台虚机:
- server-a:主实验机,承担绝大部分作业任务,装完整版系统
- client-a:客户端,用于验证从别的机器能否访问server-a上的服务
- rhel-lab:备用实验机,最小化安装,专门用来做克隆测试和破坏性实验
这个拓扑覆盖了大多数综合题的验证场景。比如在server-a上配好了HTTP服务,我不会只在server-a上用curl测,而是到client-a上从另一台机器发请求。这一步很关键,因为有的时候firewalld配置不对,本机测是本机通、外面不通,只有跨主机验证才能发现问题。
2.2 网络规划:一张表格把地址和管理关系理清楚
虚拟机的网络很讲究,我当时用的虚拟网络配置如下:
| 主机名 | 角色 | IP地址 | 子网掩码 | 默认网关 | DNS |
|---|---|---|---|---|---|
| server-a | 主实验机 | 192.168.122.10 | 255.255.255.0 | 192.168.122.1 | 192.168.122.1 |
| client-a | 验证客户端 | 192.168.122.20 | 255.255.255.0 | 192.168.122.1 | 192.168.122.1 |
| rhel-lab | 备用实验机 | 192.168.122.30 | 255.255.255.0 | 192.168.122.1 | 192.168.122.1 |
IP地址段选的是NAT模式的网段,好处是虚拟机之间互通,也能访问外网。要注意的是,有些同学做作业时图省事直接把主机名留在默认的localhost,结果后面做证书、做主机名解析相关的任务时全乱套了,所以我从一开始就把三台机器的主机名都改好,并且写了 /etc/hosts 的互相解析。
2.3 快照模板:避免“再来一次”变成“重新装系统”
练综合作业难免翻车,有时候搞坏grub引导、把系统服务删得乱七八糟、或者是SELinux配置错了导致ssh都登不进去,这时候如果没有快照,就只能重装系统,非常浪费时间。我的做法是:
- 在系统刚装好、完成最小配置(主机名、IP、yum源)后,立即拍一个快照,命名为 clean-base
- 每次完整过一遍作业后,如果要重做,就把系统还原到 clean-base
- 在做破坏性实验之前,再拍一个 pre-experiment 快照,出问题可以直接回滚
这个习惯让我的练习节奏快了很多。不夸张地说,有一次我把firewalld默认zone的富规则写错了,再加上SELinux端口标签配错,service死活起不来,排查了半小时没头绪,直接回滚快照重来,三分钟就恢复状态了。练习时快照恢复不算“作弊”,真正上考场时系统一定是全新的,但在家练的时候,快照是为了提高练习密度。
3. 五大核心模块逐项拆解:命令背后的逻辑比命令本身重要
3.1 用户与权限模块:用户、组、sudo和密码策略的连带关系
综合作业在这一模块常考的组合是:创建若干普通用户、分配到一个指定组、设置密码有效期、给某几个用户sudo权限。命令本身不多,但有几个细节我非常容易漏:
- 批量创建用户时,用 for 循环配合变量比一条条写useradd效率高,也更接近真实运维场景。我当时的脚本长这样:
bash复制for user in alice bob charlie; do
useradd -G wheel "$user"
echo "123456" | passwd --stdin "$user"
chage -M 90 -W 7 "$user"
done
这里等价于在批量建用户时统一把密码设为123456,并要求每90天更换、提前7天警告。要注意chage的-M参数是最大天数,-W是警告天数,有些作业会要求同时设置账户在某个日期过期,那就要用 -E。还有一点:如果要求用户下次登录时必须改密码,那就需要 passwd -e "$user" 强制过期。
- 关于sudo,最常考的是“某用户无需密码就能执行某几个命令”。这种要在 /etc/sudoers.d/ 下建独立文件,比直接改 /etc/sudoers 更规范。比如:
bash复制echo "alice ALL=(ALL) NOPASSWD: /usr/bin/systemctl, /usr/bin/reboot" > /etc/sudoers.d/alice
chmod 440 /etc/sudoers.d/alice
sudoers文件的权限必须是440,否则系统会拒绝加载,这是一个很容易踩的坑。另外,平时练习用 visudo 编辑,但批量写入时我用tee或者echo重定向再检查权限,效果一样。
3.2 存储管理模块:LVM的完整生命周期与fstab的坑
存储模块的典型任务是:给系统加一块新盘,创建物理卷、卷组、逻辑卷,格式化并挂载到指定目录,并写入fstab保证重启后仍然挂载。完整命令链路如下:
bash复制# 查看新磁盘
lsblk
# 创建分区
fdisk /dev/sdb # 建一个主分区 /dev/sdb1,类型设为8e(LVM)
# 创建PV、VG、LV
pvcreate /dev/sdb1
vgcreate vg_data /dev/sdb1
lvcreate -L 5G -n lv_data vg_data
# 格式化并挂载
mkfs.xfs /dev/vg_data/lv_data
mkdir -p /data
mount /dev/vg_data/lv_data /data
# 写入fstab实现永久挂载
echo "/dev/vg_data/lv_data /data xfs defaults 0 0" >> /etc/fstab
mount -a
这里面最需要注意的坑有三个。第一个,LVM的卷组和逻辑卷命名要规范,我习惯用 vg_前缀和lv_前缀,避免出现含义不明的名字。第二个,xfs文件系统不支持缩减,如果作业要求“缩小逻辑卷容量”,必须改用ext4来格式化,这时候要明确用mkfs.ext4,然后挂载参数也要对应。第三个,fstab里千万不要直接写设备路径,比如 /dev/sdb1,因为一旦重启后盘符顺序变化(比如因为克隆或者插拔硬盘),系统可能挂载失败甚至是起不来。规范的做法是用UUID或者卷组逻辑卷路径(/dev/vg_name/lv_name),我一般在使用blkid查UUID写上更稳妥。
扩容是另一个高频操作。逻辑卷的扩容分三步:先给LV扩容(lvextend),再给文件系统扩容。xfs用xfs_growfs,ext4用resize2fs,这两条命令容易混淆。好多同学在练习的时候已经lvextend了,结果忘了文件系统那步,df查出来还是原来的容量,于是以为自己没扩容成功,反复重做。实际命令如下:
bash复制lvextend -L +2G /dev/vg_data/lv_data
xfs_growfs /data
3.3 网络与主机名配置:nmcli是考试中的主力工具
网络配置在综合作业里通常包含:配置静态IP、设置主机名、配置默认路由。虽然图形化的nmtui好用,但综合作业要求可复现、可验证,用nmcli更符合命令行风格。举一个典型的静态连接配置:
bash复制nmcli connection modify ens160 ipv4.method manual \
ipv4.addresses 192.168.122.10/24 \
ipv4.gateway 192.168.122.1 \
ipv4.dns 192.168.122.1
nmcli connection up ens160
改完IP后要立刻确认是否生效,ip addr 和 ip route 都要看。一个我踩过的坑是:如果连接配置里的 ipv4.method 没改成manual,而是直接add address,系统重启后地址会被清掉。另一个坑是:作业要求改主机名,千万不要只执行 hostnamectl set-hostname,要同时确认 /etc/hosts 里的对应关系,否则某些服务启动时会尝试反向解析主机名,解析失败可能拖慢服务启动甚至启动失败。
如果作业里有网卡绑定(bond)相关的要求,那就用nmcli创建bond接口:
bash复制nmcli connection add type bond con-name bond0 ifname bond0 mode active-backup \
ipv4.method manual ipv4.addresses 192.168.122.15/24
nmcli connection add type ethernet con-name bond0-port1 ifname ens161 master bond0
nmcli connection add type ethernet con-name bond0-port2 ifname ens162 master bond0
nmcli connection up bond0
这类操作出现的频率不算太高,但一旦出现,很多人会卡在“两张物理网卡加一个bond接口”的组合上,原因是slave连接没有指定master。记住这个顺序就可以了。
3.4 服务管理模块:httpd与vsftpd的配置连动
服务管理模块最常见的是httpd。基础配置不难,但综合作业里经常会要求“把网站根目录放在自定义路径,比如 /web”,这时就有三个层面要处理:
- 创建目录、改属主属组
- 在httpd的配置里改DocumentRoot
- 处理SELinux文件上下文,否则访问会403
当时我写了一个虚拟主机配置:
bash复制cat > /etc/httpd/conf.d/lab.conf <<EOF
<VirtualHost *:80>
ServerName server-a.lab
DocumentRoot /web
<Directory /web>
Require all granted
</Directory>
</VirtualHost>
EOF
配合的SELinux命令在下一节细说。vsftpd的话,作业里常要求“允许本地用户登录,但限制在家目录内”,对应配置文件 /etc/vsftpd/vsftpd.conf 里需要设置 local_enable=YES、chroot_local_user=YES,还要注意ftp根目录的权限问题——如果权限过高,用户登录进去会看到“refusing to run with writable root inside chroot()”的报错。解决办法是确保用户家目录属主对根目录没有写权限,比如 chmod a-w /home/ftpuser 之类的处理。
3.5 安全模块:SELinux与firewalld是作业中的隐形大考
安全模块是RHCSA课程里让最多人头疼的地方,但综合作业其实考得并不复杂,只要记住几个关键场景就够了。
SELinux部分最常见的一个命令组合是:
bash复制# 查看当前状态
getenforce
# 设置自定义Web根目录的文件上下文
semanage fcontext -a -t httpd_sys_content_t "/web(/.*)?"
restorecon -Rv /web
# 查看布尔值并设置
getsebool -a | grep httpd
setsebool -P httpd_can_network_connect on
这里有一个核心概念必须理解:SELinux不只是“开着还是关着”,它更关心的是“文件有没有正确的类型标签(context)”。你新建的目录默认类型可能是default_t,Apache在强制模式下没有权限读取default_t标签的文件,所以即使文件权限是777,浏览器访问依然403。这个坑的排查方法:使用 ls -dZ /web 查看目录的SELinux标签,确认是不是 httpd_sys_content_t;如果不是,用semanage加规则并restorecon恢复标签。千万别直接 setenforce 0 回避问题,很多作业明确要求SELinux保持enforcing。
firewalld部分,作业常给出类似“只允许来自192.168.122.0/24网段访问8080端口”的要求,对应的富规则写法如下:
bash复制firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.122.0/24" port port="8080" protocol="tcp" accept'
firewall-cmd --reload
这里反复出现的一个坑是忘记--permanent导致重启后规则丢失。我说个事情:有一次我做了firewall-cmd --add-port=8080/tcp,当时测是通的,但系统重启之后8080端口又变成了未放行状态。原因就是没用--permanent。经验是:凡是用firewall-cmd改动的,先加--permanent再reload,这是最不容易出错的姿势。另外,如果是自定义服务端口,还要确认SELinux对端口有没有限制,比如 httpd 要监听 8080 而非默认 80,就需要执行 semanage port -a -t http_port_t -p tcp 8080,否则SELinux会在强制模式下拒绝监听。
4. 整合性场景翻车复盘:踩过的坑和完整排查链路
4.1 HTTP服务装了配置了,为什么始终访问不了
这个场景几乎是必考的。表现:httpd已启动,端口也正常监听80,curl本机能拿到页面,但从client-a访问就是连接超时。我第一次处理时走了完整链路才定位问题,链路顺序很有参考价值。
第一步,先确认服务状态和端口监听。用 systemctl status httpd 看服务正常,ss -tlnp | grep :80 显示监听了所有接口。这时基本排除了服务本身的问题。
第二步,看firewalld。在server-a上执行 firewall-cmd --list-all,发现services里只有ssh,没有http。这就能解释为什么本机能通而外部不能通——本机回环访问不受防火墙限制,外部访问才会被拦截。执行 firewall-cmd --permanent --add-service=http 然后reload,问题解决。
这个排查链路虽然简单,但它的价值在于明确了优先级:先看服务,再看端口监听,最后看防火墙。很多人一上来就去查SELinux,绕了一圈才发现是防火墙规则漏了。
4.2 LVM扩容后df看到的容量没变,到底有没有成功
有一次我按作业要求给一个已挂载的逻辑卷扩容,lvextend执行成功了,但执行df -h发现容量还是老的。当时的排查过程是:第一步,用 lvs 查看逻辑卷的实际大小,发现确实已经变大了;第二步,用 xfs_growfs /data 把文件系统扩大;第三步,再执行df -h,容量变化了。这个场景暴露的问题是:逻辑卷是设备层面的概念,文件系统是数据层面的概念,两者是分离的。lvextend只是把“虚拟磁盘”变大了,就像硬盘变大了但分区里的文件系统还没有感知。必须再调用xfs_growfs或resize2fs让文件系统扩展到新容量。
如果做完还是没变,可能的另一个原因是扩容目标目录写错了,比如我把xfs_growfs写成了扩容旧路径。经验是:先lsblk和lvs确认设备状态,再df确认文件系统状态,每一步都拿命令输出验证,而不是想当然觉得每一步都成功了。
4.3 服务实现了开机自启,但重启后依然没起
这是一个非常经典的综合场景。表现:systemctl enable httpd返回成功,但reboot之后systemctl status httpd显示inactive。排查链路如下:
第一步,确认enable状态。执行 systemctl is-enabled httpd,显示enabled,说明服务单元的符号链接已经建立。
第二步,看启动日志。journalctl -b | grep httpd,发现根本没有启动尝试。这就很奇怪了,enabled的服务理应开机就启动。
第三步,检查网络依赖。因为我的httpd配置里ServerName依赖主机名解析,而network服务没有在启动时等待网络就绪,服务可能在网络配置完成之前尝试启动,然后失败退出。一些较新的版本里,服务管理器默认不等待网络就绪,除非单元文件里有 After=network-online.target 和 Wants=network-online.target。通过执行 systemctl enable --now NetworkManager-wait-online.service 再结合设置单元依赖可以解决。
这个坑的教训是:开机自启并不是简单一条enable就完事的,如果服务依赖网络、依赖外部挂载点、依赖SELinux策略,只要一个依赖不满足,启动就可能失败。排查时不要只盯着服务本身,要顺着依赖关系看:network -> NetworkManager-wait-online -> httpd。
4.4 克隆虚拟机后网卡名变了导致配置丢失
有一次我从模板克隆了一台新虚机做破坏性实验,开机后执行 ip addr 发现网卡从 ens160 变成了 ens176,之前的静态IP全丢了。原因是克隆时复制了原机的udev规则,系统为“新网卡”生成了新名字。排查思路:第一步,检查 /etc/udev/rules.d/ 下有没有持久网络规则文件,发现确实有一个包含旧MAC地址的规则文件;第二步,删除该规则文件;第三步,在克隆前先清理 /etc/machine-id,让新机器生成新的机器ID;第四步,reboot后网卡名恢复为系统默认命名。
这类问题在综合作业中不常直接考,但只要是基于虚拟化的环境就很可能遇到。提前知道这个坑,可以省下大把在“网卡怎么不见了”上纠结的时间。
5. 验收前最后的自查与调试:把作业变成可复现的工程
5.1 基于题卡的逐项验证清单
所有配置完成后,不要急着交作业,先按题卡逐项做一遍专项验证。我当时整理了一张自己的验证清单,每项都用实际操作去确认:
- 所有用户是否存在,id命令输出是否正确,密码到期时间是否如预期
- sudo权限是否生效,切换到该用户执行sudo -l能否看到被授权的命令
- lvm卷组和逻辑卷状态是否正确,df -h里的容量与挂载点是否一致
- fstab是否合法,执行mount -a无报错
- 防火墙规则是否包含预期服务,firewall-cmd --list-all输出完整
- SELinux是否为enforcing,自定义目录的标签是否与预期一致
- 从client-a访问server-a上的服务,确认外部访问正常
- 系统重启一次,再检查所有服务是否是active状态
这张清单看起来朴素,但每一条都对应一个作业子题。我当时甚至会把验证结果截图或者用文本保存下来,作为提交材料的辅助说明。
5.2 重启一次系统,检查一切是否还成立
综合作业里最常出现的“隐性要求”是永久性,也就是重启后配置仍然生效。很多同学配置当时是好的,一重启就全没了,因为没写fstab、没enable服务、或者防火墙规则没加permanent。所以我的验收习惯是:所有任务都完成后,先正常reboot一次,然后在开机后从头到尾再过一遍验证清单。这一步能直接暴露所有非持久化配置的问题。
有的题目还会要求不能关闭SELinux、不能关闭firewalld,这些也要在重启后再次确认。我曾经因为练习时为了方便把SELinux临时设成了permissive,重启前忘了改回来,结果提交前突击检查才发现。好在发现得早,setenforce 1加策略调整后重新验证了Web服务没受影响。
5.3 整理一份“变更记录”式交付说明
很多综合作业除了在系统上实现功能,还会要求交一份说明文档。内容说清楚配置了哪些东西、为什么这么配置、验证结果如何。这里不要把文档写成命令流水账,而是要写成“变更记录”的风格:这是从原状态到目标状态的变更清单,包含修改的文件路径、执行的主要命令、以及验证结果。
比如用户模块的交付说明可以写成:创建用户alice并加入wheel组,设置密码策略为每90天更换、提前7天警告,用passwd -e强制首次登录修改密码,通过如下命令验证:id alice、chage -l alice。这样审阅者一眼就能看到“改了哪些文件、加了哪些用户、验证结果如何”。我在提交作业时按照这个逻辑重新整理了所有命令和输出,不仅自己思路更清晰,审阅者看着也省力很多。
5.4 时间规划建议:先主干后边缘,留足排错量
做综合作业最缺的就是时间。我给出的时间分配建议是:环境搭建1小时以内完成;核心模块(用户、存储、网络、服务、安全)分配给每个模块1到2小时;整合性场景练习和复盘安排半天;最后留出至少两个小时做重启验证和文档整理。不用追求一次把所有任务全部完成,只要保证每个模块的配置都能重启后存活,就已经及格了。
最后说几个实操体会
整个综合作业练下来,我最大的体会是:系统管理这东西,命令背得再熟,也不如真正在一台机器上从头到尾配一遍。那些平时觉得琐碎的细节——加--permanent、restorecon、chmod 440、mount -a——单独看都是小事,可正是这些小事决定了配置是临时生效还是永久生效。结课综合作业的意义,就是逼着你把这些小事串成一套能自我验证的流程。练到后面,我甚至可以闭着眼写出从新装系统到Web服务可访问的完整步骤顺序,这个过程带来的信心,是刷多少套题库都换不来的。
