先泼盆冷水:不存在“一键无损切换”的魔法。
CentOS 和 Ubuntu 虽然都是 Linux,但底层包管理器(RPM vs DEB)、系统初始化方式(SysVinit/Systemd 差异虽在缩小但配置习惯不同)、默认用户权限模型、甚至某些系统库的版本都有显著差异。所谓的“保留原有文件”,通常指的是业务数据、配置文件、代码仓库等应用层资产,而不是整个操作系统的根目录结构。
如果你是想从一台 CentOS 服务器迁移到新的 Ubuntu 服务器,或者重装系统后恢复数据,以下是经过生产环境验证的几种路径,按推荐程度排序:
方案一:云盘快照/镜像迁移(最稳妥,适合云服务器)
如果你使用的是阿里云、腾讯云、华为云等主流厂商的 ECS/CVM,这是成本最低且风险最小的方式。
- 制作 CentOS 自定义镜像:
- 在控制台对当前 CentOS 实例创建自定义镜像。这会包含系统盘的所有数据。
- 基于镜像创建新实例:
- 使用这个自定义镜像创建一个新的 Ubuntu 实例?注意:大多数云平台不允许直接用 CentOS 镜像启动 Ubuntu 内核,因为引导加载程序(GRUB)和内核模块不兼容。
- 正确做法:利用云平台的“跨平台迁移”或“异构迁移”服务(如阿里云的云迁移中心 CMS,腾讯云的 CVM 迁移工具)。这些工具会在后台进行格式转换和驱动适配。
- 如果平台不支持自动跨发行版迁移:
- 只能新建一个纯净的 Ubuntu 实例。
- 挂载旧的 CentOS 系统盘作为数据盘挂载到新 Ubuntu 上。
- 通过 SSHFS 或 rsync 将
/home,/var/www,/opt等业务目录拷贝出来。 - 卸载旧盘,完成迁移。
优点:零停机或短停机,数据一致性高。
缺点:需要云平台支持,技术门槛低。
方案二:rsync + 增量备份(经典运维手段)
这是最通用、最可控的方法,适用于任何场景(物理机、虚拟机、混合云)。
步骤详解:
-
准备目标 Ubuntu 服务器:
- 安装好基础环境,确保网络互通,SSH 可达。
- 创建用于接收数据的目录,例如
/backup_from_centos。
-
执行同步命令:
# 在 CentOS 源服务器上执行,或者直接在 Ubuntu 上用 ssh 拉取 # 推荐使用 rsync,因为它能处理断点续传、权限保留、符号链接等 rsync -avz --delete /home/ /var/www/ /etc/nginx/ /opt/myapp/ user@ubuntu_ip:/backup_from_centos/-a: 归档模式,保留权限、时间戳、软链接等。-v: 显示详细过程。-z: 压缩传输。--delete: 如果源端删除了文件,目标端也删除(谨慎使用,建议首次不加,后续加)。
-
关键注意事项:
- 不要同步
/etc/passwd,/etc/shadow,/etc/sudoers等系统用户文件!Ubuntu 的用户 UID/GID 分配可能不同,强行覆盖会导致权限混乱。 - 不要同步
/boot,/proc,/sys,/dev。这些是动态生成的或内核相关的。 - 重点同步:你的代码、数据库数据文件(需停库或逻辑导出)、Nginx/Apache 配置、Cron 任务脚本、SSH 密钥(
.ssh/id_rsa等)。
- 不要同步
-
处理权限问题:
- CentOS 和 Ubuntu 默认用户组名称可能不同(如
www-datavsapache)。 - 同步后,在 Ubuntu 上检查文件所有者:
chown -R www-data:www-data /var/www/html
- CentOS 和 Ubuntu 默认用户组名称可能不同(如
方案三:容器化迁移(Docker/Podman)—— 现代架构首选
如果你的应用已经容器化,那么“切换系统”几乎无感。
- 导出镜像:
docker save myapp:v1 > myapp.tar - 传输到 Ubuntu 服务器。
- 导入并运行:
docker load < myapp.tar docker run ... - 数据卷(Volumes):
- 如果使用了 Docker Volume,手动备份 volume 中的数据目录(通常是
/var/lib/docker/volumes/...或你指定的宿主机路径),然后在新 Ubuntu 上重新挂载。
- 如果使用了 Docker Volume,手动备份 volume 中的数据目录(通常是
优点:解耦了操作系统依赖,迁移速度快,环境一致性好。
缺点:前期需要将非容器化应用改造为容器化。
方案四:数据库专项迁移(MySQL/PostgreSQL)
数据库不能简单用 cp 复制文件,尤其是 InnoDB 引擎,直接复制可能导致损坏。
- 逻辑备份(推荐):
mysqldump -u root -p --all-databases > all_dbs.sql - 传输 SQL 文件到 Ubuntu。
- 在 Ubuntu 上安装 MySQL/PostgreSQL。
- 导入数据:
mysql -u root -p < all_dbs.sql
常见陷阱与避坑指南
-
Python 虚拟环境:
- CentOS 7 默认 Python 3.6+,Ubuntu 20.04/22.04 默认 Python 3.8/3.10。
- 不要直接复制
venv目录!不同 Python 版本和 OS 的编译扩展(如 numpy, psycopg2)不兼容。 - 正确做法:在 Ubuntu 上新建 venv,
pip install -r requirements.txt重新安装依赖。
-
PHP 扩展:
- CentOS 用
yum install php-mysql,Ubuntu 用apt install php-mysql。 - 配置文件路径不同:CentOS 在
/etc/php.d/或/etc/php.ini,Ubuntu 在/etc/php/7.4/apache2/conf.d/。 - 需要手动对照调整 PHP 配置。
- CentOS 用
-
Systemd 服务:
- CentOS 的服务文件通常在
/usr/lib/systemd/system/或/etc/systemd/system/。 - 复制到 Ubuntu 前,检查 ExecStart 路径是否正确,依赖项是否匹配。
- 建议在 Ubuntu 上重新编写 service 文件,而非直接复用。
- CentOS 的服务文件通常在
-
防火墙规则:
- CentOS 默认使用
firewalld,Ubuntu 默认使用ufw。 - 迁移后需要在 Ubuntu 上重新配置 ufw:
sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw enable
- CentOS 默认使用
-
SELinux vs AppArmor:
- CentOS 启用 SELinux,Ubuntu 启用 AppArmor。
- 迁移后,如果遇到“Permission Denied”错误,先临时关闭 AppArmor (
sudo systemctl stop apparmor) 测试是否是它拦截了访问,再逐步调整策略。
总结建议
- 如果是生产环境:务必先在测试环境完整演练一遍迁移流程。
- 数据先行:无论采用哪种方案,第一步永远是全量备份。
- 最小化迁移:只迁移业务数据和必要配置,系统级组件(如 Nginx、MySQL、Redis)建议在 Ubuntu 上全新安装,以保证稳定性和安全性。
- 灰度发布:迁移完成后,不要立即切断 DNS 或流量,观察日志至少 24-48 小时。
记住,Linux 迁移的本质是数据迁移 + 环境重建,而不是系统替换。保持冷静,分步执行,就能平稳过渡。
云技术博客