
1. 为什么还要折腾系统镜像制作这件事手里管着几十台服务器的人迟早会碰到一个绕不开的坎系统环境要统一。今天这台机器上少了个库明天那台机器的内核版本又不一样后天某台机器被人误删了关键配置。一台一台去修修到怀疑人生。更别提有些机器跑在没法直接接触的地方出了问题只能远程敲命令敲错一个字符就是灾难。我最早接触系统镜像制作是因为一个批量部署的需求。当时手头有一批配置几乎一样的机器要求系统环境完全一致包括内核参数、依赖库、服务配置、甚至时区。手动装一台机器大概要四十分钟装完还要逐项核对配置一天下来最多搞定五六台。后来我想能不能把一台已经调好的系统直接“克隆”成安装镜像以后新机器直接用这个镜像装装完就是成品。这个思路就是系统镜像制作的核心逻辑。在 CentOS 7 环境下有一套比较成熟的工具链可以完成这件事其中 Mondo Rescue 是我用得比较顺手的一个。它能把当前运行中的系统打包成一个可启动的 ISO 镜像支持裸机恢复和批量部署。这篇文章就围绕这个工具把整个制作流程、参数选择、踩坑经验完整梳理一遍。适合读这篇文章的人有 Linux 基础运维经验需要批量部署或系统备份恢复方案手头有 CentOS 7 环境愿意花时间做一次镜像以后省下无数次重复劳动。如果你只是偶尔装一台机器玩那手动装可能更快没必要上这套流程。2. 整体方案设计与工具选型思路2.1 为什么选 Mondo Rescue 而不是其他方案系统镜像制作有好几条路可以走。一条是用 Kickstart 做自动化安装本质是写一个应答文件让安装程序自动完成分区、装包、跑脚本。另一条是用容器技术把应用打包但容器解决的是应用层的问题不解决操作系统层的一致性。还有一条就是直接对系统做快照或克隆Mondo Rescue 属于这一类。Kickstart 的优势是干净、标准化装出来的系统没有历史包袱。但它有个前提你得把所有的配置项都写成脚本而且脚本要能覆盖所有场景。实际操作中很多配置是“手调出来的”比如某个服务的参数优化、某个内核模块的加载顺序、某个目录的权限设置这些东西写成脚本很繁琐而且容易漏。Mondo Rescue 的思路不一样它直接把当前系统的状态“拍”下来包括所有已安装的包、配置文件、甚至用户数据打包成 ISO。装出来的系统和你当前这台机器一模一样省去了“把配置翻译成脚本”这一步。我选 Mondo Rescue 的另一个原因是它对裸机恢复的支持比较完整。它生成的 ISO 可以直接启动进入一个恢复环境然后把系统恢复到硬盘上。整个过程不需要网络不需要额外工具一张光盘或一个 U 盘就能搞定。对于没有网络环境或者网络不稳定的场景这一点很关键。当然Mondo Rescue 也不是没有缺点。它打包出来的 ISO 体积比较大因为它把整个系统的文件都塞进去了。另外它对硬件变化的容忍度有限如果目标机器的硬盘控制器类型和源机器差别太大恢复后可能起不来。这些问题在后面会详细说。2.2 镜像制作的整体流程拆解整个流程可以分成四个阶段环境准备、系统清理与配置、镜像打包、验证与恢复。环境准备阶段要做的事情包括确认源系统状态、安装 Mondo Rescue 及其依赖、准备足够的磁盘空间。这个阶段最容易被忽视但恰恰是最容易出问题的地方。比如磁盘空间不够打包到一半失败前功尽弃。系统清理与配置阶段是决定镜像质量的关键。你要把源系统里不需要的东西删掉比如临时文件、日志、缓存、测试数据。同时要确认关键配置已经就位比如网络配置、时区、语言、服务启动项。这个阶段的目标是让源系统处于一个“干净且完整”的状态。镜像打包阶段就是运行 Mondo Rescue指定输出路径和格式等待它完成。这个过程可能需要几十分钟到几个小时取决于系统大小和磁盘速度。验证与恢复阶段是很多人会跳过的一步但我觉得这一步不能省。你至少要用生成的 ISO 启动一次走一遍恢复流程确认恢复出来的系统能正常启动、网络能通、关键服务能跑。不然等到真正需要恢复的时候才发现问题那就晚了。2.3 方案选型中的几个关键取舍第一个取舍是打包整个系统还是只打包系统盘。如果机器上有数据盘而且数据盘很大打包整个系统会让 ISO 体积爆炸。我的做法是只打包系统盘数据盘在恢复后单独挂载。这样 ISO 体积可控恢复也快。第二个取舍是是否包含用户数据。如果镜像只用于系统部署不包含用户数据那可以在打包前把/home和/data之类的目录清空。如果镜像要用于完整恢复那就得包含。这个取决于你的使用场景。第三个取舍是ISO 的输出方式。Mondo Rescue 支持输出到本地目录、输出到 ISO 文件、输出到磁带、输出到网络位置。我一般选择输出到本地目录然后再手动制作成 ISO 文件。这样中间产物可以保留方便排查问题。第四个取舍是是否启用压缩。Mondo Rescue 支持多种压缩算法压缩率越高打包时间越长但 ISO 体积越小。如果磁盘空间紧张可以选择高压缩率如果时间紧张可以选择低压缩率或不压缩。3. 核心细节解析与实操要点3.1 源系统的状态确认与清理在开始打包之前先确认源系统的状态。运行df -h看磁盘使用情况确保根分区有足够的剩余空间。Mondo Rescue 在打包过程中会在本地生成临时文件如果空间不够会直接失败。一般来说剩余空间至少要等于已用空间的一半。然后检查已安装的包列表。运行rpm -qa | wc -l看看有多少个包。包越多打包时间越长。如果有一些明显不需要的包比如开发工具、测试工具、文档包可以提前删掉。但要注意删包可能会影响依赖关系删之前最好用rpm -e --test测试一下。清理临时文件和日志。/tmp、/var/tmp、/var/log这些目录下的文件可以清掉。特别是日志文件有时候能占好几个 G。清理命令很简单rm -rf /tmp/* rm -rf /var/tmp/* find /var/log -type f -exec truncate -s 0 {} \;注意/var/log下的文件不要直接删因为有些服务依赖这些文件的存在。用truncate清空内容就行。检查网络配置。如果目标机器的网络环境和源机器不一样比如 IP 地址、网关、DNS那在打包前要把网络配置改成 DHCP 或者留空等恢复后再配。否则恢复出来的系统网络不通还得进单用户模式改配置很麻烦。检查/etc/fstab。如果里面有挂载数据盘的条目而目标机器没有对应的盘系统启动时会卡住。我的做法是在打包前把数据盘的挂载条目注释掉等恢复后再加回去。3.2 Mondo Rescue 的安装与依赖处理CentOS 7 的默认源里没有 Mondo Rescue需要从第三方源安装。我一般用 EPEL 源加上 Mondo 的官方源。安装步骤如下yum install -y epel-release wget ftp://ftp.mondorescue.org/centos/7/x86_64/mondorescue.repo -O /etc/yum.repos.d/mondorescue.repo yum install -y mondo安装完成后运行mondoarchive --version确认安装成功。如果提示缺少依赖根据提示安装对应的包。常见的依赖包括afio、buffer、mtools、syslinux等。这里有个坑Mondo Rescue 的版本和 CentOS 7 的版本要匹配。如果用的是 CentOS 7.9最好找对应版本的 Mondo 包。版本不匹配可能会导致打包失败或者生成的 ISO 无法启动。另一个坑是syslinux的版本。Mondo Rescue 用syslinux来制作可启动 ISO如果syslinux版本太老可能不支持某些启动方式。CentOS 7 默认的syslinux版本是 4.05一般够用。如果遇到启动问题可以尝试升级syslinux。3.3 打包参数的详细解读Mondo Rescue 的参数很多但常用的就那么几个。我一般用交互式模式因为可以一步步确认选项不容易出错。运行mondoarchive进入交互界面然后按提示选择。第一个选项是备份路径。选择一个有足够空间的目录比如/data/backup。不要选/tmp因为/tmp可能会被清理。第二个选项是备份介质类型。选择ISO这样会生成 ISO 文件。如果选DVD会生成适合刻录到 DVD 的镜像。如果选Tape会输出到磁带。我们一般选ISO。第三个选项是压缩方式。可选gzip、bzip2、lzo、lzma。gzip最快压缩率一般bzip2慢一些压缩率好一些lzma最慢压缩率最好。我一般选gzip因为时间比空间重要。第四个选项是是否排除某些目录。默认会排除/proc、/sys、/dev等虚拟文件系统。如果有一些大目录不想打包比如/data、/home可以在这里排除。第五个选项是是否验证备份。建议选“是”这样打包完成后会自动验证 ISO 的完整性。虽然多花一点时间但能提前发现问题。第六个选项是是否创建校验文件。建议选“是”生成一个 MD5 或 SHA256 文件方便后续核对。参数选择完成后Mondo Rescue 会开始打包。这个过程会输出大量日志可以另开一个终端用tail -f看日志。如果看到错误信息及时处理。3.4 打包过程中的资源监控打包过程中要关注几个资源指标磁盘空间、内存使用、CPU 负载。磁盘空间方面Mondo Rescue 会在备份路径下生成临时文件这些文件的大小可能和源系统已用空间相当。如果备份路径所在的分区空间不够打包会失败。可以在打包前用df -h确认打包过程中用watch df -h持续监控。内存使用方面Mondo Rescue 在打包时会占用一定内存但一般不会太多。如果系统内存很小比如 1G 以下可能会触发 OOM。可以在打包前用free -m确认如果内存紧张可以临时增加 swap。CPU 负载方面压缩过程是 CPU 密集型的如果选了高压缩率CPU 会跑满。如果这台机器还在跑其他服务可能会影响服务质量。建议在业务低峰期做打包或者用nice和ionice降低打包进程的优先级。nice -n 19 ionice -c 3 mondoarchive这样打包进程会让出 CPU 和磁盘 IO对业务影响小一些。4. 实操过程与核心环节实现4.1 从零开始制作一个可启动 ISO假设我们有一台 CentOS 7 机器已经调好了所有配置现在要把它做成 ISO。以下是完整操作步骤。第一步确认系统状态。运行以下命令检查磁盘、内存、包数量df -h free -m rpm -qa | wc -l输出示例Filesystem Size Used Avail Use% Mounted on /dev/sda2 50G 20G 30G 40% / /dev/sda1 500M 200M 300M 40% /boot这里根分区有 30G 可用足够打包。第二步清理系统。运行清理命令rm -rf /tmp/* rm -rf /var/tmp/* find /var/log -type f -exec truncate -s 0 {} \; yum clean all第三步检查网络配置和 fstab。编辑/etc/sysconfig/network-scripts/ifcfg-eth0把BOOTPROTO改成dhcp删掉IPADDR、GATEWAY、DNS1等条目。编辑/etc/fstab注释掉数据盘的挂载条目。第四步安装 Mondo Rescue。运行yum install -y epel-release wget ftp://ftp.mondorescue.org/centos/7/x86_64/mondorescue.repo -O /etc/yum.repos.d/mondorescue.repo yum install -y mondo第五步运行mondoarchive。进入交互界面后按以下选择备份路径/data/backup备份介质ISO压缩方式gzip排除目录/data、/home验证备份Yes创建校验文件Yes第六步等待打包完成。打包时间取决于系统大小和磁盘速度。20G 的系统用 gzip 压缩大概需要 30 到 60 分钟。第七步检查输出文件。打包完成后在/data/backup目录下会生成 ISO 文件和校验文件。运行ls -lh查看文件大小运行md5sum -c校验文件完整性。4.2 关键参数的计算与选择过程打包过程中有几个参数需要根据实际情况计算。第一个是 ISO 体积的估算。ISO 体积大致等于源系统已用空间乘以压缩率。gzip 的压缩率一般在 0.6 到 0.8 之间也就是说 20G 的系统压缩后大概 12G 到 16G。如果选了 bzip2压缩率能到 0.5 到 0.7但时间会长一倍。如果选了 lzma压缩率能到 0.4 到 0.6但时间会长好几倍。第二个是临时空间的需求。Mondo Rescue 在打包过程中会在备份路径下生成临时文件这些文件的大小可能和源系统已用空间相当。所以备份路径所在的分区剩余空间至少要等于源系统已用空间。比如源系统用了 20G备份路径所在分区至少要有 20G 剩余空间。第三个是内存的需求。Mondo Rescue 在打包时会占用一定内存但一般不会超过 500M。如果系统内存小于 1G建议临时增加 swap。增加 swap 的方法dd if/dev/zero of/swapfile bs1M count2048 chmod 600 /swapfile mkswap /swapfile swapon /swapfile这样临时增加了 2G swap打包完成后可以用swapoff /swapfile关掉然后删掉文件。4.3 打包完成后的验证与恢复测试打包完成后不要急着把 ISO 拿去用。先做一次恢复测试确认 ISO 能正常启动和恢复。测试方法有两种一种是用虚拟机一种是用物理机。虚拟机更方便推荐用 VirtualBox 或 VMware。创建一个新的虚拟机把 ISO 挂载为启动盘然后启动。启动后会进入 Mondo Rescue 的恢复界面。按提示选择恢复模式一般选“交互式恢复”。然后选择要恢复的分区确认恢复目标。恢复过程会把 ISO 里的系统文件写到硬盘上。恢复完成后重启虚拟机。如果一切正常系统应该能正常启动网络能通关键服务能跑。如果启动失败根据错误信息排查。常见的启动失败原因包括硬盘控制器类型不匹配、分区表不一致、引导程序未正确安装。这些问题在后面的排查章节会详细说。4.4 批量部署时的网络启动方案如果要做批量部署一张一张光盘去装太慢。可以把 ISO 放到网络启动服务器上通过 PXE 启动来批量部署。PXE 启动的配置稍微复杂一些需要 DHCP 服务器、TFTP 服务器、HTTP 服务器。大致流程是客户端通过 DHCP 获取 IP 和 TFTP 地址然后从 TFTP 下载引导文件再从 HTTP 下载 ISO 文件最后启动恢复环境。这个方案适合有几十台以上机器要部署的场景。如果只有几台还是用 U 盘或光盘更快。5. 常见问题与排查技巧实录5.1 打包失败类问题排查打包失败是最常见的问题原因五花八门。我整理了一个速查表错误现象可能原因解决方法提示空间不足备份路径所在分区剩余空间不够清理空间或换一个分区提示依赖缺失缺少 afio、buffer 等包根据提示安装对应包打包到一半卡住某个大文件正在被写入停止相关服务或排除该目录提示权限不足当前用户不是 root用 root 用户运行ISO 生成后无法启动syslinux 版本不兼容升级 syslinux 或换用 isolinux恢复后系统起不来硬盘控制器类型不匹配在 BIOS 里改硬盘模式为 IDE 或 AHCI这里重点说两个坑。第一个坑是“打包到一半卡住”。有一次我打包一个数据库服务器Mondo Rescue 跑到一半就不动了。查日志发现它在打包一个正在被写入的数据库文件文件很大而且一直在变。解决办法是在打包前停掉数据库服务或者把数据库目录排除掉。第二个坑是“ISO 生成后无法启动”。有一次我生成的 ISO 在虚拟机里启动不了提示“isolinux.bin missing or corrupt”。查了半天发现是 syslinux 版本太老不支持我用的启动方式。解决办法是升级 syslinux 到最新版或者改用 grub 作为引导程序。5.2 恢复后系统异常的处理恢复后系统异常的情况也不少。常见的有网络不通、服务起不来、磁盘挂载失败。网络不通一般是因为源机器的网络配置是静态 IP恢复后 IP 冲突或者网关不对。解决办法是进单用户模式把网络配置改成 DHCP或者改成正确的静态 IP。服务起不来一般是因为服务依赖的某个文件或目录在打包时被排除了。比如你把/var/lib/mysql排除了恢复后 MySQL 就起不来。解决办法是重新打包把必要的目录包含进去。磁盘挂载失败一般是因为/etc/fstab里有数据盘的挂载条目但目标机器没有对应的盘。解决办法是进单用户模式注释掉相关条目。5.3 镜像体积优化的几个技巧ISO 体积太大是个常见问题。除了选高压缩率还有几个技巧可以减小体积。第一个技巧是清理包缓存。yum clean all可以清掉/var/cache/yum下的缓存文件有时候能省几个 G。第二个技巧是删除旧内核。CentOS 7 默认会保留多个内核版本每个内核大概 100M 到 200M。用package-cleanup --oldkernels --count1只保留最新内核。第三个技巧是排除大目录。比如/usr/share/doc、/usr/share/man这些文档目录可以排除掉。但要注意有些程序依赖这些目录下的文件排除前要确认。第四个技巧是用lzma压缩。虽然慢但压缩率确实好。如果时间不紧张可以用lzma。5.4 跨硬件恢复的注意事项跨硬件恢复是 Mondo Rescue 的一个弱项。如果源机器和目标机器的硬件差别太大恢复后可能起不来。主要的风险点在硬盘控制器。如果源机器用的是 SCSI 控制器目标机器用的是 SATA 控制器恢复后系统可能找不到硬盘。解决办法是在打包前把硬盘控制器的驱动都装上或者在恢复后进单用户模式重新生成 initramfs。另一个风险点是网卡。如果源机器和目标机器的网卡型号不一样恢复后网络可能不通。解决办法是在打包前把常见网卡的驱动都装上或者恢复后手动配置网络。还有一个风险点是 CPU 架构。如果源机器是 Intel CPU目标机器是 AMD CPU一般没问题。但如果源机器是 64 位系统目标机器是 32 位 CPU那就起不来。这个在打包前要确认。6. 我个人的实操心得与建议做系统镜像这件事我踩过的坑比成功次数还多。最开始几次打包要么是空间不够要么是恢复后起不来要么是 ISO 体积太大。后来慢慢总结出几条经验。第一条经验是打包前一定要做一次完整的系统检查。检查磁盘空间、内存、网络配置、fstab、服务状态。这些检查花不了几分钟但能避免大部分问题。第二条经验是打包后一定要做恢复测试。不要觉得打包成功就万事大吉恢复测试才是真正的验证。我一般会在虚拟机里跑一遍恢复流程确认系统能正常启动。第三条经验是镜像要定期更新。系统配置会变软件会升级安全补丁会打。如果镜像太久不更新恢复出来的系统可能有一堆漏洞。我一般每季度更新一次镜像。第四条经验是镜像要妥善保管。ISO 文件很大放在本地磁盘上容易丢。我一般会复制到网络存储上同时保留一份校验文件。恢复前先校验确认文件完整。最后再分享一个小技巧如果打包过程中遇到莫名其妙的错误可以试试加-v参数看详细日志。Mondo Rescue 的日志有时候不够详细加-v能看到更多信息。另外/var/log/mondoarchive.log里也有完整日志可以仔细看。