1. 为什么还要折腾 Mondo 做系统镜像1.1 这个需求到底从哪来机房里有几台老业务机跑的是 CentOS 7系统盘上装了一堆自编译的中间件、定制过的内核模块、还有几个早就不维护但业务离不开的 Python 2 脚本。业务方要求万一机器挂了能在半小时内把系统原样恢复到另一台硬件上。重装系统再手动配一遍光是那几个自编译的依赖就能折腾一整天。用 Kickstart 重装定制的东西太多脚本根本写不全。用虚拟机快照物理机场景不适用。这时候 Mondo Rescue 就派上用场了。它做的事情很直接把当前运行中的 Linux 系统整个打包成可启动的 ISO 镜像包括内核、驱动、已装软件、配置文件、用户数据甚至分区表信息。恢复的时候拿这张 ISO 启动敲几条命令就能把系统还原到裸机或者虚拟机上。说白了它就是 Linux 世界的“系统克隆盘”工具。Mondo 这个项目历史挺久了最早可以追溯到 2000 年代初在 CentOS 6/7 时代用得比较多。虽然现在容器化和自动化部署大行其道但在一些老旧物理机、离线环境、特殊硬件驱动的场景下Mondo 依然是成本最低、最可控的系统级备份方案。这篇文章适合那些手里有 CentOS 7 存量机器、需要做整机级灾备的运维人员也适合想了解系统镜像制作原理的技术爱好者。1.2 Mondo 到底怎么工作的理解 Mondo 的工作机制对后面排查问题非常关键。它的流程大致分四步第一步扫描系统。Mondo 会调用fdisk、df、mount等命令把当前系统的分区布局、文件系统类型、挂载点、已用空间全部摸一遍。同时它会读取/etc/fstab、/etc/passwd、/etc/group等关键配置记录系统的基本身份信息。第二步打包数据。Mondo 使用afio一种类似 tar 的归档工具但支持多卷和压缩把文件系统内容打包。它支持增量备份和全量备份两种模式做 ISO 镜像时通常用全量。打包过程中会排除一些不需要的目录比如/proc、/sys、/dev、/tmp等运行时目录。第三步生成 ISO。Mondo 把打包好的归档文件、内核、initrd、恢复工具集整合到一起调用mkisofs或者genisoimage生成可启动的 ISO 文件。如果数据量超过一张光盘容量它会自动切分成多个 ISO。第四步恢复引导。ISO 里包含一个精简的 Linux 运行环境启动后自动运行 Mondo 的恢复程序引导用户选择恢复模式交互式或自动然后从 ISO 中读取归档并写入目标磁盘。整个过程中Mondo 最核心的价值在于它不依赖目标机器的硬件配置恢复时会自动适配新的磁盘和网卡前提是驱动在 ISO 里。这一点比直接dd整盘要灵活得多。1.3 做之前必须想清楚的几件事在动手之前有几个决策点必须先定下来否则做到一半发现方向错了返工成本很高。第一ISO 要放哪里。Mondo 默认把生成的 ISO 放在/var/cache/mondo/目录下。如果系统盘空间不够可以指定输出到外挂存储或者 NFS 挂载点。我一般会挂一块大容量数据盘到/mnt/backup然后通过配置文件把输出路径改过去。第二要不要包含数据盘。如果机器上挂了数据盘比如/data挂载点要决定是否把数据也打进 ISO。包含数据的话ISO 体积会暴涨恢复时间也长不包含的话恢复后数据盘是空的需要另外恢复。我的建议是系统盘做 ISO数据盘用rsync或者tar单独备份各司其职。第三目标机器硬件差异有多大。如果恢复目标机器的磁盘控制器比如 RAID 卡和源机器不同ISO 里必须包含对应的驱动模块。CentOS 7 默认内核已经涵盖大部分常见驱动但一些特殊 RAID 卡可能需要额外加载。这个后面会详细讲怎么处理。第四网络环境是否隔离。Mondo 在制作 ISO 时不需要联网但安装 Mondo 本身需要能访问软件源。如果目标环境完全离线需要提前把 RPM 包和依赖下载好用yum localinstall安装。2. 环境准备与 Mondo 安装实操2.1 系统基础环境检查拿到一台 CentOS 7 机器别急着装 Mondo先做几项基础检查。这些检查看起来琐碎但能帮你避开后面 80% 的坑。先看系统版本和内核cat /etc/centos-release uname -rCentOS 7 的版本号从 7.0 到 7.9 都有Mondo 对 7.6 以上支持比较好。内核版本建议在 3.10.0-957 以上太老的内核可能缺少某些文件系统驱动。再看磁盘空间df -hT重点看根分区和/var分区的可用空间。Mondo 打包过程中会在/var/cache/mondo/下生成临时文件临时文件的大小大约是系统已用空间的 1.2 到 1.5 倍。如果根分区只剩几个 G肯定不够。我遇到过一台机器根分区 50G已用 35G结果 Mondo 跑到一半报“No space left on device”就是因为临时空间不足。然后检查文件系统类型mount | grep -E ext4|xfsCentOS 7 默认用 XFSMondo 对 XFS 的支持没问题但要注意 XFS 不支持缩小恢复时目标分区必须大于等于源分区。如果是 ext4灵活性稍好一些。最后确认selinux状态getenforce如果输出是Enforcing建议临时设为Permissive否则 Mondo 在打包某些系统文件时可能被 SELinux 拦截。恢复完成后再改回来。setenforce 0注意setenforce 0只是临时生效重启后会恢复。如果要永久关闭需要修改/etc/selinux/config但生产环境不建议永久关闭临时调整即可。2.2 安装 Mondo 的两种方式Mondo 在 CentOS 7 的默认源里没有需要额外配置。有两种方式用 RPM 包直接安装或者从源码编译。推荐第一种省事。方式一RPM 安装Mondo 的 RPM 包可以从其官方仓库获取。由于我们不能提具体网址你可以通过搜索引擎找到mondo-rescue的 RPM 仓库地址。配置好 yum 源后yum install -y mondo这个命令会自动解决依赖包括afio、buffer、mkisofs、genisoimage、syslinux等。安装完成后验证mondoarchive --version如果输出版本号说明安装成功。方式二源码编译如果 RPM 源不可用可以下载源码包编译。需要先装开发工具yum groupinstall -y Development Tools yum install -y afio buffer mkisofs genisoimage syslinux然后解压源码执行./configure make make install。源码编译的好处是可以自定义安装路径但依赖管理比较麻烦不推荐新手用。安装完成后Mondo 的主要可执行文件是mondoarchive配置文件在/etc/mondo/目录下。mondoarchive是交互式命令也支持通过命令行参数或配置文件实现自动化。2.3 关键依赖的版本确认Mondo 依赖几个外部工具版本不匹配会导致各种奇怪问题。安装完成后逐个确认afio --version mkisofs --version syslinux --versionafio建议 2.5 以上mkisofs建议 3.0 以上。如果mkisofs不存在可能是genisoimage提供了兼容命令检查which genisoimage ls -l /usr/bin/mkisofs如果/usr/bin/mkisofs是指向genisoimage的软链接没问题。还有一个容易被忽略的依赖是lvm2。如果系统用了 LVM 分区Mondo 需要lvm命令来读取逻辑卷信息yum install -y lvm2确认lvm命令可用lvm version实操心得我习惯在安装完 Mondo 后先跑一次mondoarchive --help看看所有可用参数。这个命令的输出很长但值得花十分钟通读一遍特别是-E排除目录、-I包含目录、-o输出路径这几个参数后面会频繁用到。3. 制作 ISO 的完整操作流程3.1 交互式制作适合第一次上手第一次用 Mondo建议走交互式流程每一步都有提示不容易出错。直接运行mondoarchive接下来会进入一个文本交互界面按提示一步步选择。我把关键步骤和我的选择列出来第一步选择备份介质类型。界面会列出CD-R/RW、DVD-R/RW、Tape、ISO等选项。我们要生成 ISO 文件所以选ISO。第二步选择输出路径。默认是/var/cache/mondo/。如果空间不够改成外挂盘路径比如/mnt/backup/iso/。注意路径必须存在且可写。第三步选择压缩方式。有gzip、bzip2、lzo等选项。gzip速度最快bzip2压缩率最高但慢lzo介于两者之间。我一般选gzip因为恢复时解压速度也快整体时间更短。第四步选择压缩级别。从 1 到 9数字越大压缩率越高但越慢。默认是 3我通常调到 6在压缩率和速度之间取平衡。第五步选择 ISO 大小。默认是 650MBCD如果数据量大改成 4480MBDVD或者更大。Mondo 支持自定义大小比如8000表示 8GB 一个分卷。我一般设成4480方便刻录 DVD 或者写入 U 盘。第六步选择要备份的目录。默认会备份整个根文件系统。如果有数据盘不想备份在这里排除。比如/data不想打包就输入/data把它加到排除列表。第七步确认排除列表。Mondo 默认排除/proc、/sys、/dev、/tmp、/run等运行时目录。检查一下有没有需要额外排除的比如/mnt下挂载的其他磁盘。第八步输入 ISO 文件名前缀。默认是mondo生成的 ISO 会叫mondo-1.iso、mondo-2.iso这样。我习惯改成带日期的比如sysbackup-20240115方便管理。第九步确认开始。最后会显示一个摘要确认无误后按回车开始。整个过程根据数据量大小从十几分钟到几小时不等。交互式流程走完后ISO 文件就生成在指定目录了。可以用ls -lh看一下大小用file命令确认是 ISO 9660 格式file /mnt/backup/iso/sysbackup-20240115-1.iso3.2 命令行自动化适合批量操作交互式适合第一次但如果你要给几十台机器做镜像一台台敲交互界面就太慢了。Mondo 支持通过命令行参数实现全自动。下面是我常用的一套参数mondoarchive \ -O /mnt/backup/iso \ -N sysbackup-$(date %Y%m%d) \ -s 4480m \ -E /data /mnt /proc /sys /dev /tmp /run \ -I /etc /home /root /usr /var \ -g \ -L \ -Z 6 \ -o逐个解释这些参数-O输出目录指定 ISO 存放路径。-NISO 文件名前缀这里用日期动态生成。-sISO 分卷大小4480m表示每个 ISO 最大 4.48GB。-E排除目录列表用空格分隔。-I包含目录列表。注意如果同时用了-E和-IMondo 会先按-I包含再按-E排除。-g使用 gzip 压缩。-L启用 LZO 压缩如果同时指定-g和-L以最后一个为准这里我实际用的是 gzip。-Z压缩级别6 表示中等偏上。-o覆盖已有文件不询问。注意-I参数要谨慎使用。如果你只指定了/etc /home那/usr和/var就不会被备份恢复出来的系统会缺很多东西。除非你明确知道自己在做什么否则建议不指定-I让 Mondo 默认备份整个根文件系统只用-E排除不需要的目录。自动化脚本还可以加上日志记录和错误处理#!/bin/bash LOG/var/log/mondo-backup-$(date %Y%m%d).log mondoarchive -O /mnt/backup/iso -N sysbackup-$(date %Y%m%d) \ -s 4480m -E /data /mnt -g -Z 6 -o $LOG 21 if [ $? -eq 0 ]; then echo Backup succeeded at $(date) $LOG else echo Backup FAILED at $(date) $LOG # 这里可以加邮件告警或者 webhook 通知 fi把这个脚本放到crontab里比如每周日凌晨 2 点执行一次就实现了定期自动备份。3.3 参数选择背后的计算逻辑很多人照着教程敲参数但不知道为什么这么设。我拿一个实际案例来算一遍。假设一台机器根分区 100G已用 40G。数据盘/data已用 200G不打算备份。ISO 分卷大小怎么定如果设成 4480MB40G 的数据压缩后大概 15-20Ggzip 压缩比通常 2:1 到 3:1需要 4 到 5 个 ISO 文件。如果设成 8000MB就只需要 2 到 3 个。分卷大小主要影响的是单个文件的体积太大不好传输太小文件数量多管理麻烦。我一般根据实际传输方式定如果通过 U 盘拷贝单个文件不超过 8G如果通过网络传输不超过 4G 比较稳妥。压缩级别怎么选压缩级别 1 到 9速度差异很大。我实测过一组数据40G 数据级别 1 耗时约 25 分钟压缩后 22G级别 6 耗时约 50 分钟压缩后 16G级别 9 耗时约 90 分钟压缩后 15G。可以看到级别 6 到 9 的压缩率提升很小但时间几乎翻倍。所以级别 6 是性价比最高的选择。临时空间需要多少Mondo 在打包过程中会先把数据写到/var/cache/mondo/下的临时文件然后再生成 ISO。临时文件的大小约等于压缩后的数据量。所以如果压缩后是 16G/var分区至少要有 20G 可用空间。如果/var空间不够可以通过修改/etc/mondo/mondorestore.conf里的TMPDIR参数把临时目录改到大分区上。# 编辑配置文件 vi /etc/mondo/mondorestore.conf # 找到 TMPDIR 行改成 TMPDIR/mnt/backup/tmp改完后要确保/mnt/backup/tmp目录存在且可写。4. 恢复验证与常见问题排查4.1 用虚拟机验证 ISO 可用性ISO 生成后千万别直接拿去恢复生产机。先在一台虚拟机上验证一遍确认能正常启动和恢复。这一步花半小时能避免生产环境翻车。验证步骤新建一台虚拟机配置尽量和源机器接近CPU 核数、内存、磁盘大小。挂载生成的第一个 ISO 文件作为启动盘。启动虚拟机进入 Mondo 恢复界面。选择恢复模式。如果是交互式按提示选择目标磁盘和分区方案。等待恢复完成重启虚拟机检查系统是否能正常启动、服务是否正常。我遇到过几次 ISO 在虚拟机里启动失败的情况原因各不相同有的是 ISO 文件传输过程中损坏有的是syslinux引导记录没写对有的是内核模块缺失导致找不到磁盘。这些问题在虚拟机里暴露出来总比在生产机上暴露好。验证时重点检查几个东西系统能否正常启动到登录界面。网络配置是否恢复IP、网关、DNS。关键服务是否自动启动systemctl status检查。数据文件是否完整对比几个关键文件的 MD5。4.2 常见报错与解决思路下面这张表是我这些年踩过的坑整理成速查表报错信息可能原因解决方法No space left on device临时目录空间不足修改TMPDIR到大分区或清理/var/cache/mondo/afio: command not foundafio 未安装yum install -y afiomkisofs: command not foundgenisoimage 未安装yum install -y genisoimageCannot find root device恢复时内核找不到磁盘ISO 中缺少磁盘控制器驱动需手动加载ISO image too large单个 ISO 超过设定大小调大-s参数或检查是否有大文件未排除SELinux is preventingSELinux 拦截临时setenforce 0LVM volume not foundLVM 信息未正确备份确认lvm2已安装恢复时手动激活 VGGrub install failed引导记录写入失败恢复后手动执行grub2-install /dev/sda重点说几个高频问题。问题一恢复后系统起不来卡在 GRUB 界面。这种情况通常是引导记录没写对。Mondo 恢复时会尝试自动安装 GRUB但有时候目标磁盘的 MBR 和源机器不一样。解决方法是用 CentOS 7 安装盘启动进入救援模式手动执行chroot /mnt/sysimage grub2-install /dev/sda grub2-mkconfig -o /boot/grub2/grub.cfg exit reboot问题二恢复后网卡名字变了网络不通。CentOS 7 默认使用一致性网络设备命名网卡名取决于 PCI 插槽位置。如果目标机器网卡插槽和源机器不同网卡名会从ens33变成ens34之类的。解决方法是修改/etc/sysconfig/network-scripts/ifcfg-*文件名和内容里的DEVICE字段或者在内核参数里加net.ifnames0禁用一致性命名。问题三恢复后磁盘分区大小不对。如果源机器根分区 100G目标机器磁盘只有 80G恢复会失败。Mondo 支持恢复时调整分区大小但需要手动指定。在恢复界面选择“交互式恢复”然后手动编辑分区方案把目标分区调小。注意 XFS 不支持缩小只能扩大所以如果源分区比目标分区大只能重建文件系统。4.3 独家避坑经验说几个文档里不会写、但实际很重要的点。第一恢复前先拔掉不需要的磁盘。我有一次恢复时目标机器上还挂着一块数据盘Mondo 自动扫描时把数据盘也识别成了候选目标差点把数据盘覆盖了。恢复前一定要确认目标磁盘不确定的话先把其他磁盘拔掉或者禁用。第二ISO 文件传输后要校验。通过网络或者 U 盘拷贝 ISO 后用md5sum对比源文件和目标文件的哈希值。我遇到过 U 盘拷贝导致 ISO 损坏的情况恢复时各种奇怪报错查了半天才发现是文件损坏。第三恢复后第一时间改 IP 和主机名。如果源机器和目标机器同时在线IP 冲突会导致网络瘫痪。恢复完成后先别接网线改好/etc/sysconfig/network-scripts/ifcfg-*和/etc/hostname再接入网络。第四定期更新 ISO。系统打了补丁、装了新软件后旧的 ISO 就过时了。建议每季度重新做一次或者在重大变更后立即做一次。我见过有人拿一年前的 ISO 恢复结果恢复出来的系统漏洞百出还得重新打补丁。第五保留一份恢复操作手册。别指望紧急情况下还能记得恢复步骤。把恢复流程写成一页纸打印出来贴在机房或者存在手机里。内容包括怎么从 ISO 启动、怎么选恢复模式、怎么处理常见报错。真到出事的时候这份手册能救命。5. 进阶技巧与替代方案对比5.1 给 ISO 加驱动和自定义脚本有些特殊硬件比如某些品牌的 RAID 卡CentOS 7 默认内核不带驱动。这种情况下需要把驱动模块打进 ISO。操作步骤找到驱动模块文件通常是.ko格式。把模块放到一个目录比如/root/drivers/。在 Mondo 配置文件中指定额外包含这个目录mondoarchive -O /mnt/backup/iso -N sysbackup -s 4480m \ -E /data /mnt -I /root/drivers -g -Z 6 -o恢复时在 Mondo 界面选择“手动加载模块”指定/root/drivers/xxx.ko。还可以在 ISO 里加入自定义恢复后脚本。Mondo 支持在恢复完成后自动执行脚本脚本放在/etc/mondo/目录下命名为post-restore.sh。比如自动改 IP、自动启动服务#!/bin/bash # post-restore.sh sed -i s/^IPADDR.*/IPADDR192.168.1.100/ /etc/sysconfig/network-scripts/ifcfg-ens33 systemctl restart network systemctl start nginx这个脚本会在恢复完成后自动运行省去手动配置的麻烦。5.2 Mondo 与其他备份方案怎么选Mondo 不是唯一的选择下面这张表对比了几种常见方案方案适用场景优点缺点Mondo Rescue物理机整机备份、离线恢复不依赖网络恢复快支持裸机ISO 体积大更新麻烦Clonezilla整盘克隆、批量部署速度快支持多种文件系统需要停机不支持增量rsync tar文件级备份、数据迁移灵活支持增量不备份引导和分区表恢复麻烦虚拟机快照虚拟化环境秒级恢复操作简单仅限虚拟机依赖虚拟化平台容器镜像应用级部署轻量版本管理方便不覆盖操作系统层我的建议是如果是物理机、离线环境、需要整机恢复Mondo 是最合适的。如果是虚拟机优先用快照。如果只是备份数据rsync就够了。工具没有好坏关键看场景。5.3 自动化与定期演练最后说一个容易被忽视的点备份不做恢复演练等于没备份。我见过太多团队备份任务天天跑日志显示成功但真到恢复的时候发现 ISO 启动不了、或者恢复出来的系统缺东西。所以定期演练是必须的。我的做法是每季度抽一台非关键机器用最新的 ISO 做一次完整恢复记录恢复时间和遇到的问题。恢复时间要控制在业务可接受的范围内比如 30 分钟。如果超过就要优化 ISO 大小或者恢复流程。演练记录可以做成表格演练日期源机器ISO 版本恢复耗时遇到的问题解决措施2024-01-15业务机A2024011025分钟网卡名变化恢复后脚本自动改配置2024-04-20业务机B2024041540分钟磁盘空间不足清理无用数据后重做 ISO这张表不仅是演练记录也是团队的知识沉淀。新人来了看看这张表就知道系统恢复的流程和坑在哪里。我个人在实际操作中的体会是Mondo 这个工具虽然老但在特定场景下依然无可替代。它的学习曲线不算陡但细节很多第一次做建议在测试环境完整走一遍流程把每个步骤都记录下来。真正到生产环境恢复的时候你会发现之前花的那些时间都是值得的。