CentOS 7 整机镜像打包实战:Mondo 制作可引导 ISO 与恢复验证
1. 为什么还要用 Mondo 做整机镜像在虚拟化与容器化大行其道的今天很多人会觉得整机打包成 ISO这件事已经过时了。但实际运维场景里仍然有大量需求绕不开它一批老旧的物理服务器要批量重装、一个已经调优到完美状态的运行环境需要原样复制到几十台机器、某些内网设备不允许联网只能靠光盘或 U 盘离线部署。这些场景下逐台重装再手工配置时间成本高得离谱而且人为操作必然带来不一致。Mondo Rescue下文简称 Mondo就是解决这类问题的老牌工具。它的核心能力是把一台正在运行的 Linux 系统的完整状态——包括内核、驱动、已安装软件、配置文件、用户数据、分区结构——打包成可引导的 ISO 镜像。恢复时用这张盘启动就能把系统还原到打包那一刻的样子连分区表都能一并还原。对于 CentOS 7 这种生命周期长、存量部署极广的系统来说Mondo 依然是很多运维人员手里的整机克隆利器。这篇文章面向的是有基本 Linux 操作经验、需要做系统级备份或批量部署的读者。我会从 Mondo 的工作原理讲起把 CentOS 7 上的完整实操流程拆开揉碎重点讲清楚那些官方文档里一笔带过、但实际会卡住你的细节软件源怎么配、临时目录空间怎么算、镜像体积怎么压、恢复时分区对不上怎么办。全文基于我在实际项目中反复验证过的做法参数和命令都可以直接抄。需要先说明一点Mondo 打包出来的是整机快照不是增量备份工具。它适合做基线镜像、交付镜像、灾备镜像不适合做每日增量。搞清楚这个定位后面的取舍就顺了。2. Mondo 打包整机的底层逻辑2.1 它到底打包了哪些东西很多人第一次用 Mondo会误以为它只是把根目录tar一遍。实际上它的工作范围要广得多。Mondo 在打包时会扫描并记录以下几类信息分区布局每块磁盘的分区表类型MBR/GPT、每个分区的起止扇区、文件系统类型、挂载点。这些信息会写进恢复时用的脚本里所以恢复出来的分区结构和原机一致。引导加载程序GRUB 的配置、/boot下的内核与 initramfs。这是镜像能引导的关键也是出错最多的地方。文件系统内容按挂载点逐个打包默认排除/proc、/sys、/dev、/tmp这类虚拟或临时目录。软件包清单记录已安装的 RPM 包列表恢复后可用于校验。网络与系统配置主机名、网络配置、/etc下的各类配置。理解这一点很重要Mondo 恢复的不只是文件而是一台机器的完整形态。这也是它和普通文件备份工具的本质区别。2.2 镜像的两种形态ISO 与 USBMondo 最终产物有两种常见形态。一种是可引导的 ISO 文件刻盘或挂载后启动另一种是直接写入 U 盘的镜像。两者内容基本一致区别在于引导方式。ISO 走的是光盘引导路径El ToritoU 盘则依赖 MBR 引导。实际项目中我更推荐先做出 ISO再用工具写入 U 盘因为 ISO 便于归档和校验U 盘写入失败可以重来。镜像内部通常分成多个文件一个引导镜像、若干数据分片*.afio之类、一个恢复脚本。数据分片的大小可以控制默认会按介质容量切分。如果你要刻 DVD就得把分片控制在单张盘容量以内如果只是存成一个大 ISO 文件可以放宽。2.3 为什么它对空间和内存敏感Mondo 打包过程中会在临时目录里生成大量中间文件体积可能接近甚至超过原始数据量。如果/var/cache/mondo或你指定的临时目录所在分区空间不够打包会在中途失败而且报错信息往往不直观。另外Mondo 打包时会调用afio、gzip/lzo等压缩工具这些是 CPU 和内存密集型操作。内存不足时压缩进程可能被 OOM killer 干掉表现为打包到一半突然退出。所以正式打包前务必确认两件事临时目录有足够空间经验值是原始数据量的 1.5 到 2 倍以及机器有足够内存余量。这两点后面会给出具体的检查命令。3. CentOS 7 上的环境准备与依赖安装3.1 软件源配置最容易卡住的第一步CentOS 7 已经停止常规维护默认的镜像源大多失效。Mondo 本身不在基础仓库里需要额外配置源。这一步是新手最容易翻车的地方——直接yum install mondo大概率报找不到软件包。我的做法是先把基础源指向可用的归档地址再引入 Mondo 所在的仓库。具体操作如下# 备份原有源配置 mkdir -p /etc/yum.repos.d/bak mv /etc/yum.repos.d/CentOS-*.repo /etc/yum.repos.d/bak/ 2/dev/null # 写入可用的基础源归档地址 cat /etc/yum.repos.d/CentOS-Base.repo EOF [base] nameCentOS-7-Base baseurlhttp://mirror.example.org/centos/7/os/x86_64/ gpgcheck0 enabled1 [updates] nameCentOS-7-Updates baseurlhttp://mirror.example.org/centos/7/updates/x86_64/ gpgcheck0 enabled1 [extras] nameCentOS-7-Extras baseurlhttp://mirror.example.org/centos/7/extras/x86_64/ gpgcheck0 enabled1 EOF # 清理并重建缓存 yum clean all yum makecache注意上面的mirror.example.org是占位地址实际使用时替换成你所在网络能访问的镜像地址。内网环境建议自建镜像站避免打包时因网络抖动中断。基础源通了之后再配置 Mondo 的仓库。Mondo 官方为 CentOS 7 提供过 RPM 包通常放在第三方仓库里。配置好之后执行安装yum install -y mondo如果仓库里确实找不到也可以下载 RPM 包本地安装但要手动解决依赖比较麻烦。我一般优先走仓库方式。3.2 依赖组件逐个确认Mondo 依赖一批工具安装时 yum 会自动拉取但有几个关键组件值得单独确认因为它们直接影响打包能否成功组件作用缺失后果afio归档与压缩引擎打包直接无法启动gzip/bzip2/lzo压缩算法支持无法压缩镜像巨大mkisofs/genisoimage生成 ISO无法产出 ISO 文件syslinux/isolinux引导支持镜像无法引导mkfs.*系列恢复时格式化分区恢复阶段失败parted/fdisk分区操作分区还原失败一条命令确认它们是否就位for pkg in afio gzip bzip2 lzo mkisofs genisoimage syslinux parted; do rpm -q $pkg /dev/null 21 echo $pkg OK || echo $pkg MISSING done任何一项显示 MISSING都要先补装再继续。3.3 临时目录与空间规划Mondo 默认使用/var/cache/mondo作为工作目录。这个目录所在分区必须有充足空间。先看当前磁盘使用情况df -h du -sh --exclude/proc --exclude/sys --exclude/dev --exclude/tmp /第二条命令估算的是需要打包的数据总量。把它的结果乘以 1.5 到 2就是临时目录至少需要的空间。如果/var分区不够可以改到别的分区比如挂载一块大容量数据盘到/mnt/mondo-work然后在配置里指定。修改工作目录有两种方式一是改配置文件/etc/mondo/mondorescue.conf里的tmpdir项二是打包时用命令行参数覆盖。我倾向于后者灵活且不污染全局配置。内存方面用free -h看一眼。压缩过程对内存有要求如果可用内存低于 1GB建议改用lzo这种低内存占用的压缩算法或者干脆不压缩镜像会很大。4. 一次完整的 ISO 打包实操4.1 交互式打包适合第一次上手Mondo 提供交互式向导第一次用强烈建议走这条路因为它会一步步问你关键参数帮你建立直观认识。启动命令mondoarchive接下来会依次询问备份介质类型选ISO生成 ISO 文件或DVD按光盘容量切分。第一次建议选 ISO。备份路径ISO 文件输出到哪个目录比如/mnt/backup。压缩方式gzip通用、bzip2压缩率高但慢、lzo快但压缩率一般。追求体积选 bzip2追求速度选 lzo。压缩级别1 到 9数字越大压缩越狠、越慢。一般选 6。分片大小单个数据分片的最大体积。存成一个大 ISO 就选大一点比如 4096MB。排除目录默认已排除虚拟目录可以再补充比如/mnt、/data这类不需要备份的挂载点。确认内核与模块Mondo 会列出它识别到的内核确认无误后继续。回答完这些问题它就开始扫描、打包、生成 ISO。整个过程耗时取决于数据量和压缩级别几十 GB 的数据可能要跑一两个小时。4.2 命令行打包适合脚本化和批量交互式适合摸索但真正在生产里用还是命令行更可控。下面这条是我常用的模板mondoarchive \ -O /mnt/backup \ -o \ -E /mnt /data /proc /sys /dev /tmp \ -N \ -s 4096m \ -z bzip2 \ -l 6 \ -I \ -p $(hostname)-$(date %Y%m%d)逐个解释这些参数理解了才能按需调整-O /mnt/backup输出目录。-o生成 ISO 镜像。-E ...排除的目录列表用空格分隔。-N不备份网络文件系统NFS 等避免把远程挂载也打进去。-s 4096m分片大小 4GB。-z bzip2压缩算法。-l 6压缩级别。-I交互确认后开始去掉它则全自动但风险高建议保留。-p 前缀输出文件的前缀名用主机名加日期便于归档管理。提示-E里的排除项一定要想清楚。把数据盘排除掉能大幅缩小镜像但恢复后那些数据就不在了需要另行恢复。这是取舍不是对错。4.3 打包过程中的正常输出与异常信号打包时终端会滚动大量日志。正常的流程大致是扫描分区 → 挂载点检查 → 逐个文件系统打包 → 生成引导 → 合成 ISO。看到类似Making ISO image的字样说明接近尾声。需要警惕的信号有几个长时间卡在某个百分比不动可能是某个大文件压缩慢也可能是磁盘 I/O 瓶颈。用iostat看一眼就知道。出现afio: ... No space left on device说明临时目录满了必须清理后重来。出现Killed字样多半是内存不足被系统杀进程换低内存压缩算法或加内存。打包完成后输出目录里会出现.iso文件以及若干辅助文件。用ls -lh确认体积用md5sum记录校验值方便后续验证。5. 镜像瘦身与体积控制的实战技巧5.1 打包前先做减法镜像体积直接决定刻盘张数和传输时间。与其事后压缩不如打包前就清理。我通常会在打包前做这几件事# 清理 yum 缓存 yum clean all # 清理日志保留最近的即可 find /var/log -type f -name *.log -exec truncate -s 0 {} \; # 清理临时文件 rm -rf /tmp/* /var/tmp/* # 查看大目录找出可以排除的 du -sh /var/* 2/dev/null | sort -rh | head -20/var/log、/var/cache、/tmp往往是体积大户清理后能省下可观的量。如果系统里有测试数据、下载的安装包也一并清掉。5.2 压缩算法的选择逻辑三种压缩算法的取舍我用一张表说清楚算法压缩率速度内存占用适用场景gzip中等中等中等通用兼容性最好bzip2高慢较高追求最小体积不赶时间lzo低快低内存紧张或赶时间实测下来同一份数据 bzip2 比 gzip 能小 10% 到 20%但耗时可能翻倍。如果只是内部使用、不刻盘gzip 级别 6 是性价比最高的选择。如果内存只有 1GB 出头老老实实用 lzo。5.3 分片大小的权衡分片大小决定了单个文件的上限。如果目标是刻 DVD单层 4.7GB实际可用约 4.3GB分片要控制在 4GB 以内留出引导和脚本的空间。如果只是存成一个大 ISO 文件分片可以设大比如 8GB 甚至更大减少文件数量。这里有个容易忽略的点ISO 文件本身也有 4GB 的经典限制ISO9660 格式。虽然现在多数工具支持大文件扩展但为了兼容性我一般把单张 ISO 控制在 4GB 以内。超过就分片。6. 恢复验证不做这一步等于没备份6.1 用虚拟机先验证镜像做出来最忌讳直接拿去生产机恢复。正确做法是先在一台虚拟机里验证。步骤是新建虚拟机 → 挂载 ISO → 从光盘引导 → 进入 Mondo 恢复界面 → 选择恢复目标磁盘 → 执行恢复。恢复界面会列出镜像里的分区布局让你确认恢复到哪块盘。如果虚拟机磁盘比原机小恢复会失败因为分区放不下。所以验证用的虚拟磁盘要等于或大于原机磁盘。6.2 分区对不上的处理实际恢复时最常见的报错就是分区空间不足。原因通常是目标磁盘比源磁盘小或者分区顺序不一致。Mondo 恢复时允许你手动调整分区大小但操作有风险。我的经验是目标磁盘容量必须大于等于源磁盘这是硬性前提不要试图在更小的盘上恢复。如果目标盘更大Mondo 默认按原分区大小恢复剩余空间闲置。想利用多余空间需要在恢复后手动扩容分区和文件系统这是另一套操作不在本文范围。6.3 引导修复恢复完成后第一次重启如果卡在 GRUB 或直接进不去系统多半是引导没装好。用救援模式进去重新安装 GRUB# 假设系统根分区在 /dev/sda2 mount /dev/sda2 /mnt mount --bind /dev /mnt/dev mount --bind /proc /mnt/proc mount --bind /sys /mnt/sys chroot /mnt grub2-install /dev/sda grub2-mkconfig -o /boot/grub2/grub.cfg exit这套流程能解决绝大多数引导问题。关键点是grub2-install要指向磁盘设备/dev/sda而不是分区/dev/sda2这是新手常犯的错。7. 踩过的坑与经验沉淀7.1 临时目录爆满导致中途失败这个坑我踩过不止一次。表现是打包跑到一半突然报错退出日志里翻半天才看到No space left on device。根因是临时目录所在分区空间不足。后来我养成了习惯打包前先df -h看临时目录再du -sh估算数据量两者对比确认余量。如果不够提前把工作目录改到大分区。7.2 排除列表写错导致数据丢失有一次我把/data排除了本意是数据盘单独备份结果恢复后忘了恢复数据业务直接起不来。教训是排除列表要写进文档恢复流程里要有对应的数据恢复步骤。排除不是删除但恢复时如果没人记得就等于丢了。7.3 内核更新后镜像引导失败如果打包后系统又更新了内核而镜像里还是旧内核恢复出来的系统可能因为驱动不匹配出问题。所以打包镜像的时机最好选在系统状态稳定、近期不打算大改的时候。打完包到实际使用之间尽量不要再动内核和关键驱动。7.4 网络源不稳定导致依赖装不上内网环境访问外部源经常超时。我的做法是在内网自建一个镜像站把 CentOS 7 的基础源和 Mondo 相关包都同步进去。这样打包时依赖安装稳定速度也快。自建镜像站虽然前期有投入但对于需要频繁打包的团队来说回报很高。7.5 校验值一定要留ISO 文件在传输、刻盘过程中可能损坏。每次打包完我都会生成校验值并存档md5sum /mnt/backup/*.iso /mnt/backup/checksum.md5恢复前先校验能避免很多镜像明明在却装不上的玄学问题。8. 关于自动化与批量部署的延伸单机打包跑通之后自然会想到批量。如果手头有几十台配置相同的机器没必要每台都单独打包。更高效的做法是精心配置一台模板机把它打包成基线镜像然后批量恢复到其他机器恢复后再做少量个性化配置主机名、IP、密钥等。个性化配置可以写成一个首次启动脚本放在镜像里系统第一次启动时自动执行。这样基线镜像保持通用差异部分由脚本处理。这个思路在批量交付场景里非常实用能省下大量重复劳动。另外Mondo 的镜像也可以配合 PXE 网络引导使用实现无人值守的批量恢复。不过这涉及 DHCP、TFTP、HTTP 等一整套网络引导环境的搭建复杂度较高适合有专门运维团队的场景。个人或小团队用 U 盘逐台恢复反而更简单可靠。我在实际项目里的体会是工具本身不难难的是把打包—验证—归档—恢复这条链路固化下来形成可重复的流程。每次打包都记录数据量、压缩方式、校验值、恢复验证结果时间久了就是一套可靠的资产。Mondo 这种老工具用对了场景依然能发挥很大价值。