1. 从RH134考纲出发,说说哪些知识点最值得反复啃
RH134是红帽认证体系里系统管理员二阶段的核心课程,也是RHCSA考试后半段的主要覆盖范围。它跟RH124的区别在于:RH124解决的是“能不能上手操作”的问题,而RH134解决的是“能不能系统化地管理一台Linux机器”的问题。课程主线围绕用户与权限、进程与服务、存储管理、网络配置、软件包管理、系统日志与监控、计划任务等几个大块展开,听起来好像都是基础,但实际动手就会发现,真正的门槛全藏在命令背后的细节里。
这篇文章是“常用知识点汇总合集”的续篇。前一篇大概已经把RH124阶段的基础命令和常规操作梳理过了,这次我换个角度,不按考纲章节逐条罗列,而是以我在实际机器上反复用到的场景为线索,把RH134里那些“考了无数次、工作中几乎天天碰到、但很多人到考试当天才搞明白”的点挑出来,逐个拆开讲透。
适合看这篇内容的人,我觉得有三类:一是正在备考RHCSA、需要把知识点串成体系的人;二是刚接触Linux运维、想绕过教材直接上手干活的实习生或转行者;三是已经工作一两年、发现自己一直只会用某几个命令、遇到报错就只能搜索的初级运维。如果你属于其中任何一类,这篇内容应该能帮你省掉不少碰壁的时间。
我会尽量按“为什么要这样配、怎么落地执行、踩坑是什么”的顺序来写,涉及命令时会给出可以直接复制使用的写法,涉及配置文件时会展示完整内容。下面正式开始。
2. 用户与文件权限的深水区:不止是useradd和chmod
2.1 用户管理的隐藏参数与删除用户的真实困境
RH134阶段对用户管理的考察,已经不完全停留在useradd和passwd这种最基础的层面了。考试和实际运维场景里,更常见的是带参数的用户创建:系统账户、无登录shell、附加组、主组、有效期、家目录模板,这些才是真正拉开差距的地方。
我常用的用户创建组合是这样的:
useradd -r -s /sbin/nologin -d /opt/app -M appuser这里四个参数的用意要拆开看:-r表示创建系统用户,UID会落在系统账户区间(通常是1000以下,具体看发行版配置),这类账户用于跑服务而不是给人登录;-s /sbin/nologin指定不能交互式登录的shell,防止有人真的切到该账户下执行命令;-d指定家目录位置,-M则告诉系统不要在创建时自动生成家目录。这类组合常见于部署中间件或自研程序时,既能让进程以独立身份运行,又不暴露可登录的shell入口。
另一个容易翻车的点是删除用户。userdel如果直接不带参数执行,只会删除用户账户本身,它的家目录、收件目录、临时文件全都留在磁盘上。这对个人练习环境无所谓,但生产环境里通常会连带清理,标准写法是userdel -r,它会一并删除家目录和邮件池。真正让人头疼的是“删不掉”的故障,比如某个用户的进程还活着,系统会提示userdel: user xxx is currently used by process xxx。此时需要先确认进程再处理:
pgrep -u username pkill -u username userdel -r username安全生产前最好先备份该用户的数据,再执行清理。如果你只是想临时禁用某人而不删除数据,用usermod -L锁住密码,或者把用户的shell改成/sbin/nologin,这两种方式都比直接删账户温和,回滚也方便。实际管理服务器时我很少直接删除用户,多数情况下先用锁定的方式让账户失效,观察一段时间确认没有服务依赖后才真正清理,这样既安全又能随时恢复。
2.2 umask、setuid、setgid与粘滞位的叠加逻辑
权限部分,RH134的题目经常把umask、特殊权限位和目录权限混在一起考。umask的本质是“权限掩码”,它决定新建文件和目录的默认权限,其中文件的基准权限是666,目录的基准权限是777,最终权限等于基准权限减去掩码中存在的权限位。例如umask 022时,新建文件的权限是666-022,也就是644,新建目录是777-022,即755。
这里有个新手常犯的认知错误:umask 022是“减”,而不是“与”。如果掩码是027,文件默认权限是666-027=640,而不是拿二进制位去逐个与运算。理解了这一点,做题就不会错。
特殊权限位的表现和计算也比较容易混淆。setuid(4)、setgid(2)、sticky(1)三个位可以叠加在普通权限之上,使用方式像是chmod 4755 script或chmod 2770 /data/shared。它们各自的实际效果是:
- setuid:作用于可执行文件,让执行者临时拥有文件属主的身份。典型例子是
/usr/bin/passwd,普通用户执行它时能以root身份修改自己的密码。 - setgid:作用于目录时,新创建的文件会自动继承目录的属组,而不是创建者的基本组。这个在团队协作目录里特别有用。
- sticky:作用于目录时,只有文件属主、目录属主或root才能删除目录内的文件,
/tmp就是最典型的例子。
把这些位组合使用时要格外小心。我最常踩的坑是chmod -R 777和递归设置特殊权限位的组合操作。比如想设置一个共享目录为2770,结果手滑写成chmod -R 2777,不仅把目录和所有子文件的权限全部放大,还会让普通用户可以在目录里互相删文件——因为没加sticky位。建议是每次递归授权后都先跑一遍:
ls -lR /path/to/dir确认权限位没有越界,再正式上线。
2.3 ACL权限的日常用法与mask的坑
ACL(访问控制列表)在RH134的考纲里占有一席之地,原因在于传统的u/g/o权限模型搞不定“多个用户对同一目录拥有不同权限”的需求。ACL允许对独立用户、独立组单独授权,而不用把所有人都塞进同一个组里。
基础操作不复杂:
setfacl -m u:zhangsan:rwx /data/project setfacl -m g:devteam:rw /data/project setfacl -x u:zhangsan /data/project getfacl /data/project但ACL有一个很容易被忽略的机制:mask。当目录设置了ACL之后,mask值会自动出现在getfacl的输出中,它实际上限制了所有命名用户、命名组以及所属组能够获得的最大权限。换句话说,即使你给某个用户设了rwx,如果mask是r-x,那么该用户实际能用的权限只有r-x,ACL中记录的名字不会消失,但生效范围被mask截断了。
我遇到过不止一次这样的情况:开发反馈“我给某个账号授权的写权限怎么不生效”,登上去一看getfacl,mask是r-x,改动setfacl -m m::rwx之后立刻正常。所以记住,排查ACL问题时第一件事就是看mask,它负责卡住权限上限。生产环境里,如果团队协作频繁变动人员,建议干脆别依赖手写多条ACL,把目录的属组固定好,组内成员统一加组,再用一个默认ACL(setfacl -d -m)给新建文件自动继承权限,维护成本会低很多。
3. systemd:现代Linux服务管理的核心
3.1 为什么RH134绕不开systemd
RH134很大一部分考试内容围绕systemd展开,这个趋势不是红帽自己拍脑袋决定的,而是整个Linux生态随着RHEL 7引入systemd之后形成的现实。service、chkconfig、rc.local这些传统工具仍然存在,但已经全面让位于systemctl。考试不会问“systemd比SysV init好在哪”这种理论题,但会要求你完成“写unit文件、启动服务、设置开机自启、查看服务状态”这一整套动作。
理解systemd的关键在于它把“服务”抽象成unit,常见的有service(服务)、socket(套接字)、target(启动目标)、timer(定时器)等。systemctl的绝大多数操作都围绕unit展开,而unit的定义则写在.service文件、.socket文件等地方。和传统init脚本相比,systemd最大的优势是并行启动、按依赖关系启动、崩溃自动拉起,以及统一管理日志。
日常工作中最常用的几条命令值得反复盘:
systemctl start/stop/restart/reload 服务名 systemctl enable --now 服务名 systemctl status 服务名 systemctl list-units --type=service --state=running systemctl daemon-reload systemctl is-enabled 服务名其中enable --now是实践里非常顺手的组合,它把“设置开机自启”和“立刻启动”合并成一步,省去了两条命令两个步骤的冗余。写unit文件后一定要先执行daemon-reload,否则systemd仍按旧配置执行,这是一个非常高频的低级失误。
3.2 手写一个Tomcat自启动服务,把unit文件吃透
很多公司的中间件服务不是通过标准包管理器安装的,而是解压tar包直接部署的,这类服务不会自动注册到systemd,需要自己写unit文件。Tomcat就是一个很典型的目标,我之前花了不少时间踩这个坑,写清楚之后对其他Java服务就一通百通了。
在/etc/systemd/system/下创建tomcat.service:
[Unit] Description=Apache Tomcat Web Application Container After=network.target [Service] Type=forking User=tomcat Group=tomcat Environment=JAVA_HOME=/usr/lib/jvm/java-1.8.0 Environment=CATALINA_PID=/opt/tomcat/temp/tomcat.pid Environment=CATALINA_HOME=/opt/tomcat Environment=CATALINA_BASE=/opt/tomcat ExecStart=/opt/tomcat/bin/startup.sh ExecStop=/opt/tomcat/bin/shutdown.sh Restart=on-failure RestartSec=10s [Install] WantedBy=multi-user.target这个文件里有几个细节需要解释。
Type=forking是关键:startup.sh启动Tomcat后,主进程会fork出子进程然后自己退出,systemd需要知道“父进程退出不代表服务失败”,所以必须用Type=forking告诉它去认PID文件。而Tomcat的PID文件路径通过CATALINA_PID指定,systemd也要在ExecStart里能看到这个环境变量。如果你用Type=simple,systemd会认为启动进程就是服务主进程,而startup.sh很快就退出了,服务会被判定失败。
User和Group指定了服务运行的账户身份,这一点在生产环境里相当重要。用root跑Tomcat虽然省事,但一旦应用被入侵,攻击者直接获得root权限,风险极大。正规做法是创建一个专用账户,比如useradd -r -s /sbin/nologin tomcat,再把这个账户关联到Tomcat目录的属主上。
Restart=on-failure表示只在非正常退出时由systemd自动拉起进程,配合RestartSec=10s设置重启间隔,这样既能容忍偶发崩溃,又不会由于快速循环重启把系统资源耗尽。
写好之后的操作顺序我也说一下,很多人会漏掉某个环节导致失败:
chown -R tomcat:tomcat /opt/tomcat systemctl daemon-reload systemctl enable --now tomcat systemctl status tomcat --no-pager排错时优先看journalctl -u tomcat -e,这里会直接给出Java进程的启动日志,比看状态码更直观。Tomcat服务最常出现的“ExecStart格式错误”通常是因为行尾多了空格、路径写错、引号不匹配,不要慌,一行一行检查就行。
3.3 systemd故障排查的顺序与常用手段
服务启动失败,我习惯按以下顺序排查:
第一步,systemctl status 服务名 --no-pager,查看主进程状态、PID、最近日志。如果显示failed,第二步立刻journalctl -u 服务名 -n 100,重点看最后几十行有没有明确的报错关键字,比如Permission denied、No such file or directory、Executable path is not absolute等。
第三步,检查配置文件语法。unit文件里最常见的坑是:ExecStart要求路径绝对化且不能包含变量引用(除非在用/bin/sh -c等特定写法时),After=少了目标会用默认顺序启动,导致依赖网络的服务在网卡还没就绪时就开始启动。另外unit文件的权限也值得注意,chmod 777的unit文件会导致systemd拒绝加载,看到“permission denied”时先查文件权限。
第四步,如果确认unit没问题,再看SELinux或AppArmor的拦截日志,命令是ausearch -m avc -ts recent或查/var/log/messages。这个方法救过我好几次,很多奇怪的“服务起不来、看日志又不报错”最后都落在SELinux身上。
4. 网络与远程管理的正确姿势
4.1 静态IP配置:nmcli与配置文件的取舍
RH134阶段网络配置不会考得太深,但一定会要求你完成“把一台机器的IP从DHCP改成静态地址”这个任务。CentOS/RHEL系列管理网络的主流方式已经是NetworkManager,配置文件在/etc/NetworkManager/system-connections/下,而不是老教程里那个/etc/sysconfig/network-scripts/ifcfg-eth0。
我推荐优先使用nmcli,它比直接改配置文件可靠得多,原因是NetworkManager会在后台监听配置文件变化,某些版本下手动改完不会自动重载,而nmcli会保持状态一致。完整配置过程如下:
nmcli con add type ethernet con-name static-eth0 ifname eth0 ipv4.addresses 192.168.1.100/24 ipv4.gateway 192.168.1.1 ipv4.dns "8.8.8.8 114.114.114.114" ipv4.method manual nmcli con up static-eth0这里注意几个参数:con-name是连接的名称,可以自定义;ifname是实际网卡接口名,必须对应系统的真实接口;ipv4.method manual意为手动配置而不是DHCP。配置完成后验证网络是否生效:
ip addr show eth0 ip route show ping -c 4 192.168.1.1如果我必须改配置文件,也会在改动后通过nmcli con reload和nmcli con up来激活,而不是直接重启网络服务。这里有个实践小建议:在生产环境操作网络前,最好准备一个备用登录通道,比如带外管理或IPMI,否则一旦改错IP,SSH断掉之后只能去机房或靠应急恢复手段,非常被动。我在很多文档里都写过这句话,但还是每次都会有人踩。
4.2 主机名管理与SSH连接实用习惯
hostnamectl set-hostname是修改主机名的标准命令,同时建议手动维护/etc/hosts。有些环境下,重启后主机名会被DHCP或云平台重置,需要考虑使用nmcli general hostname来告诉NetworkManager持久化设置,或修改/etc/sysconfig/network。
SSH远程管理这块,我一般会注意三个细节:一是推荐用ssh-copy-id把公钥推到目标机器上,后续登录免密且比定期输入密码安全得多;二是限制/etc/ssh/sshd_config里的PermitRootLogin和PasswordAuthentication的值,避免root直接密码登录;三是改完配置务必重启sshd服务并开第二个会话验证,防止配置错误把自己锁在外面。这些习惯看似琐碎,但每一条都来自真实事故的教训。
4.3 firewalld的zone与端口开放
firewalld是后iptables时代管理防火墙的主要工具,RH134涉及它的常见操作。最基础的思路是理解zone(区域)的概念:每个zone代表一组规则,网络接口可以绑定到某个zone,zone里定义允许或拒绝的端口、服务和来源。
常用操作如下:
firewall-cmd --get-default-zone firewall-cmd --list-all firewall-cmd --add-port=8080/tcp --permanent firewall-cmd --reload firewall-cmd --list-ports--permanent参数的意思是写入持久规则,不加的话规则只在内存中生效,重启后消失。加了永久规则后必须--reload,否则当前运行时不会变化。这是一个非常经典的易错点:如果只加--permanent而不reload,当前防火墙状态不变,看起来“没生效”;如果只加不加永久参数,当前生效但重启后丢失。
如果服务本身启动了但外部访问不到,我通常先本机ss -lntp确认端口是否监听,再curl本机验证,然后检查firewalld规则,最后再看SELinux布尔值。按照这个顺序排查,多数问题能在前三步解决。
5. 系统日志与监控:关键时刻能救命的技能
5.1 journalctl的高频率用法整理
日志是系统运维最重要的信息源,RH134阶段需要掌握的是用journalctl快速定位问题。我用得最多的几个参数组合:
journalctl -u 服务名 -e # 查看某服务最新日志 journalctl -u 服务名 -n 50 # 查看最近50条 journalctl --since "10 minutes ago" --until "5 minutes ago" journalctl -p err -b # 查看本次启动以来的错误级日志 journalctl -f -u 服务名 # 实时追踪服务日志不同优先级日志用-p过滤是排查问题时的利器。err及以上通常对应真正的故障,warning多可忽略,debug则用于深入跟踪。我接到告警时通常先看-p err -b,把当次启动的错误全捞出来,再逐条分析。如果日志太多导致磁盘满了,可以设置SystemMaxUse参数限制journal占用空间,具体位置在/etc/systemd/journald.conf:
SystemMaxUse=500M改完记得重启journald服务;journalctl --vacuum-size=500M则能立即压缩现有日志占用。
5.2 日志持久化的关键前提:/var/log/journal
很多人没注意到一个细节:默认情况下journald把日志存在内存里的/run/log/journal,重启之后历史日志全没了。这在个人测试环境没问题,但在生产环境里如果遇到故障需要事后排查,丢日志的后果相当严重。
正确做法是手动创建持久化目录并设置正确权限:
mkdir -p /var/log/journal systemctl restart systemd-journald创建之后journalctl就会自动把日志写入磁盘。建议在部署新系统时尽早完成这一步,因为等到你发现已经晚了——历史日志早就没了。另外不同服务日志分开看,比如Web服务的访问日志和错误日志一般由应用自己输出到/var/log/下,不要只依赖journald,两个体系配合使用才能覆盖完整排查链路。rsyslog那边也值得一提:/etc/rsyslog.conf里的规则把日志分门别类写入/var/log/secure、/var/log/messages等文件,对后续审计和故障回溯帮助很大。
5.3 日常监控命令组合:top、ss、free、iostat怎么搭配
监控不是只盯一个指标,而是多维度组合。我常用的组合是:top看CPU和负载,free -h看内存,ss -lntp看端口监听和连接状态,iostat -x 1看磁盘IO。下面分别说明各命令的注意点。
top里最容易被忽略的是load average这个数字。有人一看到load高就以为CPU爆了,实际上load还受磁盘IO和进程等待的影响。应该结合%Cpu(s)里的wa(iowait)来判断,如果wa很高且进程普遍处于D状态,问题大概率在磁盘而不在CPU。
free -h的重点是看available,而不是简单看free列。Linux会把空闲内存用作缓存来加速读写,free值小不代表内存不够,available才是真正可用的余量。只要available足够,缓冲区占用高不用紧张。
ss -lntp替代了老的netstat,输出格式更清晰。排查“端口被占用”时,ss -lntp | grep 端口号能得到PID和进程名,再用ps -fp 该PID定位具体程序。生产环境里出现过同一个端口被残留进程占用导致新服务无法启动的问题,这类情况在ss输出里一目了然。
iostat -x 1着重看%util和await。如果%util持续接近100%,说明磁盘已接近吞吐上限;await过高则可能是排队时间增长,单个请求时延变大。两者同时偏高,基本可以确定磁盘性能瓶颈。
6. 软件包管理与dnf/rpm的细节
6.1 dnf与rpm的配合使用思路
RH134对软件管理的考察主要在dnf和rpm。处理好这两个工具的配合关系是重点:dnf关心的是依赖关系和仓库,rpm更关心已安装包的文件级信息。日常使用中,装软件用dnf,查文件属于哪个包用rpm,验证包完整性也用rpm。
以下组合是我多年来用顺手的:
dnf install -y 包名 dnf search 关键字 dnf provides /etc/nginx/nginx.conf rpm -qf /usr/bin/systemctl rpm -ql 包名 rpm -V 包名dnf provides在处理“某个文件找不到但不知道它属于哪个包”的场景里非常高效;rpm -qf则用于反向查询文件来自哪个安装包,线上排查时十分有用——比如你想知道/etc/my.cnf是从哪个包来的,一条命令就能定位。
6.2 配置本地仓库的完整思路
生产环境内网常常无法访问外网仓库,所以配置本地仓库是运维基本功。思路是:准备一台内网服务器,把ISO解压或挂载进去,用createrepo生成仓库元数据,然后在客户端配置.repo文件。
仓库配置文件位置在/etc/yum.repos.d/下,内容模板如下:
[local-base] name=Local Base Repository baseurl=http://192.168.1.10/repo/BaseOS enabled=1 gpgcheck=0配置完执行:
dnf clean all dnf makecache dnf repolist如果客户端提示找不到仓库或元数据过期,多半是baseurl路径不匹配或者仓库端没有执行createrepo。建议先在服务器上用浏览器或curl确认目录能否访问,再检查客户端配置文件,最后dnf clean all强制刷新缓存,很多时候问题就出在旧缓存上。
6.3 版本锁定与包验证的实战技巧
生产系统最怕的一件事是“重启后服务莫名不可用”,而常见原因之一是某个依赖包被意外升级。dnf versionlock可以锁住指定包的版本:
dnf install -y python3-dnf-plugin-versionlock dnf versionlock add nginx dnf versionlock list这个插件把指定包锁定为当前版本,后续执行dnf update时会自动跳过锁定项。使用时机是在重要服务部署完成后立刻锁定,不是等事故发生了才想起来。
rpm -V用于验证已安装包的关键文件是否被修改。比如怀疑/bin/ls被人动过手脚,可以执行rpm -V coreutils,输出里出现S.5....T.等标志说明文件的权限、大小、修改时间至少有一项和安装时不一样,这时候就要进一步排查。这个功能在安全审计场景里特别常用,却很少有人知道,掌握之后能帮你在系统异常时快速定位文件级别的变化。
7. 计划任务:at、crontab与systemd timer的取舍
7.1 at一次性任务的注意事项
Linux计划任务分三类:at处理一次性任务,crontab处理周期性任务,systemd timer作为更现代的方案逐渐流行。RH134要求至少掌握前两者,但实际工作中三者都值得了解。
at的用法很简单:
echo "sh /opt/scripts/backup.sh" | at 02:30 atq atrm 任务IDat运行前需要atd服务处于运行状态,并且用户必须被允许使用at命令,相关配置在/etc/at.allow和/etc/at.deny里。我个人的习惯是,只要任务会重复执行就优先用crontab而不是每次都写at,因为at任务清单不够直观,时间久了容易忘记有哪些遗留任务在等你。
7.2 crontab的时间格式与环境变量坑
crontab -l查看任务,crontab -e编辑任务,这是最基础的操作。时间格式“分 时 日 月 周”,五个字段分别对应,其中最需要仔细的是“星期”字段,取值范围是0到7,0和7都表示周日。
我踩过最大的坑是cron任务里PATH环境变量不全的问题。crontab执行环境不像登录shell那样有完整的PATH,所以/usr/bin/python3可能直接找不到python3。解决方式有两种:要么在crontab文件顶部设置PATH=/usr/local/bin:/usr/bin:/bin,要么在脚本内部使用绝对路径执行所有外部命令。第二种方式我自己更推荐,因为它不依赖cron服务端的配置,脚本拿到哪里都能跑。
%符号是另一个大坑。crontab中%有特殊含义(会被当作换行),如果命令里需要用到date +%Y%m%d这种带百分号的内容,必须转义为\%。不转义的结果是命令被截断且日志里全是aur error,非常难排查。
查看cron执行情况的方法:
grep CRON /var/log/cron tail -f /var/log/cron journalctl | grep crond7.3 systemd timer:更适合复杂任务的现代方案
如果你需要更精确的控制,或者任务涉及服务依赖关系,建议使用systemd timer。它的优势是支持日志统一收集、失败重试、随机延迟避免“整点风暴”,还能准确查看上次执行时间和下次执行时间。
一个最小示例是两个文件:
/etc/systemd/system/backup.service:
[Service] Type=oneshot ExecStart=/usr/local/bin/backup.sh/etc/systemd/system/backup.timer:
[Unit] Description=Run backup daily [Timer] OnCalendar=*-*-* 02:00:00 Persistent=true [Install] WantedBy=timers.target启动方式跟普通服务一样:
systemctl enable --now backup.timer systemctl list-timers journalctl -u backup.servicePersistent=true表示如果错过了预定执行时间(比如机器当时关机),下次开机后会立刻补跑,这一点是cron做不到的。我建议:任务简单就继续用crontab,任务多、依赖强、需要可靠记录时迁移到systemd timer。
8. 一些实在话
从头到尾把RH134的这些知识点再过一遍,其实看不出哪个是“难点中的难点”,但确实能感受到知识点之间的联系非常紧密。用户管理一定关联到文件和目录权限,权限又联系到进程运行身份,进程再关联到systemd服务,服务又绕不开网络与防火墙。考试时间紧张时,很多人的问题不是“不会”,而是“知识是散的”,遇到题目要从零开始拼接上下文,自然慢。我个人的体会是:学到这里,必须用手里的机器把每个环节串起来跑一遍,而不是一个个孤立的命令去背。准备一台干净的虚拟机,从建立用户、分配组、设置ACL、写unit文件、配防火墙、设计划任务,到模拟一次内存告警或磁盘告警并修复,整套流程演练下来,比刷两遍考纲更有用。
最后分享一个小技巧:如果你在实验环境里搞坏了某个服务,别急着重装系统,先systemctl status和journalctl -u把日志看明白,再尝试恢复。这个过程比单纯“能跑起来”更能锻炼排查能力。等到你遇到故障的第一反应不是“重启试试”,而是“先查日志再动手”,RH134的实操目标也就基本达成了。