背景

因为近期服务器到期了,换了一个服务器。原先的服务器也仅仅是弄来随便玩玩的,所以也并没有基于镜像重新生成实例了,但是我原先写的一些项目的数据是存储在基于docker生成的mysql,mongodb,reids等容器中的。因此要进行迁移了。至于一些用的不多的,或者和数据没什么太多关系的我就不迁移了,直接拉取创建就完事了。

过程其实很简单,但是有一个点是很坑的(挂载文件的坑)!!!

命令选择

到底使用export&import 还是 save & load ?

这两者的主要区别是:

类型

作用

作用对象

能否保留存储层数据

导出的内容

主要的应用场景

export & import

用来将container的文件系统进行打包的

container

不可以

一个Linux系统的文件目录

制作基础镜像

save & load

用来将一个或者多个image打包

image(container实际上也可以,但其实际上作用的是container下的image)

可以

一个分层的文件系统(相对于前者比较大,因为多层文件系统中可能有东西是重合的)

打包多个镜像

具体区别可以看这篇文章:👉 docker save与docker export的区别

总结一下docker save和docker export的区别:

  1. docker save保存的是镜像(image),docker export保存的是容器(container);
  2. docker load用来载入镜像包,docker import用来载入容器包,但两者都会恢复为镜像;
  3. docker load不能对载入的镜像重命名,而docker import可以为镜像指定新名称。

我这里只用了save和load命令。



原服务器

定制镜像

由于save&load实际操作的是image,所以导出之前,要先使用commit命令把容器中相对于其底层镜像的修改,提交为一层文件系统,与原有的image结合构成一个新的image。新的image中会包含所有修改的内容。
(ps:这种制作镜像的方式不被提倡,因为这样做会保留一些元数据信息,导致image过大,如果想用于制作一个简洁的镜像,需使用DockerFile的方式定制镜像,这里不做详述)

命令:

docker commit -m "" -a "" 05e95cc69c55 mongodb_codekiller



docker load import docker load import区别_centos


在这个命令中,如果要加上标签的话就是:

docker commit -m "" -a "" 05e95cc69c55 mongodb_codekiller:1.0

通过

docker images

查看镜像



docker load import docker load import区别_mongodb_02



导出镜像

把镜像导出为一个输出文件:

docker save -o mongodb_codekiller mongodb_codekiller

如果有标签的话就是:

docker save -o mongodb_codekiller mongodb_codekiller:1.0



docker load import docker load import区别_docker load import_03


通过:

ls -lha

查看镜像:



docker load import docker load import区别_centos_04



传输镜像

传输镜像的方式有很多,当初在学大数据的时候学了好几种传输方式,用的比较多的还是scp:

scp  mongodb_codekiller   root@blog.codekiller.top:/root/mirror/
命令 要拷贝的文件路径/名称   目的用户@主机:目的路径/名称

在目的服务器上可以看到镜像了:



docker load import docker load import区别_mongodb_05



传输挂载文件(坑)

这里最坑的一点是,说save可以保存存储层的数据,其实也没错,但是nm的挂载文件并不会保存进镜像!



docker load import docker load import区别_mongodb_06


我在迁移mongo的时候,不说是数据了,就是用户都没有创建。所幸我在之后看了一下两个服务器挂载的文件才发现问题,真是坑!

所以我在怀疑到底会不会保存存储层数据呀!?

在我迁移redis的时候,我只挂载了一些配置文件,但是最终发现用户和数据也迁移成功了!

因此这个问题应该仅仅是挂载文件的问题,这里我们解决的方法也很简单!复制过去就是了!

首先看一下我们挂载的文件:

docker inspect mongodb | grep Mounts -A 20



docker load import docker load import区别_服务器_07


文件夹的传输:

scp  -r   /root/mongodb/db/db   root@blog.codekiller.top:/root/mongodb
命令 递归   要拷贝的文件路径/名称   目的用户@主机:目的路径/名称

这里我们在原服务器上的工作完成了!

接下来看看在目的服务器上我们该如何操作!



目的服务器

导入镜像

在目的服务器上,我们已经拥有了传输过来的镜像,与save对应的就是load了:

docker load -i mongodb_codekiller

如果是有标签的记得添上(不然默认就是latest):

docker load -i mongodb_codekiller:1.0

查看镜像:



docker load import docker load import区别_服务器_08



运行容器

使用刚刚导入的镜像,运行为一个容器:

docker run -p 27017:27017 --name mongodb -v $PWD/db:/data/db -d mongodb_codekiller --auth

运行容器的命令不同镜像是有略微不同的,这里只要注意一下挂载的文件就行了。

挂载的文件一定要是我们上面传输过来的文件!

查看容器运行状况:



docker load import docker load import区别_centos_09


这样子基本就没什么问题了。剩下的可以自己去测试确认一下!