ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

系统重装不丢镜像:Docker备份与恢复实战指南

系统重装不丢镜像:Docker备份与恢复实战指南 如果你正在读这篇文章很可能正面临两个场景中的一个要么系统已经出了问题准备重装Windows或Linux突然想起来Docker里还躺着好几个镜像要么已经重装完了打开Docker Desktop发现镜像列表空空如也心态瞬间爆炸。标题里“系统重装不丢镜像”这八个字就是我踩过三次坑之后悟出来的刚需。Docker镜像的备份与恢复本质上就是四个字导出、导入。但你真去操作的时候会发现单机备份好说批量迁移才是噩梦镜像能打tar包可恢复了之后容器起不来、数据卷没挂载、端口全部冲突……这些问题每一个我都会在后面拆开来讲。这篇文章适合谁适合正在用Docker Desktop的Windows用户、服务器上用Docker跑生产服务但准备迁移或重装的运维以及刚学Docker不久、想知道save/load和export/import到底有什么区别的新手。我会结合自己重装系统的实际操作经验把从备份到恢复的完整流程、踩坑点和避雷技巧全部捋清楚。1. 系统重装场景下的镜像迁移难点与思路拆解1.1 为什么镜像会丢不只是重装的问题先说一个大家容易忽略的事实重装系统丢了镜像其实根本不是重装这件事本身造成的而是重装前的“环境清理”把Docker的存储目录一起干掉了。Windows上如果你用的是Docker Desktop镜像默认存放在WSL2发行版的虚拟磁盘里也就是那个vhdx文件里。你重装系统整个C盘被格式化这个虚拟磁盘自然跟着灰飞烟灭。更隐蔽的是即使你只是重置了WSL2发行版——比如因为Docker Desktop启动不了顺手执行了wsl --unregister docker-desktop——镜像和数据卷也会被一并清空。这一点我特别要提醒很多人以为Docker Desktop卸载重装不会动镜像实际上如果你在卸载时勾选了删除WSL数据或者WSL发行版本身损坏导致需要重建镜像一样保不住。Linux服务器上情况类似。镜像默认存在/var/lib/docker目录下重装系统格式化分区目录没了即便是无损重装只要/var/lib/docker所在的分区没单独划出来也一样被覆盖。所以结论很清晰镜像备份不是“要不要做”的问题而是“每一次系统级变更前必须做”的固定动作。1.2 三种主流备份方案对比针对“系统重装不丢镜像”这句话目前我能想到的可靠方案有这三种方案原理优点缺点适用场景docker save tar归档把镜像导出为本地tar文件操作简单、离线可用、可控性强不能自动增量、大镜像占用磁盘空间单机迁移、系统重装前手动备份自建Docker Registry私有仓库通过push/pull同步镜像到仓库服务器可增量、适合长期维护、恢复速度快需要额外一台服务器或存储空间多台机器、定期备份、生产环境直接复制/var/lib/docker目录停服后压缩整个Docker数据目录镜像、容器、数据卷全部保留对运行中的Docker有风险、跨系统版本兼容性差Linux物理机整机迁移我自己的习惯是手动操作前用方案一日常定期备份用方案二LVM快照或者整盘灾备用方案三。方案一操作最直观适合绝大多数人方案二适合有一定基础、有多台机器的人方案三我不建议新手用因为如果新旧系统内核版本差异大/var/lib/docker目录里的存储驱动元数据很容易不兼容恢复后Docker守护进程会报错。1.3 一个容易搞混的概念备份镜像 ≠ 备份数据在展开实操之前我必须先把这件事说透Docker镜像是个只读模板真正跑起来的业务数据在容器层和数据卷里。打个比方镜像就像一张Windows安装光盘容器就是从光盘启动起来的系统。你重装电脑时如果只把光盘带走了那C盘里的文档、桌面上的照片全都没了——文档照片相当于容器内改动和数据卷。后面你会看到我备份的时候永远是“镜像tar包”加“数据卷tar包”一起打包两个都留好恢复的时候才能真正还原到重装前的状态。这个认知如果不建立就算你照着本文把镜像load回去了容器里的配置、数据库文件该缺还是缺。2. 核心细节解析save/load与export/import的取舍2.1 docker save和docker load的正确用法Docker官方提供的最基础备份手段是docker save和docker load。先看命令格式# 备份单个镜像 docker save -o nginx-backup.tar nginx:latest # 备份多个镜像 docker save -o images-backup.tar nginx:latest mysql:8.0 redis:7-alpine # 恢复 docker load -i nginx-backup.tar-o后面的文件可以任意命名但后缀建议用.tar。如果你用了.tar.gz注意docker save并不会帮你压缩gz后缀只是你手动或者用管道压缩后的结果。想压缩的话可以这样docker save nginx:latest | gzip nginx-backup.tar.gz # 恢复时 gunzip -c nginx-backup.tar.gz | docker load为什么我推荐管道压缩而不是先docker save -o再gzip因为前者不落中间文件省一次磁盘写放大。但对于几十GB的大镜像我建议别省这一步直接先出tar再单独压缩反而更好排查问题因为docker load对损坏的tar包报错信息比较明确而对被截断的gz流报错比较晦涩。还要提一个关键细节docker save保存的是镜像的完整层结构和历史元数据docker load能还原出完全一样的镜像。但docker pull下来的一些元信息如Digest摘要也会保留后期你用docker inspect看RepoDigests属性时能看到。这个特性决定了save/load是“标准备份方式”。2.2 docker export和docker import别看错了和save/load特别容易搞混的还有一对命令docker export和docker import。docker export是把一个容器的文件系统导出成tar包而不是镜像。换句话说它扁平化了镜像层和容器层把当前容器所有文件打在一起。# 将容器mywebserver的文件系统导出 docker export -o mywebserver-fs.tar mywebserver # 从该tar包导入为一个新镜像 docker import mywebserver-fs.tar mywebserver:202401这里有个非常隐蔽的坑docker export导出的文件系统里很多容器运行时的元数据环境变量、工作目录、启动命令、暴露端口会被丢弃。导入后的新镜像的Entrypoint和CMD很可能变成空。你docker run这个导入出来的镜像时得手动加-e、-p、--entrypoint参数非常麻烦。那export/import有什么用我的判断是它适合做“现场取证式”的快照不适合做常规备份。比如一个容器被改得面目全非、镜像却在早期版本时export一下可以把现场文件保留下来。常规重装场景下优先用save/load别用export/import。2.3 为什么还要考虑docker commit有一种特殊情况镜像是从Docker Hub拉的你直接在docker run容器里改了一堆配置比如安装了Vim、修改了Nginx的配置文件然后希望把“这个改好的容器”备份下来。这时候docker commit可以帮你把容器当前状态固化成新镜像再docker save备份。# 在容器内做完修改后提交为新镜像 docker commit mynginx mynginx:with-vim # 再备份 docker save -o mynginx-with-vim.tar mynginx:with-vim不过commit有个老生常谈的问题它不太适合有数据卷的容器因为数据卷里的内容不会进镜像。而且commit出来的镜像体积往往臃肿因为原本属于临时文件、日志文件的内容也被一起打包了。所以我给这个操作的定位是临时固化状态时用重装前的正式备份中它只对“没有卷且需要保留容器内改动”的容器有意义。2.4 备份前必看的Docker环境信息重装系统之前建议先跑一遍以下命令把环境信息收拢到一个文本文件里恢复时能少走很多弯路# 列出所有镜像及大小 docker images --format table {{.Repository}}:{{.Tag}}\t{{.ID}}\t{{.Size}} # 列出所有容器含停止的 docker ps -a # 列出所有数据卷 docker volume ls # 导出容器的完整配置以备重建 docker inspect $(docker ps -aq) /path/to/backup/container-inspect.jsondocker inspect导出的那份JSON很有价值。恢复后你如果要重建容器这份文件里能看到之前用什么镜像、什么端口映射、哪些卷、哪些环境变量。当然最直接的还是用Docker Compose管理容器因为compose文件本身就是最好的配置备份——这点我放到后面第五节讲。3. 实操备份流程从单镜像导出到批量脚本化3.1 单机单个镜像备份假设现在机器上跑了一堆服务我要赶在重装系统前把它备份干净。最简单的是从单个镜像开始docker save -o /backup/nginx-latest.tar nginx:latest ls -lh /backup/nginx-latest.tar这里的一个小动作是备份完毕后建议立刻执行sha256sum生成校验文件防止后面拷贝、复制过程中损坏了tar包却不知道sha256sum /backup/nginx-latest.tar /backup/nginx-latest.tar.sha256恢复的时候先校验一下再docker loadcd /backup echo 校验收到的文件 sha256sum -c nginx-latest.tar.sha256 docker load -i nginx-latest.tar有些人嫌麻烦觉得多此一举但我在系统迁移时真的遇到过U盘拷一半断连、tar文件损坏的情况。没有校验文件你可能在docker load时报一个莫名其妙的archive/tar: invalid tar header就必须重新到处找备份来源了。多一行命令少一次抓狂性价比极高。3.2 全量镜像批量导出与压缩机器上镜像一多一个个docker save显然不现实。这里贴一个我常用的脚本它会把当前机器上所有镜像逐一遍历并保存为独立的tar文件#!/bin/bash # 批量导出所有Docker镜像 # 用法: ./backup-images.sh /path/to/backup/dir BACKUP_DIR${1:-./docker-image-backup} mkdir -p $BACKUP_DIR # 获取镜像列表仓库:标签 docker images --format {{.Repository}}:{{.Tag}} | while read -r image; do # 过滤掉悬空镜像或纯ID列表 if [ $image none:none ]; then echo [跳过悬空镜像] $image continue fi # 将路径中的 / 替换为 _ 避免文件名不合法 safe_name$(echo $image | tr /: __) file_name$BACKUP_DIR/${safe_name}.tar echo 正在导出 $image - $file_name docker save -o $file_name $image done # 生成所有文件的校验信息 echo 生成SHA256校验文件... (cd $BACKUP_DIR sha256sum *.tar checksum.sha256) echo 备份完成文件列表 ls -lh $BACKUP_DIR注意我在脚本里做了一个安全处理镜像名中的斜杠和冒号替换成下划线。因为镜像名可能是registry.example.com/team/app:1.2.3直接当文件名会带/导致目录层级错乱带:在Windows上又会被拒。这个细节不处理脚本在Windows上大概率会炸。如果你希望所有镜像打包成一个文件这样好拷贝但恢复时没办法单选也可以这样docker save $(docker images -q) /backup/all-images.tardocker images -q会输出所有镜像ID注意系统里如果有悬空镜像none这也会被包含进去。恢复时docker load -i all-images.tar会把所有镜像全部导入。跑完批量脚本后我的习惯产物是这样的目录/backup/ ├── nginx_latest.tar ├── mysql_8.0.tar ├── redis_7-alpine.tar ├── my-service_1.0.tar └── checksum.sha2563.3 使用私有Registry进行推送式备份对服务器环境我强烈建议搭建一个本地私有Registry把重要的镜像统一推过去。这样重装后的恢复就是一条docker pull命令的事。搭建方式如下# 启动一个本地registry容器端口5000 docker run -d -p 5000:5000 --restartalways --name registry registry:2然后给镜像打一个私有仓库的标签再推送过去docker tag nginx:latest localhost:5000/nginx:latest docker push localhost:5000/nginx:latest恢复端只需要docker pull localhost:5000/nginx:latest # 如果你不想要带仓库地址的标签可以重新打标签 docker tag localhost:5000/nginx:latest nginx:latest这个方案平时看起来比docker save厚重但它的优势在于仓库天然是集中式、支持多版本管理。如果搭配一个内网存储甚至可以把它当成团队内部镜像源来用。不过要提醒私有仓库的镜像文件存储在你指定的服务器目录里这个目录本身也要纳入备份计划否则服务器挂了镜像一样丢。3.4 数据卷的备份镜像之外的另一半战场还记得前面说的“备份镜像 ≠ 备份数据”吗现在来处理数据卷。Docker数据卷主要有两类。一类是docker volume管理的命名卷另一类是bind mount宿主机目录。备份命名卷最通用的方式是启动一个临时容器把它挂载到卷上然后打包# 假设有一个名为mysql-data的卷需要备份 docker run --rm -v mysql-data:/source -v /backup:/backup alpine tar czf /backup/mysql-data.tar.gz -C /source ./一句话解释这条命令用一个临时alpine容器把mysql-data卷挂到容器的/source同时把宿主机的/backup挂到容器的/backup然后在容器内把/source里的内容压缩到/backup/mysql-data.tar.gz。--rm保证容器用完自动删掉不残留。bind mount目录就更简单了直接压缩宿主机目录即可tar czf /backup/mysql-bind.tar.gz /data/mysql注意bind mount打包前最好先确保容器停了再打包否则数据库文件处于热写状态打出来的包的一致性没有保障。MySQL这类数据库尤其如此。4. 实操恢复流程干净环境重建与验证4.1 新系统安装Docker的关键准备重装好系统后第一件事不是立刻导入镜像而是先装一个能用的Docker环境。如果你之前用的是Docker Desktop记得开启Windows的虚拟机平台选项控制面板 - 启用或关闭Windows功能 - 勾选“虚拟机平台”和“适用于Linux的Windows子系统”然后重启。这一步漏了Docker Desktop会报“Virtualization support not detected”或者“Failed to start because v...这样的错热词里提到了相关错误基本就是虚拟化没开。Linux服务器上没有这个问题直接装docker-ce即可但要注意当前账户是否有权限操作Docker记得把用户加入docker组sudo usermod -aG docker $USER # 重新登录后生效4.2 通过docker load逐个恢复镜像环境就绪后把备份文件拿到新机器上先校验完整性cd /path/to/backup sha256sum -c checksum.sha256校验通过后批量导入镜像# 逐个导入 for f in *.tar; do echo 导入 $f; docker load -i $f; done如果你备份时是导出成一个超大all-images.tar那一条命令搞定docker load -i all-images.tar导入完成后验证一下docker images这一看就能确认镜像是不是都回来了。4.3 从Registry拉取恢复如果使用的是私有仓库方式那就更轻松了先启动registry容器或者直接指向远程仓库地址再从仓库pulldocker pull localhost:5000/nginx:latest docker tag localhost:5000/nginx:latest nginx:latest需要注意一点如果你的私有Registry开启了认证那么恢复服务器上需要先docker login localhost:5000并且这里要手动输入用户名密码。没有配认证的话默认可以匿名拉取这种方便在隔离内网可以用但连着外网就别这么裸奔了。4.4 恢复数据卷并重建容器镜像导入只是第一步要跑起来还得恢复数据卷和容器配置。针对命名卷参考备份时的反向操作# 先创建一个空数据卷 docker volume create mysql-data # 把备份的压缩包解压进卷里 docker run --rm -v mysql-data:/target -v /backup:/backup alpine tar xzf /backup/mysql-data.tar.gz -C /target针对bind mount路径先在宿主机建好目录并解压再重建容器。容器重建有两条路。第一条是直接用docker run命令重建这要求你备份时把docker run的参数都记下来了第二条是之前有docker-compose.yml那直接用compose恢复docker compose up -d我现在强烈建议从第一次部署某个容器开始就用Compose管理因为它的可恢复性比裸docker run好太多。镜像能备份、卷能备份但一条裸docker run命令是不会自动备份的你恢复时全靠回忆当初“-p 8080:80 -e xxxyyy”写了什么——迟早翻车。4.5 恢复后的验证清单镜像和容器都恢复后不要直接就认为万事大吉。我给自己定了一份验证清单每一条都会过一遍容器进程状态docker ps -a看看是不是所有预期的容器都变成Up而不是Exited。端口监听ss -tlnp | grep -E 8080|3306这类命令确认端口映射没被其他进程占掉。业务探活如果是Web服务curl一下本机地址确认能拿到200响应如果是数据库用客户端连一下确认数据都在。日志没有持续报错docker logs --tail 50 container看一眼最近日志防止恢复后容器在疯狂重启。数据卷文件进容器里ls一下相关数据目录或者直接查数据库表确认不是空卷。这套验证流程看起来繁琐但总比重装完一周后才发现某个服务的数据库是空的强。5. 备份恢复中的常见问题与排查技巧实录5.1 Docker Desktop重装后镜像空间丢失如何找回这是Windows用户的高频问题。场景是Docker Desktop某次更新失败或WSL2的docker-desktop发行版异常你wsl --unregister docker-desktop后重装Docker Desktop结果之前拉取的镜像全没了。原因在于Docker Desktop在WSL2中的镜像存储位于docker-desktop发行版里而你unregister了这个发行版存储文件就没了。这类情况救不救得回来取决于有没有提前备份。如果提前做了docker save备份用本文第4节恢复即可如果没有备份可以尝试在WSL2的vhdx文件中做数据恢复但成功率不稳定而且vhdx文件很少能完整恢复出来。所以这里真的要说一句经验之谈Docker Desktop每当你准备升级版本或者系统重装前先把镜像批量导一遍成本远低于事后抢救。5.2 备份tar文件完好但docker load导入时报错docker load -i xxx.tar报错信息五花八门常见的有file does not exist路径写错检查文件名。invalid tar headertar文件损坏先跑sha256sum -c校验如果校验通过仍报错可能是tar包本身不完整或导出时Docker版本跨度过大。Error processing tar file: unexpected EOF同样指向文件不完整重新拷贝或重新导出。no space left on device磁盘空间不足Docker需要把镜像层解压到存储目录空间不够就导入失败。先清理一下旧镜像或日志再导入。这里提醒一下导入新镜像时如果本地已有同名不同ID的镜像docker load会保留原有镜像并加载新镜像可能让docker images里出现两个相同标签但ID不同条目的情况。遇到这种情况用docker tag重新打标签或者直接docker rmi旧ID来清理。5.3 恢复后容器起不来疯狂重启镜像和卷都恢复好之后容器启动仍可能报错。比较典型的几个原因数据卷路径不一致bind mount的宿主机路径和原来不一样容器内进程找不到数据文件比如MySQL起不来报Cant open the mysql.plugin table。检查挂载路径是否准确必要时新建目录并把解压的数据放过去。环境变量缺失很多镜像靠-e MYSQL_ROOT_PASSWORD之类的环境变量初始化恢复时如果忘了写数据库容器可能直接用默认配置启动或者直接启动失败。端口被占用新系统上可能已经有一个服务占用了3306、8080等端口容器起不来就查一下端口冲突。依赖的其他容器还没就绪比如应用容器依赖数据库容器数据库还在初始化时应用就先启动了导致应用退出。这是编排层面的问题最好用Docker Compose管理配合healthcheck来控制启动顺序。排查手法其实很简单docker logs container看报错docker inspect container看挂载和环境变量把这两条命令用熟了大部分问题都能定位。5.4 旧配置“硬编码”在容器里导出镜像时没包含恢复后丢失还有一个高频问题是你在容器里用了一个bind mount挂载了宿主机某个目录备份镜像时只备份了镜像本身却忘了这个目录结果恢复后容器是起来了但配置是空的。这种事情我遇到太多次了。印象最深的是某次跑Grafana所有面板配置都在挂载的宿主机目录下镜像tar包只有程序本体。恢复后Grafana起得飞快但面板全空。所以请一定记住每次备份的产物应该是“镜像tar包 数据卷tar包 配置文件tar包”三件套而不是只有镜像tar包。5.5 备份恢复后的数据一致性检查对于数据库类容器恢复后千万急着把容器设为Up完了就完事要检查一下数据。顺手列几条MySQL登录后执行SHOW DATABASES;看库里表是否齐全。Redisredis-cli DBSIZE看key数量或者对比一下KEYS *里关键的key是否存在。PostgreSQL\l列出数据库\dt看表。文件类服务如Nginxls /usr/share/nginx/html确认静态文件都在。数据完整性的验证不能省尤其是有段时间空窗期的备份备份时数据是什么状态恢复后就要是什么状态别到业务报警了才发现数据不对。6. 进阶从“备份镜像”到“完整恢复工作流”6.1 用Docker Compose管理可复现的容器配置如果说镜像tar包是“可运行的软件”那Compose文件就是“怎么运行这个软件的说明书”。有了Compose文件恢复容器就是一条命令没有Compose文件你得靠docker inspect去逆向推导。一个最小示例# docker-compose.yml services: web: image: nginx:latest ports: - 8080:80 volumes: - ./html:/usr/share/nginx/html db: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: rootpass MYSQL_DATABASE: appdb volumes: - mysql-data:/var/lib/mysql volumes: mysql-data:重装后在新系统上执行docker compose up -d它会自动按Compose文件创建网络、创建卷、拉取或加载镜像如果是load进本地的镜像并启动容器。所以我现在每次部署新服务几乎都是先写Compose文件。备份时把docker-compose.yml和.env文件放进备份目录这件事比写任何脚本都有价值。6.2 随时可用的备份徽章脚本一键备份全部为了方便起见我后来把备份流程整合成了一个“备份徽章”脚本所谓一键备份说的是执行一个脚本后把镜像、数据卷、Compose文件一起处理好。这里贴一个我的实用简化版#!/bin/bash # docker-backup-all.sh # 备份所有镜像 所有命名数据卷 Compose配置 set -e BACKUP_ROOT./docker-backup-$(date %Y%m%d-%H%M%S) mkdir -p $BACKUP_ROOT/images $BACKUP_ROOT/volumes $BACKUP_ROOT/compose # 1. 备份镜像 echo 备份镜像 docker images --format {{.Repository}}:{{.Tag}} | while read -r image; do case $image in none:none) continue ;; esac safe$(echo $image | tr /: __) docker save -o $BACKUP_ROOT/images/${safe}.tar $image done # 2. 备份命名数据卷 echo 备份数据卷 for vol in $(docker volume ls -q); do echo 卷 $vol docker run --rm -v $vol:/source -v $PWD/$BACKUP_ROOT/volumes:/target alpine tar czf /target/${vol}.tar.gz -C /source ./ done # 3. 备份compose文件 echo 备份compose文件 find . -maxdepth 2 -name docker-compose*.yml -o -name docker-compose*.yaml -o -name compose.yaml 2/dev/null | while read -r f; do cp $f $BACKUP_ROOT/compose/ done echo 校验信息生成 (cd $BACKUP_ROOT sha256sum images/*.tar volumes/*.tar.gz checksum.sha256) echo 备份完成$BACKUP_ROOT这个脚本有个偷懒的地方卷备份用了alpine容器每次都会拉取一个很小的alpine镜像内网环境第一次执行时如果连不了外网会卡住。提前docker pull alpine即可或者直接改用宿主机tar命令处理bind mount。6.3 数据卷备份的三条路如何选数据卷备份看起来简单实际上细节很多。我总结三条路命名卷用临时容器打包最通用但需要能跑临时容器对正在运行的容器会有影响吗没有只读取卷文件。推荐。bind mount不用容器直接tar宿主机目录简单直接但必须保证目录没有被容器写入否则热拷贝可能不一致。建议先停容器再备份。数据库类用数据库自带工具MySQL用mysqldump、PostgreSQL用pg_dump先在SQL层面逻辑导出再压缩备份。逻辑备份的好处是可移植性强而且能规避直接复制文件带来的引擎版本兼容问题。我自己对数据库卷一律是“双保险”既用卷整体打包又跑一次逻辑导出。前者图恢复快后者图容量小、兼容性好。恢复时先用逻辑导出文件冷启动一遍确认数据无误后再切到卷整体挂载这样最稳。6.4 跨Docker版本恢复的兼容性心法如果你是从旧版本Docker导出镜像到新版本Docker导入一般都能正常运作毕竟镜像格式向后兼容做得不错。但你如果反向导——新版本导出到就旧版本Docker——可能会遇到镜像架构或OCI规范不兼容问题。举个例子我用Docker Desktop 4.x导出的是OCI布局老版本的Docker如果还停留在旧格式上导入时会报“保留层失败”之类的错误。解决办法是导出前确认目标环境的Docker版本或者干脆在目标环境上用新版Docker再拉一次远程仓库里的镜像。跨版本恢复更稳妥的操作是如果两端都能访问同一个Registry直接用push/pull模式Registry负责格式转换和存储客户端只管拉取兼容问题会少很多。7. 写在最后的个人建议最后分享一条我从重装系统里悟出来的真建议备份不是重装前的“临时操作”而是日常运维的一部分。我现在给自己定了个习惯每个月用那套一键备份脚本全量备一次定期检查备份文件是否能成功恢复。别小看这个动作很多人备份完了从来不验证到了真正要用的时候才发现文件早损坏了。我就在系统迁移前发生过一次拿着备份U盘上原封不动的tar包做恢复演练发现校验值对不上——因为那张U盘本身就已经是劣质存储悄悄丢数据。自此以后每个备份产物生成后的第一时间我一定会sha256sum -c校验一次恢复前再校验一次。校验过的备份才是真正有效的备份。系统重装这件事谁都不希望年年碰到但一旦要面对能提前20分钟做备份恢复时就能少折腾两小时。希望这篇文章能帮你把“丢镜像”从重装的焦虑清单里彻底划掉。如果动手能力强的话还可以把备份脚本挂到cron job或者Windows计划任务里定期自动执行再把备份目录同步到另一块硬盘或NAS上。备份守着两份恢复的时候无论哪一份坏掉情况都不会太糟——这算是我从多次系统迁移里捡到的最大教训了。
返回列表