ARTICLE DETAIL

资讯详情

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

RHEL 9.7部署优化实战:从内核参数到安全加固的完整指南

RHEL 9.7部署优化实战:从内核参数到安全加固的完整指南 RHEL 9.7 发布后我第一时间在测试环境做了部署验证随后又给几台生产用的 Linux 服务器做了一遍系统优化。很多人拿到新系统装完就急着跑业务不愿意花时间去读默认配置结果上线之后踩到一坑接一坑IO 延迟忽高忽低、内存被缓存吃干净、ssh 会话时不时断连、系统日志把根分区撑爆。这篇文章把我部署 RHEL 9.7 的过程以及平时优化 Linux 发行版时沉淀下来的方法整理成一套可以照着做的方案适合运维工程师、系统管理员也适合正在准备 Linux 面试或者刚开始接触服务器管理的朋友。我不会堆一堆调优命令让你直接抄作业而是把每个参数“为什么要动”“动了之后怎么验证”“出问题怎么回滚”讲清楚。毕竟生产环境不是实验室改挂了没人替你兜底。下面进入正题。1. 部署前要做的规划不是装完就完事1.1 先弄清楚要优化什么很多新人在部署 RHEL 9.7 时第一反应是“装最新的就是最好的”。但如果你上生产环境默认参数几乎不可能贴合你的业务场景。比如默认的 vm.swappiness 是 60内存稍微吃紧一点系统就开始把进程往 swap 里放传统机械盘上这会导致明显的卡顿再比如默认的日志上限虽然有journald 托管但面对高频业务的输出/var/log 分区被写满只是时间问题。做优化之前先给服务器定性它承载的是数据库、Web 服务、文件存储还是开发测试环境不同角色需要调整的参数重点完全不同。数据库侧重 IO 调度和内存回收Web 服务侧重文件句柄和网络栈文件存储侧重文件系统挂载参数和磁盘吞吐。先想清楚这台机器要干什么再动手改配置。否则照搬一篇教程轻则无效重则把本来就稳定的服务弄得异常。1.2 镜像选择、磁盘布局和最小化安装RHEL 9.7 的安装介质有两种常见形态完整 DVD ISO 和 Boot ISO。生产环境我建议直接用完整 ISO因为安装时可以顺便把需要的包都选好避免装完以后找依赖。个人实验场景可以选 Boot ISO 加网络源。如果你的网络环境没法直连 Red Hat 订阅服务可以提前搭一个本地 HTTP 源把 ISO 挂载到 /mnt用 createrepo 生成仓库元数据安装和后面更新都走这个本地源速度比外网快得多。磁盘分区建议用系统默认的 LVM 加 XFS 组合但把 /home 从根分区里拆出去。很多服务器 /home 的空间常年闲置而根分区被日志、容器镜像之类的东西填满。我的习惯是 /boot 单独 1G/home 给一个可调整的逻辑卷其余空间全部交给 / 后续哪块不够用直接用 lvextend 扩。swap 分区大小按物理内存来定内存小于 8G 时建议给到物理内存的 1.5 倍内存大于 16G 时不需要线性放大按 16G 加内存-16G× 0.5 计算比如 64G 内存给 40G swap 差不多。如果要用 kdump还需要额外预留一部分内存用于内核崩溃转储。安装类型选择上能选最小化就不要选带 GUI。服务器上装图形桌面不仅占用内存和 CPU还会多出一堆不必要的进程增加攻击面。RHEL 9.7 在安装时可以选择 Server with GUI 或 Minimal Install我几乎每次都选后者。安装过程中顺手把 Network Host Name 配好主机名用“用途-环境-编号”这样的格式比如 web-prod-01、db-test-02别用 localhost。后面管理多台服务器时一眼就能看出它是干什么的。1.3 系统装完后的第一轮基础配置系统重启之后第一件事是确认网络、时区和基础软件源。RHEL 9.7 默认不安装 ifconfig 命令用 ip addr 查看 IP 信息。修改网卡配置在 /etc/NetworkManager/system-connections/ 目录里以 keyfile 方式管理用 nmcli 命令更容易上手。举个例子nmcli connection modify eth0 ipv4.addresses 192.168.10.20/24 nmcli connection modify eth0 ipv4.gateway 192.168.10.1 nmcli connection modify eth0 ipv4.dns 223.5.5.5 nmcli connection modify eth0 ipv4.method manual nmcli connection up eth0这一步经常有人漏掉 DNS 配置导致后面 dnf 做更新时域名解析直接卡死。时区同步用 chrony 而不是老掉牙的 ntpdate。RHEL 9.7 自带 chronyd但默认只启用系统自带的一小部分服务器建议调整 /etc/chrony.conf 指向你所在环境能够访问的 NTP 服务器然后执行systemctl enable --now chronyd chronyc tracking查看输出中的 System time 一栏数值持续为 0 或非常小说明时间已经同步。时间不同步会导致日志时间错乱、证书校验失败、集群节点间通信出各种诡异问题尤其多机部署时这个问题会放大成灾难。基础工具方面我通常会补装这几个包vim、lrzsz、tree、bash-completion、sysstat、iotop、lsof、strace、tcpdump。RHEL 9.7 默认源里都有一条命令装齐dnf install -y vim lrzsz tree bash-completion sysstat iotop lsof strace tcpdump装完这些再开始做进一步调优工具齐了排查问题才顺手。2. 内核和资源调度优化2.1 内核参数到底哪些值得调RHEL 9.7 的内核版本在 5.14 基础上做了大量增强默认参数对大多数场景是安全的但谈不上最优。我调内核参数遵循一个原则一次只动一个模块改完观察一段时间再动下一个。不要一次性把几十条参数灌进 sysctl.conf出了问题根本不知道是谁的锅。生产服务器上我最常调整的参数有这几类内存回收类vm.swappiness 默认 60太高了。对于服务器我一般改成 10 到 30 之间。这个值的含义是内核在使用 swap 的“积极性”有多高值越大越积极。改成 10 以后系统会优先释放 page cache而不是频繁换页。注意别改成 0RHEL 9.7 支持设置为 0但这意味着页面回收时几乎不换出匿名页在某些低内存场景下反而容易触发 OOM。脏页回写类vm.dirty_ratio 和 vm.dirty_background_ratio 控制写入缓存到落盘之间的延迟。默认值分别为 20 和 10对于有大量小文件写的业务可以把 dirty_background_ratio 降到 5让内核更早开始后台回写避免一次性刷太多脏页导致 IO 抖动。如果拿不准先不要动这两个参数它们是“调错了影响全局”的那种。网络栈类高并发 Web 或反向代理服务器上我会调整这几个net.core.somaxconn 4096 net.ipv4.tcp_tw_reuse 1 net.ipv4.tcp_fin_timeout 15 net.ipv4.tcp_max_syn_backlog 8192somaxconn 影响 listen 队列的长度很多应用比如 Nginx 和 Redis都建议调大到 4096 以上。tcp_tw_reuse 允许回收处于 TIME_WAIT 状态的连接缩短连接关闭后的等待时间对短连接很多的业务帮助明显。每次修改 /etc/sysctl.conf 之后先执行sysctl -p让配置生效再用sysctl -a或直接sysctl 参数名验证。想回滚就备份原文件把备份内容恢复回去再重新加载。2.2 tuned 和启动参数管理RHEL 系发行版一个容易被忽略的优化工具是 tuned。它不是简单往 /proc 里写变量而是一组按场景编排好的性能调优组合覆盖 CPU 调度、磁盘调度、网络缓冲、透明大页等一堆内容。装好以后先执行tuned-adm recommend看它推荐哪个 profile再根据业务选择普通服务器通过tuned-adm profile virtual-guest或throughput-performance数据库、延迟敏感业务tuned-adm profile latency-performance节能需求比较大tuned-adm profile powersave我遇到过不少人自己辛辛苦苦调了一堆 sysctl 参数发现系统重启后有些被还原了原因就是 tuned 会在启动时接管一部分内核参数设置。建议的做法是先用 tuned 设置整体风格再通过 /etc/tuned/ 下自定义 profile 覆盖个别参数而不是和 tuned 对着干。启动参数层面RHEL 9.7 用 grubby 管理内核启动项。比如我想在启动时关掉 IPv6grubby --update-kernelALL --argsipv6.disable1如果之后想恢复用 grubby --update-kernelALL --remove-argsipv6.disable1 去掉即可。每次修改后记得执行grub2-mkconfig -o /boot/grub2/grub.cfg不过 grubby 在新版本里会自动生成对应配置这一步更多是为了双保险。启动参数里我还会保留 quiet减少启动时刷屏定位问题的时候再用 rd.shell 临时进入救援模式。2.3 存储、文件系统和 swap 的取舍存储优化是很多线上问题的重灾区。RHEL 9.7 默认文件系统是 XFS挂载参数建议加上 noatime 和 nodiratime减少每次读取文件时对 access time 的更新写入这对读多写少的场景提升明显。在 /etc/fstab 里找到对应行改成类似下面这样/dev/mapper/rl-root / xfs defaults,noatime,nodiratime 0 0注意 XFS 不能在线收缩只能扩大。分区规划如果不合理后面想缩只能通过备份恢复这也是为什么前面强调要把空间尽量交给根分区。传统机械盘建议把 IO 调度器调整为 bfq 或 mq-deadlineNVMe 固态盘则用 none 就好。RHEL 9.7 中可以通过 udev 规则或者 /sys/block/设备/queue/scheduler 临时修改。绝大多数现代服务器已经全 SSD这个参数的收益有限别在上面花太多时间。对于需要挂载 NAS 存储或者远程 NFS 的场景fstab 里这几点是关键使用 _netdev 确保网络挂载在网络就绪后再执行加 soft 而不是 hard 模式避免 NFS 服务端失联时客户端挂死同时设置 timeo 和 retrans。一个可用的写法是192.168.100.5:/data /mnt/data nfs4 noatime,_netdev,soft,timeo50,retrans2 0 0我在实际运维中就被 hard 模式坑过一次存储阵列升级几十台客户端全部夯住之后一律改用 soft配合监控告警至少服务器本体不会跟着一起瘫。swap 的调整也比较容易出现理解偏差。前面分区阶段已经把 swap 规划好如果在运行中需要扩大 swap先swapoff /dev/xxx然后 lvextend再 mkswap最后 swapon。这个顺序不要乱否则分区表会不一致。对内存大的机器swap 更像是一个保险丝别指望它提升业务性能。3. 安全加固和服务治理3.1 SELinux默认强制别一禁了之网上很多教程装完 RHEL 系以后第一件事就是setenforce 0并写进 /etc/selinux/config。我必须明确说这是最糟糕的习惯。RHEL 9.7 的 SELinux 默认 enforcing它的存在不是为了给你添堵而是对进程权限做最小化约束。生产环境把 SELinux 关掉等于把系统自带的安全边界拆了。真正应该做的是学会和 SELinux 合作。如果某个服务因为 SELinux 策略访问被拒绝先看日志ausearch -m AVC -ts recent audit2why -i /var/log/audit/audit.logaudit2why 会告诉你具体是哪条策略拦住了什么有时候只是文件标签不对。比如把 /home 下的目录用作 Web 根目录nginx 无法访问这时候正确做法是semanage fcontext -a -t httpd_sys_content_t /home/webroot(/.*)? restorecon -Rv /home/webroot我已经数不清有多少第三方安装文档写着“先关闭 SELinux 再安装”这种文档在 RHEL 9.7 上直接把你的安全基线拉低一截。宁可花半小时把策略调对也不要图省事一禁了之。3.2 SSH、用户和密码策略SSH 是服务器最暴露的服务部署后第一轮加固就是改它。在 /etc/ssh/sshd_config 里我建议做这几项调整Port 2222 PermitRootLogin no PasswordAuthentication no PubkeyAuthentication yes MaxAuthTries 3 ClientAliveInterval 60 ClientAliveCountMax 3把端口从 22 迁走能挡掉大量的扫描式爆破。但改端口前一定要确认防火墙的放行规则也跟着改否则 sshd 重启后你自己先连不进去了。更要紧的是先把自己的公钥放进去确认能成功登录再关掉密码认证。顺序如果反了你可能会把自己锁在门外。真要找回机器只能去机房或者用带外管理口这教训太深刻了。普通用户和提权管理用 systemd 好习惯平时用一个普通账号干活需要管理员权限时通过 sudo 切换。新建用户和设置密码过期提醒的常用命令如下useradd ops passwd ops chage -M 90 -W 7 ops # 90天内必须改密提前7天提示 chage -l ops # 查看用户密码策略给管理员授权时不要直接编辑 /etc/sudoers而是放到 /etc/sudoers.d/ 下面echo ops ALL(ALL) NOPASSWD:ALL /etc/sudoers.d/ops这样既清晰又不会因为手抖写错主文件导致所有 sudo 都不可用。目录里每次新增文件之前先用visudo -cf校验语法。3.3 dnf 源、更新与日志控制RHEL 9.7 的软件管理是 dnf使用习惯和 CentOS 不太一样。生产环境不要看到 update 就无脑执行建议分场景处理。查看安全更新用dnf update --security安装特定软件包先用dnf provides 路径找归属包别靠猜。为了提升国内网络环境下的下载速度可以配置镜像站加速比如把 /etc/yum.repos.d/ 里的 metalink 切换到可用镜像注意做源配置备份避免源变更后依赖解析出错。没有订阅或者离线环境就用本地仓库dnf config-manager --add-repofile:///mnt/rhel9 dnf repolist日志控制这块journald 默认把日志写到内存和磁盘我见过 /var/log/journal 飙到几个 G 的情况。规定一个上限mkdir -p /etc/systemd/journald.conf.d cat /etc/systemd/journald.conf.d/sizelimit.conf EOF [Journal] SystemMaxUse200M EOF systemctl restart systemd-journald再配合 logrotate 把 /var/log/messages 等历史日志压缩保留。日志上限设好之后根分区会因为日志耗尽而满的机会小了很多。分区一旦写满业务进程写不了文件表现出的故障是千奇百怪排查半天最后发现 df -h 已经 100%。4. 从 RHEL9.7 到通用 Linux 优化4.1 常用命令和系统管理速查题目里“Liunes 操作系统”我理解大概率是 Linux 的笔误。RHEL 9.7 只是 Linux 的一个发行版下面这些优化经验在 Debian、Ubuntu、Rocky、Alma 等发行版上同样适用。首先把系统管理的常用命令整理成一张速查表有些朋友遇到问题第一反应是全网搜还不如先把这几个命令吃透。# CPU 负载 top mpstat -P ALL 1 # 内存 free -h vmstat 1 5 # 磁盘 iostat -x 1 df -hT du --max-depth1 -h /data # 网络 ss -tunlp ip -s link # 进程 ps -eo pid,ppid,stat,comm,%cpu,%mem --sort-%cpu lsof -p PID这些命令的熟练程度基本能反映一个运维的基础功底。面试里常考的 Linux 常用命令比如查端口占用、查文件被哪个进程占用、看服务日志本质上就是上面这批命令的组合。我建议不要死记选项而是理解每个命令背后的数据来源top 看的是 /proc/statfree 看的是 /proc/meminfoss 看的是内核套接字表这样记忆负担会轻很多。日常系统管理还有一个高频场景删除文件。rm -rf /的教训讲了一万遍还是会有人犯。我的习惯是删除重要目录之前先用ls -ld确认路径再在命令里写绝对路径时多看一眼能不用 -rf 就不用。更稳妥的做法是移动到 /tmp 观察几天再决定是否真正删除。删除文件夹命令要区分清楚rmdir 空目录和rm -r 递归删除前者删不掉非空目录后者会把目录连同内容一起清掉。操作前先du -sh看看目录大小心里有数再动手。4.2 修改进程名的几种方式Linux 修改进程名是面试和实际运维都可能碰到的话题。Java 和 Python 程序默认进程名经常是 java、python一旦起了多个实例ps 根本分不清谁是谁排查问题时只能靠 pid 号来回对。我的处理方式是让进程名带上业务标识。最简单的方式是在 shell 里用 exec 启动程序时传入新的 argv[0]exec -a payment-service java -jar /opt/payment-service.jarPython 或者任意 ELF 程序也可以这样处理。如果是 systemd 管理的服务在 ExecStart 里加上 exec -aExecStart/bin/bash -c exec -a web-api /usr/bin/python3 /opt/web-api/app.py如果程序内部想改自己的进程名C/C 可以用 prctl 系统调用Java 可以通过 jcmd 修改但改完以后只是 jps 里的显示名变化ps 里看到的还是原始 comm。理解底层逻辑比背命令更重要进程名本质上就是 argv[0] 和 /proc/pid/comm 的组合很多工具显示的是前者改进程名要同时照顾到两个层面。4.3 从 RHEL 迁移到其他发行版的关注点RHEL 9.7 的优化经验往其他 Linux 发行版迁移时有三个最容易踩的坑。第一包管理器不同。Debian/Ubuntu 用 aptRHEL 系用 dnf安装命令不能照抄但服务管理用的 systemd 在两大阵营里基本一致这是 Linux 生态的幸事。第二配置文件路径和默认 shell 有差异比如 RHEL 默认 bashDebian 的某些场景默认 dash脚本里用了 bash 的数组语法在 dash 下会报错。第三内核版本差异带来参数兼容问题比如某个 sysctl 参数在 RHEL 9.7 里存在在旧版 Debian 上可能就是 unknown key。做多发行版优化时我一般先跑uname -a确认内核再看 /etc/os-release 确认版本最后才决定用哪套方法论。磨刀不误砍柴工不要一个脚本走天下版本差异会让你死得很难看。另外RHEL 生态的替代方案 Rocky Linux 和 AlmaLinux 与 RHEL 二进制兼容很多 RHEL 的调优参数可以直接沿用。如果你不想订阅企业版同时又需要 RHEL 的稳定性这类兼容发行版是一个不错的实验环境。5. 线上故障排查与复盘实录5.1 最常见的三类问题定位故障排查是优化工作的逆向过程。很多时候你不知道系统哪里不对劲那就从最常出问题的三个方向下手。内存问题症状是业务变慢、时不时 OOM。先 free -h 看 available 而不是 free。Linux 会把空闲内存用作 page cacheavailable 才是真实可分配内存。再用cat /proc/meminfo看 CommitLimit 和 Committed_AS如果 Committed_AS 长期接近 CommitLimit说明内存超额分配严重考虑加内存或者限制进程。CPU 问题症状是 load average 高但 CPU 使用率不高。这种时候 vmstat 里的 r 列值得关注它表示处于可运行状态的进程数。如果 r 大于 CPU 核数说明有进程在排队如果 CPU 使用率低但 load 高大概率是 IO 等待用 iostat 看 %util 和 await 就能定位。网络问题症状是连接超时或者偶尔断开。先 ss -s 看连接状态汇总再看是否有大量 TIME_WAIT。TIME_WAIT 多不一定是坏事但服务端主动断开且短连接密集时会占用大量端口可以通过前面提到的 tcp_tw_reuse 和 tcp_fin_timeout 改善。5.2 一次典型卡死案例复盘讲一次我实际遇到的线上故障某台 RHEL 9.7 应用服务器频繁出现几分钟的“假死”业务侧反馈接口响应超时但 ping 还能通。我登录进去先看 uptimeload average 已经到 30但 CPU 使用率只有 20% 左右说明不是计算密集。然后再看vmstat 1 5r 列很低b 列却持续不为 0b 列表示阻塞在 IO 上的进程数这基本锁定了是磁盘 IO 问题。用 iostat -x 1 检查发现 %util 接近 100%await 超过 100 毫秒而 svctm 又和 await 差距巨大说明请求在等待队列里排队盘已经忙不过来了。进一步用iotop -o找到罪魁祸首是一个日志采集 agent 在不停刷日志写到根分区。根分区当时的剩余空间只剩 5%日志轮转配置又没生效导致 agent 写日志时反复触发了回收。把进程停掉清理旧日志调整 journald 日志上限和 logrotate 策略后load 逐渐回落服务恢复正常。复盘下来问题本质上不是 agent 写得多而是我把日志上限的配置放到了重启计划的最后一环结果它先爆了。优化配置之后这类问题还没有再出现过。5.3 排查工具与命令清单工具不在于多在于用得对。我常用的排查链路如下# 1. 看整体负载 uptime top # 2. 看 CPU 和 IO 维度的分割 vmstat 1 5 mpstat -P ALL 1 # 3. 看磁盘 iostat -x 1 iotop -o # 4. 看网络 ss -s ss -tunlp tcpdump -i eth0 port 8080 -n -c 50 # 5. 看进程调用 strace -p PID perf top注意 strace 和 perf 在生产环境要谨慎使用strace 会显著拖慢目标进程适合在做低峰期操作。排查任何一个系统问题遵循“先整体后局部先看指标再看进程最后再看调用细节”不要一上来就 gdb。6. 写在最后优化是习惯不是脚本库这套方法折腾下来我最大的体会是系统优化不是一个一劳永逸的脚本更不是把网上所有参数复制进 sysctl.conf 就完成任务。每一个参数背后都是一种取舍调整之前要清楚你的业务是吃内存、吃磁盘还是吃网络调整之后要做对比验证在没有监控数据支撑的情况下的优化都只是心理安慰。我个人在实践中养成的习惯是所有变更先备份能用 ansible 等配置管理工具做统一管理就不用手动改单机每次调整后记录变更原因和观察结果哪怕一行注释也算数新装一台系统先把 tuned 方案敲定再对遗留参数做微调而不是反过来。RHEL 9.7 也好其他 Linux 发行版也罢底层逻辑都是一样的理解机制比记住命令更重要。最后再分享一个可以长期坚持的小技巧每季度给关键服务器做一次dnf update --security和日志磁盘占用检查顺手用systemd-analyze blame看一下启动时间有没有劣化。很多大故障都是从小事情慢慢积累出来的提前二十秒发现问题可能就避免一次整体事故。希望这些经验能帮你少踩几个坑如果你有自己的优化心得也欢迎在评论区一起聊。
返回列表