
很多人第一次被问到 CentOS 和 RedHat 的关系都是在比较尴尬的场合要么是面试官随口一问要么是项目交接时发现对面的老哥把两者混着用要么是自己面对一台写着 Red Hat Enterprise Linux 的机器照着 CentOS 的教程敲命令敲完 yum 直接报没有权限。更麻烦的是CentOS 7 在 2024 年 6 月走到生命周期终点之后CentOS Linux 8 早就提前收摊CentOS Stream 变成了另一条路线很多人的知识体系还停留在CentOS 就是免费的 RedHat这一句话上。这篇东西不讲历史课本我从实际运维和迁移的角度把两者的血缘、版本对应、包管理差异、日常命令的分叉点以及一堆反复出现的坑一次性摊开讲清楚。不管你是刚在 VMware 里装上 CentOS 7 的新手还是正在给公司做 RHEL 订阅合规和系统迁移的老手都能从里面找到能直接抄走的东西。1. 搞清血缘谁是上游谁是下游先把最容易搞混的一句话摆正Red Hat Enterprise Linux下文简称 RHEL是商业发行版传统意义上的 CentOS Linux 是它的下游复刻版而 2021 年之后的 CentOS Stream 反过来变成了 RHEL 的上游。这三者的顺序在不同年代是反的这是所有混乱的源头。1.1 RHEL 的源码是怎么出来的Red Hat 的开发链路大致是 Fedora → RHEL。Fedora 是节奏快、尝鲜性质的社区版本每半年一个版本RHEL 从 Fedora 里挑出一个时间点做分支然后进入长达十年的维护。RHEL 本身是商业产品但它的绝大多数组件是 GPL 等开源协议覆盖的协议要求它必须把对应源码放出来。Red Hat 走的是 SRPM源码 RPM这条路把这些源码包放在客户门户里供持有订阅的用户获取。这里有个实操层面的关键点SRPM 不等于二进制 RPM。SRPM 是配方加原料包含 spec 文件、补丁、原始 tarball二进制 RPM 是做好的菜。CentOS 当年干的事情就是把 SRPM 拿回来去掉 Red Hat 的商标和品牌资源改掉 release 包然后重新编译一遍产出自己的二进制包。所以早期 CentOS 和对应版本的 RHEL 在二进制层面是高度一致的用户态的程序几乎可以互换。1.2 传统 CentOS 的重建模式好处和代价重建模式带来的好处非常直观也就是 CentOS 当年能火起来的原因包管理方式一模一样命令一模一样配置文件路径一模一样RHEL 的文档和书可以直接拿来用。你在 RHEL 7 上学的 systemctl、firewalld、nmcli在 CentOS 7 上原样可用。代价也很明显。第一是时间差RHEL 出补丁CentOS 要等人家把源码放出来、再走一遍重建流程紧急安全补丁通常慢几天到几周第二是没有官方支持出问题只能靠社区和自己第三是品牌资源被剥离后一些依赖 Red Hat 认证的组件比如某些认证插件、订阅相关的工具链天生就没有。理解了这一点你就能明白为什么很多企业明知道 CentOS 免费还是咬牙买订阅——买的是响应时间和责任主体不是那几个 RPM。1.3 角色反转CentOS Linux 和 CentOS Stream 是两码事2020 年底的那次路线调整是很多人知识断层的分界线。简单说CentOS Linux老模式RHEL 的下游复刻有明确的版本号7、8有明确的生命周期。7 撑到了 2024 年 6 月8 提前在 2021 年底结束。CentOS Stream新模式RHEL 的上游滚动开发分支。它比 RHEL 早一步拿到变更相当于 RHEL 下一个次版本的预演场。Stream 9、Stream 10 都是滚动更新的没有传统意义上的小版本号。这个反转带来的实际影响是Stream 上的包可能比对应的 RHEL 版本新也可能在某些细节上不一致因为它是正在开发中的状态而不是已经冻结验收完的状态。拿它当生产环境的铁板一块来用需要你自己做验证不能指望有一份和 RHEL 完全二进制对齐的保证。2. 版本号、生命周期与订阅那点事搞清楚血缘之后第二个高频问题是我这台 CentOS 7 相当于 RHEL 几还能用多久版本号对应关系比较好办生命周期和授权才是真正会让人踩坑的地方。2.1 版本号为什么能一一对上传统 CentOS 的版本号是直接跟着 RHEL 走的CentOS 7.9 对应 RHEL 7.9CentOS 8.5 对应 RHEL 8.5。这不是巧合是重建模式的必然结果——源码版本号一致产物版本号自然一致。所以你在 CentOS 7.6 上查到的内核版本、glibc 版本、systemd 版本基本可以拿去对照 RHEL 7.6 的文档。一个能快速自查的小方法在任意一台机器上执行下面这几条就能拿到判断依据cat /etc/redhat-release # CentOS 上会显示 CentOS Linux release 7.9.2009 (Core) cat /etc/os-release # 更通用的方式能看出 ID 是 centos 还是 rhel uname -r # 内核版本注意 CentOS 的内核字符串里没有 RHEL 的构建后缀 rpm -q centos-release # CentOS 上拿到的是 centos-releaseRHEL 上是 redhat-release最后一条特别有用。很多脚本判断发行版就是靠rpm -q --whatprovides /etc/redhat-releaseCentOS 和 RHEL 返回的包名不一样写脚本做兼容时要留意。2.2 生命周期对照表下面这张表是我自己在做迁移规划时常用的对照注意 CentOS Linux 8 那一行是个例外它没有走完 RHEL 8 的完整周期。产品线发布生命周期终点需要留意的地方RHEL 7 / CentOS 72014 年 6 月2024 年 6 月 30 日两者基本同步结束CentOS 7.9 是最后一个版本RHEL 82019 年 5 月2029 年 5 月CentOS Linux 8 已于 2021 年 12 月 31 日提前终止RHEL 92022 年 5 月2032 年 5 月对应的是 CentOS Stream 9滚动更新RHEL 102025 年2035 年对应 CentOS Stream 10RHEL 的十年周期通常拆成完整支持和维护支持两个阶段后半段基本只收安全补丁和严重问题修复不再加新功能和新硬件支持。做硬件升级规划时这个分界线比 EOL 日期更值得关注——你可能还在周期内但新买的网卡和阵列卡已经不在支持列表里了。2.3 授权和订阅能装上不等于能合规用CentOS 不讲授权装多少台都行。RHEL 讲。RHEL 的订阅机制是通过subscription-manager注册到 Red Hat 的 CDN注册之后才会给你仓库的访问凭证放在/etc/pki/entitlement/下面。没注册的 RHELyum repolist会告诉你仓库是空的或者全部 disabled这时候很多人会以为是网络问题其实是没订阅。判断当前机器状态最快的三条命令subscription-manager status # 看整体订阅状态 subscription-manager repos # 看有哪些可用仓库、哪些启用 yum repolist all # 看仓库实际生效情况反过来说CentOS 的仓库地址是公共镜像站走的是mirror或者vault不需要任何凭证。这就是为什么同一份yum install教程在 CentOS 上一把过在 RHEL 上可能第一步就卡住。写自动化脚本或者做镜像时这一步必须分开处理。3. 仓库与包管理差异最集中的地带RHEL 和 CentOS 的差异百分之八十都体现在仓库和包这一层。命令语法几乎一样yum/dnf 是同一套但仓库从哪来、包里装了什么差别不小。3.1 仓库地址与订阅机制的分叉CentOS 7 及以前/etc/yum.repos.d/下是CentOS-Base.repo指向公共镜像。CentOS 8 和 Stream 时代换成了 dnf文件结构类似但内容指向不同域名。RHEL 上则是redhat.repo这个文件是被subscription-manager动态生成的你手动改它会被覆盖想加仓库要用subscription-manager repos --enablexxx或者干脆自己新写一个.repo文件。老版本的情况更复杂一点。RHEL 6.5 那个年代早期用的是 RHN Classic 那套体系后来切到 subscription-manager。现在再想把一台 RHEL 6.5 跑起来装包最省事的做法是挂 ISO 做本地仓库别指望连官方源了mount -o loop /path/to/rhel-server-6.5-x86_64-dvd.iso /mnt cat /etc/yum.repos.d/local.repo EOF [local] namelocal-iso baseurlfile:///mnt enabled1 gpgcheck0 EOF yum clean all yum makecache同样的套路对 CentOS 7.9 也成立尤其是内网离线环境把 ISO 挂上去做本地源比一个个 rpm 手动装靠谱得多。3.2 包名和版本字符串的差别前面提到的centos-release和redhat-release只是最表层的一处。再往下看内核版本字符串CentOS 的内核不会带 RHEL 的构建后缀某些依赖内核字符串做判断的第三方驱动安装脚本会因此报错。品牌相关包logos、indexhtml、release notes 这类包在两边的名字和内容都不一样。/etc/issue、/etc/motd很多合规检查脚本会读这里两边内容天然不同。真正需要注意的是内核 ABI。传统 CentOS 和 RHEL 在同一个小版本上内核 ABI 是一致的所以第三方内核模块比如某些存储驱动、安全模块编译一次两边都能用。但跨小版本就不保证了这也是为什么生产环境升级内核前一定要先看变更说明。3.3 商业组件的有无RHEL 订阅里包含一些 CentOS 没有的东西实际会用到的主要有这几类组件作用CentOS 上的替代方案Insights 客户端主动收集系统信息做风险提示基本没有等价的只能靠自建监控官方认证的硬件驱动经过厂商联合验证自行编译风险自担高可用与集群套件官方支持的 HA 方案走社区版组件问题自解安全合规内容包用于基线扫描社区有部分开源规则可参考所以如果你在做等保、金融行业合规这类工作选型时把这一块算进去不然临到检查才发现少东西返工成本很高。4. 日常运维命令哪些完全一样哪些会翻车命令层面我的经验是这样系统管理的基础操作九成以上相通翻车集中在仓库、订阅、网络配置格式、SELinux 策略这四个点上。下面按常用场景拆开说。4.1 网卡与 IP 配置从 ifcfg 到 keyfileCentOS 7 和 RHEL 7 都用 NetworkManager 管网络配置文件在/etc/sysconfig/network-scripts/ifcfg-xxx。CentOS 7.6 那种老机器上查看网卡最常用的还是这几条ip addr show # 首选net-tools 不装也能用 nmcli device status # 看设备状态和连接名 lspci | grep -i ethernet # 看物理网卡型号注意 minimal 安装的 CentOS 默认不带net-toolsifconfig和netstat直接是 command not found要么装包要么改用ip和ss。这个坑几乎每个新手都踩过。到了 RHEL 9 / CentOS Stream 9 以后NetworkManager 的配置格式换成了 keyfile路径变成/etc/NetworkManager/system-connections/老式的 ifcfg 虽然还能读但新写建议直接用 nmclinmcli con mod ens160 ipv4.addresses 192.168.1.50/24 nmcli con mod ens160 ipv4.gateway 192.168.1.1 nmcli con mod ens160 ipv4.dns 223.5.5.5 114.114.114.114 nmcli con mod ens160 ipv4.method manual nmcli con up ens160CentOS Stream 10 固定 IP 也是这套。写错网关或者掩码症状就是能 ping 通同网段但出不了门别急着怀疑系统先把ip route看一眼。查看某个进程占了哪些端口和连接用ss -tunap或者lsof -i -P -n都比老netstat快ss在两边系统里都是标配。4.2 防火墙放行firewalld 是共同语言RHEL 7 和 CentOS 7 开始默认都是 firewalld命令完全一致firewall-cmd --add-port8080/tcp --permanent firewall-cmd --reload firewall-cmd --list-all对应的配置文件在/etc/firewalld/zones/public.xml如果做批量部署直接推这个文件比逐台敲命令高效。要注意的是--permanent不加的话重启就丢这个错我见过太多次。还有一个高频现象服务本机curl 127.0.0.1通外部连不上。拿 redis 举例你redis-cli登录进去发现一切正常但另一台机器连不上八成是bind 127.0.0.1只监听了本地或者protected-mode yes挡着再或者防火墙没放 6379。这三步依次排查基本能定位。4.3 日志与服务管理RHEL 7 和 CentOS 7 之后都是 systemd日志走 journaldjournalctl -u nginx -n 100 --no-pager # 看某个服务的近期日志 journalctl --since 1 hour ago -p err # 看一小时内错误级别日志 tail -f /var/log/messages # 传统文本日志两边都在 tail -f /var/log/secure # 登录、sudo、ssh 相关 dmesg -T | tail -50 # 内核环缓冲带时间戳RHEL 6.5 那种老系统没有 systemd日志就是纯文本服务管理用service xxx start和chkconfig重启用shutdown -r now。到了 systemd 时代重启统一是systemctl reboot或者shutdown -r now两条命令在 RHEL 和 CentOS 上都一样。做维护窗口时尽量用shutdown -r 5 维护重启这种带通知的方式比reboot体面得多。4.4 用户、口令与远程端口单用户模式重置 root 口令这套操作两边完全一样开机在 GRUB 菜单按e在 kernel 行尾加rd.breakCentOS 7 / RHEL 7 及以后或者single更老的系统然后mount -o remount,rw /sysroot、chroot /sysroot、passwd root最后一定要执行touch /.autorelabel否则 SELinux 上下文不对重启后可能进不了系统。这个touch是新手最容易漏的一步。改 SSH 远程端口这件事光改/etc/ssh/sshd_config里的Port是不够的。SELinux 开着的话还得给新端口打标签semanage port -a -t ssh_port_t -p tcp 2222 firewall-cmd --add-port2222/tcp --permanent firewall-cmd --reload顺序上建议先把新端口开好、验证能连上再关旧端口不然你就得去机房了。这套流程在 RHEL 和 CentOS 上没有区别。5. 磁盘、离线装包、容器实操重灾区这一块是我被问得最多的也是 CentOS 和 RHEL 差异体现得最不明显、但坑最多的地方。因为命令一样反而容易让人忽略环境差异。5.1 磁盘扩容和 LV 空间挪移虚拟机磁盘扩容的标准链路是这样先在虚拟化平台把磁盘调大进系统后扩分区、扩 PV、扩 LV、扩文件系统。lsblk # 确认新容量已经识别 growpart /dev/sda 3 # 扩展分区CentOS 7 需装 cloud-utils-growpart pvresize /dev/sda3 lvextend -l 100%FREE /dev/mapper/centos-root xfs_growfs / # XFS 用这个ext4 用 resize2fscentos-root这个名字是 CentOS 默认的 VG 名RHEL 默认也叫这个所以两边通用。如果你的盘是 ext4最后一步换成resize2fs /dev/mapper/centos-root。搞混了会报错但不会损坏数据重跑一次就行。把 /home 的空间挪给根分区是个经典需求尤其是根分区快满、/home 却空着一大半的机器。步骤是先确认 /home 没有正在使用的进程umount /home然后lvreduce -L -50G /dev/mapper/centos-home如果要缩文件系统加-r让它一起处理但 XFS不支持缩小只有 ext4 可以。XFS 的情况下只能备份数据、删掉 LV、重建、再恢复。这一点非常关键很多人上来就lvreduce结果把 XFS 搞崩了。顺手说个排查磁盘占用的组合拳找大文件用find / -xdev -type f -size 10M -exec ls -lh {} \; 2/dev/null | sort -k5 -h | tail -20比du一层层翻快得多。挂载新盘时记得改/etc/fstab并且先mount -a验证一遍写错 UUID 就等着下次开机进应急模式吧。5.2 离线装包gcc、nodejs、maven 的通用套路内网环境装东西有个万能思路能挂 ISO 就别手动 rpm。因为离线装 gcc 这类编译器依赖链能拉出几十个包手动装到崩溃。# 挂载 ISO 做本地源RHEL 和 CentOS 通用 mount -o loop /path/to/dvd.iso /mnt cat /etc/yum.repos.d/local.repo EOF [local] namelocal baseurlfile:///mnt enabled1 gpgcheck0 EOF yum clean all yum makecache yum install -y gcc gcc-c make如果实在没有完整 ISO只有零散 rpm那就在一台能联网的同版本机器上用yumdownloader把依赖一起拉下来再传到内网yumdownloader --resolve --destdir/tmp/pkgs gcc # 内网机器上 yum localinstall -y /tmp/pkgs/*.rpmNode.js 的离线安装更简单直接下官方二进制压缩包解压即可不走系统包管理器也就没有依赖问题tar -xf node-v20.x-linux-x64.tar.xz -C /usr/local/ ln -s /usr/local/node-v20.x-linux-x64/bin/node /usr/bin/node ln -s /usr/local/node-v20.x-linux-x64/bin/npm /usr/bin/npmMaven 的离线要分两层Maven 本身解压即用麻烦的是依赖。做法是在有网机器上mvn dependency:go-offline把依赖拉全然后把整个本地仓库目录默认~/.maven_repo打包带走在离线机器的settings.xml里把localRepository指向这个目录。经验是go-offline经常抓不全尤其是插件依赖所以最好的办法是先在联网环境完整跑一次mvn package把仓库打满再整体搬过去。CentOS 上还有一个高频疑问系统自带的 python 和 rpm 的关系。记住一条就够——别动系统自带的 python。CentOS 7 的 yum 是 python2 写的CentOS 8 以后 yum/dnf 依赖python3系统包你手工升级或替换/usr/bin/pythonyum 立刻罢工。要装新版本就用虚拟环境或者独立目录别碰系统解释器。5.3 Docker 与 Web 应用部署RHEL 7.5 那批机器部署 Docker和 CentOS 7 完全一样装yum-utils加仓库yum install docker-ce然后systemctl enable --now docker。镜像源慢的话改/etc/docker/daemon.json{ registry-mirrors: [https://your-mirror.example.com], log-driver: json-file, log-opts: { max-size: 50m, max-file: 3 } }顺手把日志限制加上不然跑几个月的容器能把磁盘吃满。跑一个 Web 应用的最小闭环docker run -d --name web -p 8080:80 --restartalways nginx--restartalways别忘了不然宿主重启后容器不会自己起来这是部署后最常见的上线第二天打不开的原因。Nginx 如果用二进制包部署步骤是解压、./configure、make、make install然后自己写 systemd unit。这里有个 SELinux 的坑Nginx 反向代理后端时会被 SELinux 拦住需要setsebool -P httpd_can_network_connect 1。用 yum 装的 Nginx 也一样会遇到跟发行版无关。5.4 Samba、面板工具这类周边Samba 配置在 RHEL 和 CentOS 上完全一致/etc/samba/smb.conf写共享段smbpasswd -a user加账号然后放行 137/138/139/445。唯一的差别还是 SELinux共享目录必须先打上下文semanage fcontext -a -t samba_share_t /data/share(/.*)? restorecon -Rv /data/share宝塔这类面板在 CentOS 上装得多一些因为社区教程多、脚本适配久。但要注意面板会自动改防火墙、改系统服务、装一堆自编译组件跟你后面自己配的 Nginx、MySQL 很容易打架。我的建议是面板只用在测试机和小型内部服务上正式环境还是老老实实手工装出了问题你能说清楚是哪一层。6. 几个反复出现的故障链路下面这几个问题我在不同公司、不同团队里见过至少五次以上几乎是 CentOS/RHEL 使用者的共同记忆。关键在于排查思路而不是背答案。6.1 卡在 starting dracut initqueue hook开机卡在这一行症状是等很久最后掉进 dracut 应急 shell或者直接超时。根因基本集中在内核找不到根设备这一类。排查按这个顺序走看 fstab。在 dracut shell 里执行cat /etc/fstab比对里面的 UUID 和blkid的输出。最常见的场景是虚拟机克隆之后磁盘 UUID 变了fstab 还指着老 UUID。看根设备是否被识别。ls /dev/mapper/、cat /proc/cmdline确认root指向的设备存在。看是不是内核和模块不匹配。升级内核后 initramfs 没重建或者虚拟化平台换了磁盘控制器类型比如从 IDE 换成 SCSI驱动没进 initramfs。修复方式通常是进救援模式把 fstab 改对或者用dracut -f重建 initramfs。想看得更清楚可以在启动参数里临时加rd.debug和rd.shell它会告诉你到底卡在等哪个设备。这个技巧比反复重启有效得多。6.2 虚拟机 NAT 模式上不了网、ping 不通网关VMware 里装 CentOS 7NAT 模式是最常用的也是最容易没网的。按这个顺序查宿主机服务是否在跑Windows 上打开服务列表确认 VMware NAT Service 和 DHCP Service 是启动状态这两个服务被安全软件干掉的情况非常常见。虚拟机网络编辑器看 NAT 网段比如 192.168.x.0/24和虚拟机里配的 IP 是否同网段网关是不是.2结尾那个地址。虚拟机内部ip addr看有没有拿到地址ip route看默认路由在不在。CentOS minimal 装完经常ONBOOTno网卡压根没起来改/etc/sysconfig/network-scripts/ifcfg-ens33里的ONBOOTyes然后systemctl restart network。检查 ICMP 是否被禁sysctl net.ipv4.icmp_echo_ignore_all返回 1 的话 ping 不通但网络其实是好的别被误导。如果同网段能通、网关 ping 不通先确认网关地址有没有写错。虚拟化环境下网关通常不是.1这个反直觉的点坑过很多人。6.3 从 CentOS 7.9 迁移到新系统时最容易忽略的事老系统迁新系统技术上的坑反而好解决真正麻烦的是这三件事第三方仓库。CentOS 7 时代大家习惯装 EPEL、remi、nginx 官方源这些。迁到 RHEL 或 Stream 之后这些仓库的地址、GPG key、包名可能有变化得逐个重新确认。老版本比如 RHEL 5、6 那批的资源现在基本都在归档站点里能找到但不会再更新。自编译组件。凡是当年make install装的东西自编译的 Nginx、Python、OpenSSL新系统上全部要重新评估因为系统库版本变了老的二进制大概率跑不起来。SELinux 策略和防火墙规则的沉淀。跑了几年的机器上往往有一堆当年为了先让它跑起来而临时加的放行规则没人记得为什么加。迁移时正是清理的好机会但前提是你得先把它们捞出来看一遍firewall-cmd --list-all和semanage fcontext -l是起点。6.4 SSH 大版本升级的保守做法CentOS 7.9 上升级 OpenSSH 到很新的版本这个需求在合规检查里很常见因为 CentOS 7 自带的 OpenSSH 版本太老。我的做法永远是另起一个端口不碰原来的# 编译前先备份配置 cp -a /etc/ssh /etc/ssh.bak.$(date %F) ./configure --prefix/usr/local/openssh --sysconfdir/etc/ssh --with-pam ... make make install # 新 sshd 先跑在 2222 端口 /usr/local/openssh/sbin/sshd -p 2222 -f /etc/ssh/sshd_config.new验证 2222 能正常登录并且要用新账号体系验证一遍 PAM 认证确认无误再考虑换默认端口。整个过程最重要的一条纪律不要在 SSH 会话里直接重启 sshd一旦配置有问题你就失去了唯一的入口。所有验证都通过新端口做确认好了再动老服务。7. 选型什么时候选 RHEL什么时候走 Stream聊完技术细节回到最实际的问题新项目到底该选哪个。我的判断标准比较简单按谁来兜底来分。如果你所在的组织有合规要求、需要有人对操作系统层面的安全事件负责、需要硬件厂商的联合认证那就买 RHEL 订阅。别只算软件的钱订阅买的是响应链路和责任人出事故时能有人陪你一起查这个价值在很多场景下比授权费高得多。如果只是内部测试环境、学习环境、边缘小服务CentOS Stream 完全够用而且它比老 CentOS 更贴近 RHEL 的演进方向。但要接受一个事实它没有固定小版本滚动更新意味着你得自己做验证不能像以前那样装完 7.9 就锁死三年不动。如果团队没有这个验证能力那不如考虑那些承诺长期支持的社区发行版。还有一个折中路线是用 RHEL 的二进制但不买订阅的各种下游重建版本各有各的维护节奏和社区背景选之前看清楚它的生命周期承诺和更新节奏别只看和 RHEL 兼容这句宣传语。我自己踩过最深的坑是早年在一个项目里把 CentOS 和 RHEL 当成完全等价来写自动化脚本结果脚本里判断发行版的逻辑在 RHEL 上直接失效因为centos-release包不存在。后来养成了一个习惯任何判断发行版的代码一律只读/etc/os-release里的ID和VERSION_ID字段不去猜包名、不去猜文件路径。这个习惯到现在为止在 RHEL、CentOS、Stream 以及各种衍生版本上都没翻过车。另一个习惯是给任何一台新机器做完基础配置之后立刻把uname -a、rpm -qa | sort、ip addr、firewall-cmd --list-all四条命令的输出存档一份等哪天机器出问题或者要做迁移时这份档案能帮你省掉大量追溯时间。