docker容器和数据据迁移

[TOC]

数据存储

官方建议,进行数据迁移的容器最好使用volume。这是因为volume完全由Docker管理,迁移更为便捷。而bind mounts依赖于宿主机的文件系统结构,迁移时可能会引发兼容性问题。更多关于volume的迁移信息,可以参考官方文档

Volumes are the preferred mechanism for persisting data generated by and used by Docker containers. While bind mounts are dependent on the directory structure and OS of the host machine, volumes are completely managed by Docker. Volumes have several advantages over bind mounts:

Volumes are easier to back up or migrate than bind mounts. You can manage volumes using Docker CLI commands or the Docker API. Volumes work on both Linux and Windows containers. Volumes can be more safely shared among multiple containers. Volume drivers let you store volumes on remote hosts or cloud providers, encrypt the contents of volumes, or add other functionality. New volumes can have their content pre-populated by a container. Volumes on Docker Desktop have much higher performance than bind mounts from Mac and Windows hosts.

以下是官方文档中的备份与恢复数据的示例代码:

  • 备份数据:将目标volume的数据打包到宿主机的bind mounts目录下的当前路径($(pwd))。
    docker run --rm --volumes-from dbstore -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
    
  • 还原数据:将宿主机的bind mounts目录中的备份包解压到目标volume中。
    docker run --rm --volumes-from dbstore2 -v $(pwd):/backup ubuntu bash -c "cd /dbdata && tar xvf /backup/backup.tar --strip 1"
    

    这里使用临时的ubuntu容器是为了使用tar命令来打包和解包数据。事实上,我们可以选择体积更小的alpine镜像,因为它的包体更小

注:我最初并不理解这段代码的意义,通过查阅大量资料了解了volume和bind mounts的区别以及docker run的参数选项后,才明白其用意。

为什么Docker不提供一个直接导出数据的简单命令???

容器迁移

大体上有两种迁移容器的方法:

  1. 使用docker commit将镜像提交到Docker Hub。
  2. 将镜像导出到本地文件,然后拷贝到目标设备进行导入。

由于一些工作环境可能无法访问Docker Hub(如网络限制等原因),这里主要讨论第二种方法。

Docker 提供了两种导出/导入的方法:

  1. export/import
  2. save/load

应该使用哪种方法? 你可能已经注意到它们的参数说明:

amao@amao:~$ sudo docker export --help
Usage:  docker export [OPTIONS] CONTAINER
Export a container's filesystem as a tar archive
amao@amao:~$ sudo docker save --help
Usage:  docker save [OPTIONS] IMAGE [IMAGE...]
Save one or more images to a tar archive (streamed to STDOUT by defaul

export:a container’s filesystem as a tar archive save:one or more images to a tar archive (streamed to STDOUT by defaul

要理解这两句话需要先了解一下docker镜像分层和文件系统管理相关的技术知识,比如参考一下这篇Docker 进阶之镜像分层详解

我个人的理解:

  • export 导导出的是容器的合并文件系统,不包含Docker的元数据和配置。因此,导出的文件无法直接还原为Docker镜像,但可以用于非Docker环境中的数据恢复或二次开发。
  • save 导出所有相关的镜像层、文件系统和Docker的配置。

所以,在绝大多数情况下,迁移时使用save/load更为合适,但缺点是生成的包体积较大。Docker有一些方法可以减少包体大小,但这是另一个话题了。

提示:我还在研究export/import的具体使用场景,未来可能会更新这部分内容。

迁移样例工程

示例项目地址: https://github.com/lizijie/restore_docker_container_example

该项目展示了如何通过本地导出和导入的方法迁移Jenkins容器,以下是一些需要注意的地方:

  1. 根据需要重新编写Dockerfile。
  2. conf文件定义了脚本中使用的环境变量。如果你也在进行Jenkins迁移,只需重新定义这些变量即可。
  3. 官方文档中使用ubuntu来打包和解包操作,示例中使用了体积更小的alpine镜像。
  4. 官方文档使用–volumes-from来挂载指定容器的volume。虽然这种方法有效,但不够直观。你可以参考其他方式,直接挂载指定名称的volume来操作。

原文:
https://lizijie.github.io/2024/08/27/docker%E5%AE%B9%E5%99%A8%E5%92%8C%E6%95%B0%E6%8D%AE%E6%8D%AE%E8%BF%81%E7%A7%BB.html
作者github:
https://github.com/lizijie

PREVIOUSlocust游戏压测示例
NEXTgit打标签脚本