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|xfs"CentOS 7 默认用 XFS,Mondo 对 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 大小。默认是 650MB(CD),如果数据量大,改成 4480MB(DVD)或者更大。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 存放路径。-N:ISO 文件名前缀,这里用日期动态生成。-s:ISO 分卷大小,4480m表示每个 ISO 最大 4.48GB。-E:排除目录列表,用空格分隔。-I:包含目录列表。注意,如果同时用了-E和-I,Mondo 会先按-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" 2>&1 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 分卷大小怎么定?如果设成 4480MB,40G 的数据压缩后大概 15-20G(gzip 压缩比通常 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 found | afio 未安装 | yum install -y afio |
mkisofs: command not found | genisoimage 未安装 | yum install -y genisoimage |
Cannot find root device | 恢复时内核找不到磁盘 | ISO 中缺少磁盘控制器驱动,需手动加载 |
ISO image too large | 单个 ISO 超过设定大小 | 调大-s参数,或检查是否有大文件未排除 |
SELinux is preventing | SELinux 拦截 | 临时setenforce 0 |
LVM volume not found | LVM 信息未正确备份 | 确认lvm2已安装,恢复时手动激活 VG |
Grub 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.ifnames=0禁用一致性命名。
问题三:恢复后磁盘分区大小不对。
如果源机器根分区 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=.*/IPADDR=192.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 | 业务机A | 20240110 | 25分钟 | 网卡名变化 | 恢复后脚本自动改配置 |
| 2024-04-20 | 业务机B | 20240415 | 40分钟 | 磁盘空间不足 | 清理无用数据后重做 ISO |
这张表不仅是演练记录,也是团队的知识沉淀。新人来了,看看这张表就知道系统恢复的流程和坑在哪里。
我个人在实际操作中的体会是:Mondo 这个工具虽然老,但在特定场景下依然无可替代。它的学习曲线不算陡,但细节很多,第一次做建议在测试环境完整走一遍流程,把每个步骤都记录下来。真正到生产环境恢复的时候,你会发现之前花的那些时间都是值得的。