ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

RH134前半程核心解析:从命令行效率到SSH免密的自动化运维体系

RH134前半程核心解析:从命令行效率到SSH免密的自动化运维体系 我其实挺少看到有人认认真真坐下来把 RH134 前半程梳理成体系的。大部分备考的朋友要么抱着题海猛刷要么把课程从头到尾点一遍结果考完没几天就忘了。RH134 这门课红帽给出的全称是 Red Hat System Administration II对应的是 RHCSA 认证的完整考试范围。很多人的误区是觉得它就是 RH124 的续集多学几个命令而已。真正走过一遍之后你会发现RH134 的重点根本不在“认识新命令”而在“把系统运维自动化”。这一篇我先集中拆解前半程的核心模块命令行效率、周期任务、时间同步、性能调优、SSH 免密。这几个主题在教材里分在不同章节但实际是一条线——都是为了让一台 Linux 服务器在无人值守的情况下稳定干活。下面我会按自己的学习顺序把每个模块的设计思路、关键命令、实际操作和踩坑经验全部整理出来。正在备考 RHCSA 或者刚开始接触企业 Linux 运维的朋友这篇文章应该能帮你省掉不少自己绕弯的时间。1. 先聊聊 RH134 前半程的课程设计与学习思路RH134 前半部分学下来我的整体感受是它不像 RH124 那样什么都讲一遍而是围绕“自动化运维”这个目标重新组织内容。红帽官方把 RH134 定位为 RHCSA 的第二门课程考纲覆盖的内容其实和 RH124 有大量重叠但是深度和角度完全不一样。RH124 教你“这个命令能做什么”RH134 教你“如何让一系列命令在正确的时间、以正确的优先级、在正确的环境下自动执行”。举个例子RH124 里你会学到cron是 Linux 的计划任务工具然后练习一下怎么写crontab。RH134 里你不仅要会用还要知道 cron 任务执行时为什么不加载用户的登录环境变量、为什么脚本里的命令要写绝对路径、日志要在哪里排查、权限不够时任务为什么直接不跑。这些细节看上去不起眼却是实际运维中最容易翻车的地方。我建议把前半程拆成下面三个层次来学习第一层是提升操作效率。核心是 PATH 环境变量、自定义命令、bash 历史技巧。目的很简单让你在命令行里少敲重复命令。这一层掌握得越牢后面所有模块的实操速度都会快一截。第二层是让系统自动干活。核心是 cron、at、systemd timer 这类计划任务工具。目的不是背格式而是理解“系统调度机制”的完整链路包括服务、日志、环境、权限。第三层是让系统稳定运转。核心是时间同步chrony、进程优先级nice/renice、SSH 免密认证。这些内容单独看起来不复杂但组合在一起就是一台服务器“自我管理”的基础设施。这三个层次并不是完全独立的。比如 SSH 免密配置好之后cron 任务里就能放心调用ssh userhost command去远程执行脚本时间不同步时日志错乱会直接影响你排查 cron 任务是否准时执行。这也是为什么我把这几个模块放在同一篇总结里它们在生产环境里本来就是互相咬合的一整套东西。2. 命令行效率PATH、shell 历史与自定义命令RH134 前半程第一个让我觉得“终于有人讲明白”的模块是关于命令行效率的部分。它不会单独列一张命令大全让你背而是教你从机制层面去理解shell 是怎么找到命令的、什么情况下会找不到命令、怎么把自己写的脚本变成系统级命令。2.1 PATH 环境变量决定了“为什么敲命令找不到”当你在终端输入一个命令shell 并不会全盘扫描整个文件系统去找它而是按 PATH 环境变量中记录的目录顺序一个一个目录查找。找到第一个同名可执行文件就停止。如果全部找完都没有就会报command not found。echo $PATH默认输出大概长这样/root/.local/bin:/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/binRH134 里反复出现的一个场景是你自己写了一个脚本放在/root/scripts/下面给了执行权限但是敲名字执行时提示找不到命令。原因就在 PATH 里没有包含这个目录。解决办法有两个方向把脚本放进 PATH 已有的目录比如/usr/local/bin/这是最推荐的方式把脚本所在目录加进 PATH比如在~/.bashrc里追加一行。echo export PATH$PATH:/root/scripts ~/.bashrc source ~/.bashrc我自己的经验是考试环境里尽量使用第一种方式也就是把脚本放入/usr/local/bin/。原因很简单RHCSA 考试对“命令可用范围”是有要求的你通过修改登录环境变量的方式添加 PATH只能在当前用户当前 shell 里生效如果题目明确要求“所有用户都能执行”那就必须把脚本放到公共目录而不是去改某个用户的 bashrc。2.2 自定义命令脚本的编写规范RH134 里自定义命令不只是写一个 shell 脚本那么简单它讲究一套完整的规范目的是让脚本在自动化场景里可复用、可排错。我按自己的实操习惯整理了几个必需点。脚本头部必须有#!/bin/bash声明解释器然后设置set -o nounset和set -o errexit。它们的作用分别是遇到未定义变量时报错退出遇到命令执行失败时立即退出。这样脚本不会带着错误状态继续往下跑这在 cron 任务里尤其重要因为脚本出错了你要能通过退出状态码第一时间发现。#!/bin/bash set -o nounset set -o errexit LOG_FILE/var/log/myapp/backup.log echo $(date %Y-%m-%d %H:%M:%S) backup started $LOG_FILE脚本写好之后需要赋予执行权限chmod x /usr/local/bin/my-backup一个容易被忽略的细节是脚本命名。尽量不要和系统已有命令重名比如test、kill、read否则会因为 PATH 查找顺序导致奇怪的行为。我一般习惯用带连字符的名字比如my-backup、sys-info既能识别是自己写的又避免和系统工具冲突。2.3 bash 历史技巧在考试中的价值RH134 前几章会花一点时间讲 bash 历史很多人觉得这部分是凑数实际作用很大。在考试里你敲命令的速度直接决定了能不能做完所有题目。下面这几个快捷键和语法我建议练到手感自然。!!执行上一条命令!$引用上一条命令的最后一个参数!string执行最近一条以 string 开头的历史命令Ctrl r反向搜索历史命令Ctrl w删除光标前一个单词。举个例子你刚刚创建了一个用户紧接着想给它设置密码传统方式是再敲一遍完整命令但用历史引用更快useradd testuser passwd !$!$会展开成上一条命令的最后一个参数testuser实际执行的就是passwd testuser。这类技巧在考试的时间压力下非常实用日常运维中也能少敲很多重复内容。3. 计划任务cron 是最常用答案但也是最容易出问题的部分计划任务这个模块几乎是 RH134 考试必考的内容也是生产环境里用得最多的自动化手段。很多刚入行的朋友只会写个crontab -e然后往里填五段式时间表达式却不知道任务没执行时应该从哪里排查。这一节我把时间格式、用户级和系统级 cron 的区别、环境变量问题、日志排查全部串起来讲一遍。3.1 cron 的时间表达式到底该怎么读cron 的时间格式是五个字段依次是分钟、小时、日期、月份、星期。用*表示任意值用逗号表示枚举用连字符表示范围用/表示步进。后面跟的是要执行的命令。下面这张表是记忆重点字段取值范围含义分钟0-59每小时的第几分钟小时0-23每天的第几个小时日期1-31每月的第几天月份1-12每年的第几个月星期0-7每周的第几天0 和 7 都表示周日几个常见写法# 每天 02:30 执行 30 2 * * * /usr/local/bin/my-backup # 每 10 分钟执行一次 */10 * * * * /usr/local/bin/check_disk.sh # 每周一到周五的 08:00 执行 0 8 * * 1-5 /usr/local/bin/report.sh有一个非常容易踩的坑日期字段和星期字段是“或”的关系。比如0 0 1 * 1在不少人的理解里是“每月第一天且是周一时执行”但实际语义是“每月 1 号执行并且也在每周一执行”。如果你真的想表达“每月 1 号且正好是周一”cron 做不到只能组合条件在脚本里判断。这个知识点在考试里出现过理解不到位很容易选错。3.2 用户级 crontab 与系统 /etc/crontab 的区别RH134 里会把 crontab 分两种用户级和系统级。用户级通过crontab -e编辑属于当前用户的计划任务系统级文件是/etc/crontab它多了一个“执行用户”字段格式是六段式。# /etc/crontab 示例 30 2 * * * root /usr/local/bin/my-backup日常维护中我绝大多数情况使用用户级 crontab因为不需要直接修改系统文件也不涉及额外的权限管理。考试中你也要留意题目要求的是“为某用户创建计划任务”这时的正确操作是crontab -u username -e而不是去编辑/etc/crontab。用户级 cron 任务默认会向该用户发送邮件输出如果没有配置邮件系统这些邮件会堆积在本地的/var/spool/mail/目录下。所以我一般会在每条任务后面加上重定向30 2 * * * /usr/local/bin/my-backup /var/log/my-backup.log 21这样既能记录输出又不会把本地邮箱撑爆排查问题也方便。3.3 cron 环境变量是隐藏杀手这是我认为整个 cron 模块里最值得单独拎出来讲的知识点。cron 在用户登录时不存在它由crond守护进程启动默认不会加载用户登录 shell 的环境变量比如/etc/profile或~/.bash_profile。它只使用一个极其精简的环境PATH 通常是/usr/bin:/bin。所以你在交互 shell 里能正常执行的命令放进 cron 里很可能因为 PATH 里没有/usr/local/bin而失败。解决办法有两个脚本里所有外部命令都写绝对路径比如/usr/bin/find、/usr/sbin/tcpdump在 crontab 文件顶部显式设置 PATH。PATH/usr/local/bin:/usr/bin:/bin 30 2 * * * /usr/local/bin/my-backup我自己更推荐“命令全用绝对路径 脚本内部定义变量”的做法因为在多个 Linux 发行版之间迁移 crontab 时这种写法最不容易出问题。另外%在 crontab 里有特殊含义它表示换行如果你要执行命令并把日期传给脚本比如0 2 * * * /usr/local/bin/backup.sh $(date \%F)这里必须写成\%F不转义的话 cron 会把%后面的内容当作标准输入传给命令。3.4 at 命令处理一次性任务周期性任务用 cron临时任务用at。比如你现在想预定 15 分钟后运行一个脚本用at比临时写一行 crontab 干净得多。at now 5 minutes /usr/local/bin/quick_check.sh输入完成后按Ctrl D提交。查看队列用atq删除任务用atrm 任务号。值得留意的是at服务由atd守护进程支撑如果执行at时提示无法打开作业文件或找不到队列先检查systemctl status atd。4. 系统时间同步时区设置与 chrony 排查时间问题在考试里看起来分值不大但实际生产中非常重要。日志记录、证书校验、Kerberos 认证、数据库事务、分布式集群的一致性几乎全都依赖系统时间的正确性。很多人复习 RH134 时直接跳过时间模块觉得无非是date -s改一下这个想法在单机环境里没错放到真实网络环境里就会吃大亏。4.1 timedatectl现代 RHEL 的时间管理入口RHEL 8/9 系列里时间管理统一走timedatectl取代了老旧的date、hwclock、tzselect那一套手动配置方式。timedatectl status这条命令能看到本地时间、UTC 时间、RTC 时间以及是否启用了 NTP 同步。查看当前时区timedatectl list-timezones设置时区timedatectl set-timezone Asia/Shanghai启用 NTP 自动同步timedatectl set-ntp yes不要再像以前那样去创建/etc/localtime的软链接除非你是在非常老的系统上操作。红帽考试现在要求的是timedatectl的用法这个命令本身工程化程度高直接改文件的方式很容易在系统更新时被覆盖。4.2 chrony 的配置与验证RHEL 8/9 默认的时间同步服务是 chronyd对应的配置在/etc/chrony.conf。配置文件里常见的是pool或server指令用来指定上游时间服务器。pool 2.rhel.pool.ntp.org iburst配置完成后重启 chronyd 并验证systemctl restart chronyd chronyc sources -v输出里可以看到同步源状态^*表示当前已同步^-表示候选但未选择^?表示无法连接。继续查看同步精度和偏差chronyc tracking这一行里重点关注Leap status、Stratum和System time偏移值。如果Stratum是 15 或 16通常意味着该机器没有正常同步到上游时间服务器。还有一点chrony 默认监听的 UDP 123 端口需要能被外部访问如果配置了 firewalld要记得放行firewall-cmd --permanent --add-servicentp firewall-cmd --reload4.3 时间管理实操中的几个典型问题我遇到过的最典型的状况是系统明明开了set-ntp yes但chronyc sources显示所有源都是^?。排查思路是先看上游时间服务器是否可达用普通 UDP 连接测试不方便可以直接在 chrony 配置里换一个更近的池地址或者在客户端机器上抓包确认 UDP 123 是否有响应。另一个常见问题是刚部署完虚拟机时区还是默认的 UTC导致日志时间和本地时间差 8 个小时。修改时区之后要记得同步到硬件时钟timedatectl set-local-rtc 0 hwclock --systohc很多人在这一步漏掉hwclock的同步重启之后时间又变回去了。考试里虽然不一定要求你操作硬件时钟但理解“系统时间”和“硬件时钟”的区别是基本要求。5. 性能调优nice/renice 与 systemd 参数性能调优这个模块乍一听很高大上RH134 前半程涉及的内容其实非常务实核心就是进程优先级和如何把一个进程放到受限的环境中运行。5.1 nice 值到底是什么Linux 的进程调度器会根据进程的优先级来决定 CPU 时间片的分配。这个优先级在用户态用一个叫 nice value 的值来表达范围是 -20 到 19。数值越小优先级越高越容易被调度器选中执行数值越大优先级越低越“谦让”其他进程。用生活化的类比来说CPU 就像一个只有一个窗口的食堂打饭口进程是排队的人。nice 值越低的人越优先插队nice 值越高的人越靠后站着。这个“礼貌值”的名字nice本身就说明了一切你对别的进程越礼貌你的 nice 值越高。查看进程的 nice 值ps -o pid,ni,comm -p PID启动一个进程并设置 nice 值nice -n -5 /usr/local/bin/performance-test注意普通用户只能调高自己的进程 nice 值让进程更谦让不能调低让进程更优先。只有 root 用户能把 nice 值降到负数。5.2 renice 调整运行中的进程进程已经跑起来了发现它占用了太多 CPU或者需要提速可以用 renice 调整。renice -n 10 -p 12345这个操作把 PID 12345 的 nice 值设置为 10让它的调度优先级变低。如果是把一个 CPU 密集型任务降权在真实服务器上效果立竿见影原本卡顿的其他服务会明显恢复响应。需要强调的一点是nice/renice 调整的是“调度优先级”不是“CPU 配额”。也就是说系统负载不高时一个 nice 值高的进程照样可能跑满 CPU只有在多个进程争抢 CPU 时nice 值才真正发挥作用。很多人在性能调优时把这个概念搞混以为设置了 nice 值就等于限制了 CPU 使用率实际不是一回事。如果要做硬性限制需要配合cgroups或者systemd的CPUQuota等机制。5.3 systemd-run 与 systemd 服务级别的优先级控制RH134 里比较新的考纲内容是把进程放到 systemd 管理的 scope 下运行。systemd-run这个命令允许你临时启动一个程序并给它设置多种资源控制参数包括 CPUWeight、MemoryMax、Nice 等。systemd-run --unittest-task --nice-5 /usr/local/bin/performance-test这条命令把performance-test放到一个名为test-task的 systemd scope 中运行并指定 nice 值为 -5。查看运行情况systemctl status test-task systemctl show test-task -p Nice如果这个过程需要长期作为服务运行更标准的做法是编写 systemd unit 文件在[Service]段里写[Service] ExecStart/usr/local/bin/performance-test Nice-5这样服务启动时就会自动以指定优先级运行非常适合数据库、计算任务这类需要稳定调度顺序的场景。学习这个模块时我建议把nice、renice、systemd-run三个命令放在一起练这样你能同时理解“用户态直接调进程”和“通过 systemd 管理进程”两条路径考试题目无论从哪个角度出都不会慌。5.4 性能调优的验证方法调优完之后怎么证明生效了我的习惯是开两个终端窗口一个窗口用 top 实时观察进程状态另一个窗口执行测试任务。top在 top 输出里NI 列就是进程的 nice 值。如果任务开始跑NI 列的数字应该和预期一致。执行密集计算后观察 CPU 时间在各进程之间的分配比例也能明显感受到优先级差异带来的调度效果。验证 systemd-run 创建的 scope 时用systemctl status test-task看进程的 CGroup 归属和资源限制。6. SSH 免密配置从生成密钥到故障排查完整梳理SSH 免密是 Linux 运维里出镜率极高的需求。RH134 专门安排了这个模块因为它是后续自动化脚本、Ansible 批量操作、集群互信的基础。没有免密你的 cron 远程任务根本没法稳定地无人值守执行。6.1 密钥生成与分发标准流程免密登录的原理其实很简单客户端生成一对密钥公钥放到服务器的某个用户家目录下的authorized_keys文件里后续 SSH 登录时服务器用公钥验证客户端的私钥签名验证通过就放行不再询问密码。在客户端生成密钥ssh-keygen -t rsa -b 4096默认会在~/.ssh/id_rsa生成私钥~/.ssh/id_rsa.pub生成公钥。如果不希望每次登录都输入保护密码一路回车即可。分发公钥到目标服务器ssh-copy-id -i ~/.ssh/id_rsa.pub userserver这一步会要求输入目标用户的密码输入正确后公钥就被追加到远程主机的~/.ssh/authorized_keys。免密配置完成后测试ssh userserver hostname; uptime这条命令如果直接返回主机名和运行时间不提示输密码说明免密配置成功。6.2 权限和 SELinux 上下文SSH 免密失败十有八九是权限问题。OpenSSH 对关键文件和目录的权限要求非常严格任何“过度宽松”都会导致密钥验证被拒绝。标准要求如下路径要求权限客户端~/.ssh/700客户端~/.ssh/id_rsa600服务端~/.ssh/700服务端~/.ssh/authorized_keys600调整权限的命令chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys如果是 RHEL 系统还要考虑 SELinux 上下文。正常情况下~/.ssh这个路径的 SELinux 类型是ssh_home_t。你手动创建或拷贝文件时上下文可能不对这会导致 sshd 拒绝读取 authorized_keys。修复方式restorecon -R -v ~/.ssh执行后再用ls -Z ~/.ssh/authorized_keys确认上下文已经恢复成unconfined_u:object_r:ssh_home_t:s0这类合法标签。6.3 排查 SSH 免密的思路免密登录失败时不要只盯着 authorized_keys 反复看。我一般按下面的顺序排查先用有密码连接测试连通性ssh userserver能登录吗如果密码都过不了先解决基本网络和用户认证问题用调试模式观察过程ssh -vvv userserver日志会清楚显示证书认证是否被接受看服务器端日志tail -f /var/log/secure重点看Authentication refused或no matching key type这类关键字检查服务器端sshd_config是否显式禁用了密钥认证。RHEL 8 默认PubkeyAuthentication yes但部分安全加固模板会改成 no需要确认。如果看到Permission denied (publickey,password)基本可以确定是权限或者密钥内容问题。重新执行ssh-copy-id是速度最快的修复方案因为它会自动处理权限和路径问题。7. 实战演练把前半程知识串成一个完整实验上面讲了这么多模块如果只是分别练习记忆是不够牢固的。我强烈建议搭一个两节点的实验环境把文章里提到的所有内容一次串起来。下面是我自己演练时完整跑过一遍的流程可以直接照着做。7.1 实验环境与目标准备两台虚拟机或容器一台作为server一台作为client。系统用 RHEL 9 或者 Rocky Linux 9 都行差别不大。目标如下在 server 上新增一个自定义命令/usr/local/bin/node-info输出主机名、IP、时间和内存使用情况给 server 配置 cron 计划任务每 5 分钟执行一次node-info并追加写入日志文件将 server 的时区设置为Asia/Shanghai并启用 chronyd 同步启动一个 CPU 密集测试进程通过 nice/renice 调整优先级配置 client 到 server 的 SSH 免密登录并远程执行node-info验证自动化链路完整。7.2 逐步操作记录第一步编写自定义命令脚本cat /usr/local/bin/node-info EOF #!/bin/bash echo Hostname: $(hostname) echo IP: $(hostname -I) echo Time: $(date %Y-%m-%d %H:%M:%S) echo Memory: $(free -h | awk /^Mem:/ {print $3 / $2}) echo --- EOF chmod x /usr/local/bin/node-info直接执行验证node-info如果提示找不到命令先确认/usr/local/bin是否在 PATH 中或者用完整路径/usr/local/bin/node-info执行。第二步创建 cron 计划任务crontab -e添加以下内容PATH/usr/local/bin:/usr/bin:/bin */5 * * * * /usr/local/bin/node-info /var/log/node-info.log 21保存退出后验证crontab -l等待几分钟后查看日志文件cat /var/log/node-info.log如果日志为空先执行systemctl status crond确认 crond 正常运行。第三步设置时区和时间同步timedatectl set-timezone Asia/Shanghai timedatectl set-ntp yes systemctl restart chronyd chronyc sources -v输出里出现^*后再执行chronyc tracking看 Leap status 是否为 Normal。第四步进程性能调优。在 server 上启动一个计算任务systemd-run --unitdemo-task --nice-10 sh -c while true; do echo running; sleep 2; done查看状态systemctl status demo-task systemctl show demo-task -p Nice能看到Nice-10说明配置生效。不需要这个任务时停止它systemctl stop demo-task第五步SSH 免密。在 client 上生成密钥并复制到 serverssh-keygen -t rsa -b 4096 -N ssh-copy-id -i ~/.ssh/id_rsa.pub rootserver测试免密登录并远程执行自定义命令ssh rootserver /usr/local/bin/node-info返回 server 的完整系统信息后再配合 cron 任务想想看如果这个命令被写进别的 server 的 crontab 里是不是就能实现多台机器定时远程收集状态这就是 RH134 前半程所有模块联动起来后真实能做的事。8. 常见问题与避坑速查表最后把这几个模块里我实际踩过、以及在辅导别人时看到的高频问题统一整理成一个速查表。每一条都是真实场景里发生过的不是从手册里抄来的。问题典型现象排查思路处理方案cron 任务未执行时间到了没有产生任何日志检查 crond 是否运行查看/var/log/cron确认 crontab 语法正确systemctl status crond查看日志中的实际执行记录脚本内命令改用绝对路径cron 中命令包含%报错日志显示参数被截断%被 cron 当成了换行符写成\%时区修改后重启失效重启后 time 又变回 UTC系统硬件时钟没有同步hwclock --systohcchrony 无法同步chronyc sources全是^?上游服务器不可达防火墙拦截 UDP 123配置的 pool 地址错误更换 pool放行firewall-cmd --add-servicentp检查网络连通性设置 nice 后感觉无变化高负载时目标进程还是占用大量 CPUnice 只在资源争抢时影响调度不限制 CPU 配额明确调整目标如果需要硬性限制配合 systemd CPUQuotassh 免密失败登录时仍提示输入密码权限不正确SELinux 上下文错误sshd_config 中禁用了密钥认证检查~/.ssh权限为 700、authorized_keys为 600执行restorecon -R -v ~/.ssh查看/var/log/secure自定义命令找不到输入脚本名提示 command not found脚本目录不在 PATH 中脚本没有执行权限移入/usr/local/bin后chmod x或把目录加入用户的.bashrc这之中我最想再强调一次的是 cron 环境变量问题。现实中很多任务“不执行”的真相并不是 cron 没运行而是脚本里用的命令在 cron 的精简 PATH 里找不到导致执行时报错但用户没收到邮件也没看日志。养成在 crontab 顶部声明 PATH、在脚本里用绝对路径的习惯之后这类问题能减少八成。RH134 前半程的这些内容单独挑任何一块出来都不难。但组合在一起它就构成了一套自动化运维的基础能力你自己定义一个可执行的命令让系统按计划去跑它保证系统时间正确调整进程优先级避免资源争抢再用 SSH 免密把远程操作串起来。这种能力不是背几条命令就能建立的需要多动手搭环境、多故意制造故障去排查。我自己学这部分的最大体会是红帽考试看重“结果正确”但生产环境更看重“结果可重复、可排查”。沿着这个思路去练习RH134 学完的效果会远比一张证书本身值钱。
返回列表