Docker(三)-Docker中Image、Container与Volume的迁移

Image

镜像的迁移,适用于离线环境。docker

通常离线环境,都会自建Docker Registry。 不管 官方的 ,仍是最近流行的 Harbor ,都是不错的选择。 可是,这个世界上就是有些环境,或者说一些环境在某些时期,没有外网,也没有内部的Registry。 这个时候要部署Docker的服务,怎么办?网络

只能经过镜像的迁移。 实际上, Harbor 的offline installer,就是采用这种形式。ssh

Save

# use stdout docker save alpine > /tmp/alpine.tar # or write to a file directly docker save alpine -o /tmp/alpine.tar

推荐使用 -o 的形式,由于利用stdout的作法虽然直观,但在某些场景下无效,好比利用ssh 远程执行命令。spa

Load

# use stdout docker load < /tmp/wekan.tar # or read from a file directly docker load -i /tmp/wekan.tar

Container

容器的迁移,适用于已经上线,且状态复杂、从零开始启动不能正常工做的服务。 容器迁移的包,包含了镜像。插件

Export

先准备一个正在运行的服务,而且弄脏环境。3d

$ docker run --rm -d --name test alpine tail -f /dev/null 9232f0c1dafe0f29918f281ca37bb41914677e818cb6f252abf3dab3be04fbb2 $ docker exec test touch proof $ docker exec test ls -hl proof -rw-r--r-- 1 root root 0 Nov 20 14:33 proof

执行导出操做:rest

docker export test -o test.tar

Import

首先,关闭刚才运行的服务。code

$ docker kill test
test

执行导入操做:blog

$ docker import test.tar test-img sha256:e03727eeba7e16dd3acfcc7536f1244762508f9b6b9856e49cc837c1b7ffa444

要注意的是, import 后获得的是一个镜像,至关因而执行了 docker commit 后的内容。 固然, docker commit 不是一个推荐的操做,因此容器的导入、导出,就显得不是那么的顺眼。部署

最后,检查以前建立的文件。

$ docker run --rm -d --name test test-img tail -f /dev/null ee29cb63bb2d3ed8ac890789ba80c4fe4078b9d5343a8952b6217d64b4dcbe23 $ docker exec test ls -hl proof -rw-r--r-- 1 root root 0 Nov 20 14:33 proof

能够看到,前面建立的文件是存在的,而且时间戳彻底一致。

Volume

数据卷的迁移,比较麻烦。 Docker并未提供官方的简单方案。

固然,直接用 root 用户访问文件系统的Docker数据,好比默认的/var/lib/docker/volumes/ 下的文件夹,直接进行打包操做,也不是不行。 但这毫无疑问是最糟糕的方案。

目前参考《 Use volumes | Docker Documentation 》,找到的最佳方案是,用另外一个容器,把数据卷内容打包,而且经过挂载的形式传递到宿主机。

Backup

首先,准备一个Volume。

$ docker run --rm -d --name test -v test-vol:/data test-img tail -f /dev/null f4ff81f4c31025ff476fbebc2c779a915b43ba5940b5bcc42e3ef9b1379eaeab $ docker exec test touch /data/proof $ docker exec test ls -hl proof -rw-r--r-- 1 root root 0 Nov 20 14:40 proof

执行备份操做:

$ docker run --rm -v test-vol:/volume -v $PWD:/backup alpine tar cvf /backup/backup.tar volume volume/ volume/proof

直接在已运行容器中打包,而后经过 docker cp 复制出来,也是一个方案。 但这会对正在运行的容器有影响,不建议在真正重要的容器中使用。

这里利用了一个 Alpine 镜像来执行操做。 实际上,任何一个自带 tar 的镜像都是能够的。

Restore

首先,清理刚才的容器和数据卷。

$ docker kill test
test
$ docker volume rm test-vol
test-vol

执行还原操做:

docker run --rm -v test-vol:/volume -v $PWD:/backup alpine tar xf /backup/backup.tar

最后,检查还原后的结果。

$ docker run --rm -v test-vol:/data alpine ls -ahl /data total 8 drwxr-xr-x 2 root root 4.0K Nov 20 14:48 . drwxr-xr-x 1 root root 4.0K Nov 20 14:50 .. -rw-r--r-- 1 root root 0 Nov 20 14:40 proof

结论

以上其实都不是常规手段。

Image的传递,更应该依赖于内部Docker Registry而非tar。 (固然,也有例外,好比集群部署大镜像的P2P方案,也许能够借鉴这个手段。)

Container的状态,应该是可弃的。 一个运行了很长时间的Container,应该是能够 restart 、甚至 kill 后再从新 run 也不影响既有功能的。 任何有依赖的状态,都应该考虑持久化、网络化,而不能单纯地保存在本地文件系统中。

Volume的手动迁移,的确能够采用上述方式。 可是,Volume须要手动迁移、备份吗? 这须要专业而完善的插件来实现。

相关文章
相关标签/搜索