资讯动态

CentOS 7与Ubuntu 20.04双版本测试环境部署避坑手册

发布时间:2026/10/16 6:55:44 来源:尧图企业网站定制
两个发行版一套测试环境乍看像是自己给自己找麻烦。但做过兼容性验证的运维都知道客户线上跑什么系统测试环境就得跟着搭什么系统。客户那里还是 CentOS 7你本地清一色 Ubuntu功能在测试机跑得飞起到了对方现场说崩就崩连问题都复现不了。我这边测试机房里CentOS 7 和 Ubuntu 20.04 长期各占一半这套部署手册就是我在两套系统之间反复折腾之后沉淀下来的覆盖了从系统装完那一刻到软件源、常用服务、防火墙、安全模块、验收检查的完整流程每个环节都给了可以直接复制的命令和踩坑说明。适合运维工程师、测试开发、以及需要自己维护开发机和测试机的后端同学参考。1. 双版本并存的现实考量为什么测试环境比生产环境更“杂”1.1 两种发行版在测试环境里的角色分工很多新人会问测试环境随便用一个系统不就好了吗为什么要养两套答案是测试环境的职责决定了它必须“杂”。生产环境讲究统一、稳定能用一套标准配置解决问题就绝不引入第二个变量但测试环境的核心价值是最大程度模拟真实用户的运行条件。存量客户里面CentOS 7 这批老服务器数量仍然不少它们在正常跑业务不会因为你换了发行版就立刻升级。另一边开发人员自己搭的服务器、新项目的CI环境很多都跑在 Ubuntu 20.04 这类新一点的系统上。如果测试环境只服务其中一边那另一类问题就完全覆盖不到。我在这套环境上做的典型测试是同一个应用包分别在 CentOS 7 和 Ubuntu 20.04 上部署一遍验证安装脚本、依赖库、配置文件有没有写死系统路径再跑一遍核心功能回归。这个过程帮我挡掉过很多“只在某一种系统上能跑”的隐蔽问题。1.2 部署前的统一规划主机名、IP、账号与网络段两套系统命令不同、包管理不同但基础规划千万不要各干各的不然环境一多就乱。我这边用的是这套约定主机名采用test-centos-01、test-ubuntu-01这种带系统标识的格式一眼能看出机器用途。IP 段统一规划例如内网用192.168.10.0/24CentOS 机器用192.168.10.11起Ubuntu 机器用192.168.10.21起避免两边 IP 撞车。账号统一用deploy用户通过 sudo 提权不直接用 root 操作日常命令。关机、重启、服务启停都通过 systemd不用旧的service命令。为什么要单独建一个 deploy 用户而不是 root 一把梭因为测试环境经常要跑自动化脚本、定时任务、部署工具如果所有操作都以 root 身份进行脚本里一旦写下危险命令比如误删目录、权限写错代价就是整个环境报废。用普通用户加 sudo相当于给这些操作加了道闸口日志里也能看到是谁用 sudo 干了什么。分区规划上测试环境不需要像生产环境那样精细但建议至少把/和/data分开。/data挂独立分区后续装测试数据、日志、备份文件都放这里系统盘被日志打满时不会拖垮整台机器。1.3 镜像选择用最终版和 LTS别追新CentOS 7 选 7.9这是这个系列最后的版本Ubuntu 20.04 选 20.04.6也是该系列的最终维护版本。测试环境要的是可复现今天装完是这个版本半年后再装一批机器版本依然一致行为一致这才是测试的价值。追新版本对测试环境是负资产。安装镜像方面我建议用 minimal / server 最小化安装包不要在安装阶段勾选一堆图形组件后面需要的软件全部走软件源安装。这样既能缩短装机时间也方便沉淀成自动化交付流程。CentOS 7 的官方源已经进入 EOL 状态装完系统后第一件事就是把 yum 源调整到可用的镜像状态这个后面详细说。2. CentOS 7 初始化全流程yum 时代的部署习惯2.1 装完系统后的第一件事主机名和静态 IPCentOS 7 装完后默认走 DHCPIP 一变后面所有基于 IP 的配置都得跟着改所以我的习惯是第一步就改成静态地址。hostnamectl set-hostname test-centos-01网卡配置文件在/etc/sysconfig/network-scripts/ifcfg-接口名接口名可能是ens33、eth0取决于你的虚拟化平台和网卡命名规则。改完后长这样TYPEEthernet BOOTPROTOstatic IPADDR192.168.10.11 NETMASK255.255.255.0 GATEWAY192.168.10.1 DNS1192.168.10.2 ONBOOTyes然后重启网络服务systemctl restart network这里有个新手高频踩坑点ONBOOTno忘了改成yes导致机器重启后网卡直接不启动。另外 CentOS 7 的 NetworkManager 和 network 服务经常同时存在如果你发现改了配置文件但 IP 没生效可以看一下这个网卡是不是被 NetworkManager 接管了必要时用nmcli进行确认和调整。2.2 软件源与 epel包管理的第一步CentOS 7 的系统源现在处于 EOL 状态如果yum install报错说找不到 mirrorlist需要手动把 base 源切换到 vault 镜像。简单操作是把/etc/yum.repos.d/CentOS-Base.repo里的mirrorlist注释掉把baseurl指向 vault 地址然后执行yum clean all yum makecache装完基础源后第一时间安装 EPEL 源。EPEL 里提供了大量 base 源没有的实用工具比如htop、jq、tree这类小工具在排查问题时会频繁用到。直接yum install -y epel-release安装基础工具包yum install -y vim wget git lsof net-tools unzip zipnet-tools虽然老旧但里面包含ifconfig、netstat这些经典命令很多老运维习惯了netstat -tlnp看端口没装这个包会报 command not found。2.3 测试环境常见组件的 yum 安装方式测试环境通常需要 JDK、Nginx、MySQL/MariaDB、Redis 这几样。CentOS 7 默认源里的版本普遍偏老这反而是测试环境需要的——测试环境永远应该优先复刻客户现场版本而不是追逐新版本。OpenJDK 直接yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-develNginx 用源里自带版本即可yum install -y nginx systemctl enable --now nginxCentOS 7 源里的 MySQL 不是官方 MySQL而是 MariaDB 5.5版本比较老。如果被测应用依赖 MySQL 5.7 或 8.0需要手动装官方 RPM 包再安装。这里要给个提示装官方 RPM 包时记得确认它和当前系统架构匹配不要复制了错误版本。Redis 源里是 3.2比较老但胜在稳定。服务名是redisyum install -y redis systemctl enable --now redis2.4 systemd 开机自启与单元文件要点CentOS 7 的 systemd 版本偏老在它上面写单元文件有些新语法会被静默忽略。比如我在一个服务文件里写了MemoryHigh512MCentOS 7 不会报错但它也不会真正生效直到迁移到 Ubuntu 20.04 才意识到这个配置其实是可以工作的。一个规范的测试服务单元文件长这样[Unit] DescriptionTest App Service Afternetwork.target [Service] Userdeploy ExecStart/opt/app/bin/start.sh Restartalways RestartSec5 EnvironmentAPP_ENVtesting [Install] WantedBymulti-user.target写完放到/etc/systemd/system/下然后systemctl daemon-reload systemctl enable --now test-app.service注意ExecStart里的路径必须写成绝对路径且不要带~systemd 不会做变量展开。另外服务如果是脚本脚本里涉及环境变量时尽量在单元文件里用Environment显式声明不要指望登录用户的.bashrc能加载到 systemd 进程里。3. Ubuntu 20.04 初始化全流程apt 时代的部署习惯3.1 netplan 配置网络从 ifcfg 到 YAML 的思维切换Ubuntu 20.04 默认用 netplan 管理网络配置文件在/etc/netplan/下面常见文件名是00-installer-config.yaml。静态 IP 配置大概是这个样子network: version: 2 ethernets: ens160: dhcp4: no addresses: - 192.168.10.21/24 routes: - to: default via: 192.168.10.1 nameservers: addresses: - 192.168.10.2改完后应用sudo netplan apply这里有个非常实用的安全手段netplan try。它会先检测配置合法性应用后如果一段时间内没有确认自动回滚到上一份配置。我第一次改 Ubuntu 网络配置时直接用了apply缩进写错导致网卡全断只能跑去机器前面接显示器。后来一律用try再没出过这种事故。还有一点netplan 底层渲染器可能是networkd也可能是NetworkManager。如果这台机器之后要做复杂的网卡绑定或者 Docker 网络建议在部署时确认一下/etc/netplan/里的renderer字段后面排查网络问题时能少走弯路。3.2 apt 源与软件更新策略Ubuntu 20.04 的 apt 源配置文件在/etc/apt/sources.list。默认源在绝大多数场景下都可用如果内网有镜像源可以换成内网地址加速。完成系统更新sudo apt update sudo apt upgrade -y我的建议是刚装完系统时做一次全量升级让系统和软件包保持在同一批版本上之后就不需要频繁 upgrade测试环境最重要的是版本一致性频繁升级反而是麻烦来源。装基础工具sudo apt install -y vim wget git lsof net-tools unzip zipUbuntu 20.04 里的net-tools需要单独安装如果不装ifconfig和netstat都不存在需要习惯用ip addr和ss -tlnp。3.3 在 Ubuntu 上复刻同样的服务栈同等服务在 Ubuntu 上的安装命令和 CentOS 很不一样最直观的差异体现在包名上。# JDK sudo apt install -y openjdk-8-jdk-headless openjdk-11-jdk-headless # Nginx sudo apt install -y nginx sudo systemctl enable --now nginx # MySQL默认是 8.0 sudo apt install -y mysql-server sudo systemctl enable --now mysql # Redis sudo apt install -y redis-server sudo systemctl enable --now redis-server如果你需要的是 MariaDB就装mariadb-server服务名同样是mariadb。需要说明的是 Ubuntu 上安装 MySQL 后会默认监听本地 socket远程连接前要手动确认 bind-address 配置这个点和 CentOS 上装 MariaDB 的行为不太一样。另外 Nginx 的配置目录结构差异比较明显CentOS 7 的 nginx 默认会在/etc/nginx/conf.d/下加载所有.conf文件Ubuntu 上的 nginx 包则用/etc/nginx/sites-available/和/etc/nginx/sites-enabled/两套目录通过软链接激活站点。如果从 CentOS 迁移过来记得先看一下nginx.conf里到底 include 了哪个目录再决定配置文件放哪。3.4 与 CentOS 7 的全方位差异对照表对比项CentOS 7Ubuntu 20.04包管理器yumapt网络配置/etc/sysconfig/network-scripts/ifcfg-*/etc/netplan/*.yaml防火墙firewalldufw安全模块SELinuxAppArmorsudo 用户组wheelsudo默认 Python2.7python3 是 3.63.8Linux 内核3.105.4Nginx 配置目录/etc/nginx/conf.d//etc/nginx/sites-available/Redis 服务名redisredis-server这张表建议保存在备忘录里每次在两套系统间切换部署操作时先对着看一眼能避免大量低级错误。4. 双系统下最容易被坑的细节从安全模块到服务管理4.1 SELinux 与 AppArmor同样的“安全模块”不同的惩罚方式CentOS 7 默认启用 SELinux状态是 enforcing。这意味着如果一个服务进程想监听一个非常规端口或者想读取某个被标记的文件而策略没有放行它会被静默拦截。最典型的症状是服务状态显示 running端口就是听不到日志里也看不到明显报错。遇到这种情况先看审计日志ausearch -m avc -ts recent或者临时关掉 SELinux 验证是不是它在拦截setenforce 0如果关掉之后问题消失那就确认是 SELinux 策略问题需要针对性调整服务标签或端口策略而不是一路setenforce 0关到底。测试环境也一样建议保持 enforcing因为生产环境的 CentOS 通常是开着的测试环境关掉就意味着你永远测不到权限问题。Ubuntu 20.04 的 AppArmor 也在默默工作行为方式更偏向限制具体程序的 profile。用aa-status可以查看当前加载的策略。对于常规的 Web 服务和数据库服务AppArmor 的存在感通常比 SELinux 低但如果你改了 MySQL 的数据目录或者 Nginx 的 web 根目录一样可能被 AppArmor 拒在门外。4.2 firewalld 与 ufw防火墙命令的对应关系CentOS 7 默认用 firewalld放行端口语法是systemctl start firewalld firewall-cmd --permanent --add-port8080/tcp firewall-cmd --reloadUbuntu 20.04 默认装了 ufw但默认不启用。启用前先放行需要的端口否则 SSH 会断掉sudo ufw allow 22/tcp sudo ufw allow 8080/tcp sudo ufw enable这里要特别注意默认行为差异firewalld 在 CentOS 7 默认对公共区域的入站流量限制较严而 ufw 默认策略是允许出站、拒绝入站但未启用时等于没有防火墙。所以我在双版本部署中养成一个习惯不管是哪套系统装完服务后都顺手确认一遍防火墙状态用ss -tlnp确认端口在听再用firewall-cmd --list-all或ufw status verbose确认放行规则。4.3 systemd 版本差异和单元文件的细节坑CentOS 7 自带 systemd 219Ubuntu 20.04 自带 systemd 245两者差了六年的功能演进。这个差距在写单元文件时会直接暴露出来。CentOS 7 时代比较有限部分新指令不识别但不报错默默不生效Ubuntu 20.04 能支持更丰富的资源限制参数比如MemoryMax、TasksMax这类。合理的做法是写单元文件时只用两边都支持的基础指令特殊参数按系统分开管理。另外单元文件覆盖顺序也要知道/etc/systemd/system/下的同名文件会覆盖/lib/systemd/system/下的包默认文件。我在自定义服务参数时都会复制一份到/etc/systemd/system/里再修改而不是直接改包目录下的文件这样软件包升级时不会把我的自定义配置冲掉。4.4 用户、权限与 SSH 加固的常见不一致创建 deploy 用户时两边的命令细节不一样# CentOS 7 useradd -G wheel deploy # Ubuntu 20.04 useradd -m -s /bin/bash -G sudo deployCentOS 7 的 wheel 组默认有 sudo 权限Ubuntu 20.04 的 sudo 组对应同样的能力。但两个系统的 useradd 默认行为有差别稳妥的做法是显式加上-m -s /bin/bash确保家目录和 shell 都符合预期。SSH 加固方面两边都建议修改/etc/ssh/sshd_config关闭 root 密码登录、仅允许密钥登录。不同发行版对PermitRootLogin的默认值也不完全一样CentOS 7 默认是yesUbuntu 20.04 默认是prohibit-password所以这个文件一定要显式配置不要依赖默认值。5. 部署完成不等于结束验收清单与一键巡检思路5.1 手动验收十组命令看遍系统状态部署完一套环境我会按下面的顺序快速过一遍cat /etc/os-release # 确认系统版本防止连错机器 hostnamectl # 确认主机名 ip addr show # 确认 IP free -h # 确认内存 df -h / /data # 确认磁盘 nproc # 确认 CPU 核数 systemctl list-units --typeservice --staterunning | grep -E nginx|mysql|redis ss -tlnp # 确认关键端口 journalctl -p err -b # 看看本次开机有没有报错 yum check-update / apt list --upgradable前四项是最容易被忽略的多台机器连着跳板机经常出现想部署 CentOS 的机器结果 SSH 登到了 Ubuntu 上一通操作全部白费。先看系统版本再动手是测试环境部署的基本仪式感。5.2 自动化巡检脚本同一套脚本覆盖双版本双版本维护最大的痛点是命令不统一所以巡检脚本里需要先做发行版判断。一段最简版本的思路#!/bin/bash if grep -qi centos /etc/os-release; then echo System: CentOS firewall-cmd --list-all else echo System: Ubuntu sudo ufw status verbose fi echo --- Key ports --- ss -tlnp | grep -E :80|:3306|:6379|:8080 echo --- Running services --- systemctl list-units --typeservice --staterunning | grep -E nginx|mysql|redis echo --- Disk usage --- df -h / /data 2/dev/null把这个脚本放到每台机器的/usr/local/bin/healthcheck.sh加上可执行权限就能用一条命令快速巡检。核心逻辑就是按发行版分流公共部分统一用 systemd 和ss命令。5.3 时间同步、日志与后续更新策略测试环境的时间不同步会导致日志对不上、证书验证失败、数据库写入时间错乱。CentOS 7 默认用 chronysystemctl enable --now chronyd chronyc sources -vUbuntu 20.04 默认用 systemd-timesyncdtimedatectl set-ntp true timedatectl status日志查看统一用 journalctl两边行为基本一致。我习惯把关键服务的日志长期保留避免测试跑了几天之后想查历史记录却发现被轮转掉了这时就需要调整 journald 的保留策略。关于系统更新我的策略是装完机做一次全量更新然后锁定版本除非是为了验证某个具体缺陷否则测试环境不频繁升级。频繁变动的环境不是好的测试环境。6. 半年部署下来的踩坑记录与排查路线6.1 Python 版本差异引发的脚本兼容问题有一回把一套监控脚本从 Ubuntu 20.04 复制到 CentOS 7 上直接运行结果报了ModuleNotFoundError: No module named requests。检查才发现CentOS 7 默认python指向 Python 2.7yum install python-requests装的是 Python 2 版本而脚本用的是 Python 3 语法和依赖。Ubuntu 20.04 默认python3指向 3.8且没有提供python这个命令两边的默认行为完全错位。后来我在所有部署脚本里统一约定脚本第一行写死解释器路径要么/usr/bin/python3要么通过 virtualenv 锁定依赖绝不依赖系统默认python。同时把测试环境的基础镜像里都预装python3-pip避免后续还要现场补包。6.2 apt 的锁与依赖问题Ubuntu 上的隐藏事故Ubuntu 在执行 apt 安装时经常遇到Could not get lock /var/lib/dpkg/lock-frontend这个锁表示有另一个 apt 或 dpkg 进程在运行。可能是后台 unattended-upgrades 在自动更新也可能是之前某个 apt 命令被中断没有释放锁。正确做法是先看进程ps aux | grep -E apt|dpkg lsof /var/lib/dpkg/lock-frontend确认确实没有 apt 进程残留再移除 stale lock 文件。我见过有人看都不看直接rm -rf /var/lib/dpkg/lock*然后整个 dpkg 数据库出问题。这个要特别提醒锁文件不是不能删但必须先确认没有相关进程持有它。6.3 修改 netplan 导致的“掉网”事故改造一台 Ubuntu 测试机时我把00-installer-config.yaml里的缩进写错了然后直接执行sudo netplan apply网络立即断掉SSH 连接卡死最后只能通过管理台进系统改回来。后来我在部署手册里加了硬性规定任何 netplan 改动必须先用sudo netplan try验证确认网络正常后按回车确认再执行apply或者干脆不执行apply。CentOS 7 那边也有类似事故修改ifcfg-ens33时把UUID行删掉了导致重启后网络服务起不来。原因是配置文件和 NetworkManager 记录的设备标识对不上。这类坑的共同点都是“以为只改了一个字段实际上破坏了系统用于识别设备的元数据”。6.4 排查方法论用差异对照表缩小变量范围双版本环境里遇到“这台机器有问题那台机器没问题”的情况我最常用也最有效的排查思路是先把两边除了发行版之外的所有差异拉出来逐个排除。比如服务起不来先看服务状态是不是都在运行然后看端口是不是都在监听再看防火墙有没有放行再看安全模块有没有拦截最后看文件权限和用户是否一致。大部分时候问题出在“某个你以为一样、其实不一样”的默认配置上比如 CentOS 7 的redis服务名和 Ubuntu 的redis-server服务名、firewalld 和 ufw 的默认策略差异。每次出现新的诡异问题我都会把原因补进上面的差异对照表里这张表就是双版本维护最重要的资产。最后一件事跑完这套部署流程我的感受是双版本部署的难点从来不在某个单独的命令而在于那些“默认不一样”的角落。只要每次部署都把发行版差异当作独立变量来对待复杂的双环境维护完全可以做到有条不紊。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑