主页
文章
分类
标签
关于
docker镜像的导出与导入
发布于: 2025-2-2   更新于: 2025-2-2   收录于: docker
文章字数: 1870   阅读时间: 4 分钟   阅读量:

前言

学习镜像的导入与导出主要有两个原因:

  • 将自己搭建好的镜像移植到别的机器。
  • 机器处于无网络环境,无法从网上下载镜像。

在Docker中,实现镜像导出与导入主要涉及 export\importsave\load 这两组命令 (这两组命令千万千万不要混用

docker exportdocker import

docker export

docker export 命令用于将一个运行中的容器导出为一个 tar 归档文件。这个归档文件包含了容器在导出时的文件系统快照,但不包含镜像的历史信息和元数据。

语法格式:

1
docker export [OPTIONS] CONTAINER容器ID  > [归档文件名.tar]

先查看当前的容器情况:

1
docker ps -a

例如,我们有一个正在运行的容器 my_container,想要将其导出为 my_container_export.tar 文件,可以执行以下命令:

1
docker export my_container > my_container_export.tar

docker import

docker import 命令用于从一个 tar 归档文件创建一个新的镜像。这个命令会将 export 导出的文件系统快照重新构建为一个镜像。

语法格式:

1
docker import [OPTIONS] [归档文件路径|URL] [镜像名[:标签]]

例如,我们将刚才导出的 my_container_export.tar 文件导入为一个新的镜像 my_new_image:v1

1
docker import my_container_export.tar my_new_image:v1

注意事项

  1. 镜像历史信息:由于 export 导出的文件不包含镜像历史信息,所以使用 import 导入后生成的镜像层数会变为一层,这可能会影响镜像的可维护性和大小。例如,如果原镜像有多个构建步骤,经过 exportimport 后,这些步骤将不可追溯。
  2. 容器状态export 操作基于容器当前的状态,因此在导出前确保容器内的应用和数据是你期望的状态。如果容器内有正在运行的进程,导出时这些进程可能会被冻结,以保证数据一致性。

docker savedocker load

docker save

docker save 命令用于将一个或多个镜像保存为一个 tar 归档文件。与 export 不同,save 会保留镜像的所有历史信息和元数据。

语法格式:

1
docker save [OPTIONS] IMAGE [IMAGE...] > [归档文件名.tar]

例如,要保存 ubuntu:latest 镜像为 ubuntu_save.tar 文件:

1
docker save ubuntu:latest > ubuntu_save.tar

如果要保存多个镜像,可以在命令后依次列出镜像名:

1
docker save ubuntu:latest nginx:latest > multi_images_save.tar

docker load

docker load 命令用于从 save 生成的 tar 归档文件中加载镜像。

语法格式:

1
docker load [OPTIONS] < [归档文件名.tar]

例如,加载刚才保存的 ubuntu_save.tar 文件:

1
docker load < ubuntu_save.tar

注意事项

  1. 镜像大小:由于 save 保留了镜像的历史信息,生成的归档文件通常会比 export 生成的文件大,因为它包含了更多的元数据和镜像构建历史。
  2. 网络环境:在无网络环境下,saveload 是在不同机器间迁移镜像的有效方式。但要注意目标机器上的Docker版本是否与源机器兼容,以确保镜像能够正确加载。

export/importsave/load 的对比

直接区别

  • export:从容器中生成tar文件,不支持将多个镜像打包到一个文件

  • save:从镜像中生成tar文件,支持将多个镜像打包到一个文件

  • import:可以为镜像指定新名称

  • load:不能对载入的镜像重命名

使用场景

  • export/import:适用于对镜像历史信息不关心,只需要容器当前文件系统状态的场景,比如快速迁移一个运行中的容器状态到其他机器。例如,在开发测试环境中,快速复制一个已配置好的容器环境。
  • save/load:更适合需要完整保留镜像构建历史和元数据的场景,比如在生产环境中迁移镜像,确保镜像的完整性和可追溯性,或者是要部署的客户服务器并不能连外网,用自己的可联网的电脑下载镜像,然后导出。

镜像特性

  • 镜像层数export/import 会使镜像层数变为一层,而 save/load 保留原镜像的层数结构。
  • 镜像大小:一般情况下,save 生成的归档文件大于 export 生成的文件,因为 save 包含更多信息。

问题

invalid tar header

在使用load导入镜像时出错:archive/tar: invalid tar header

  • 问题环境:我的镜像是从win11下的wsldocker save的,而要load的机器为ubuntu22.04server

  • 问题原因:我打开运行save命令时,使用的是win11的powershell,而powershell有个问题,Powershell 向 标准输出STDOUT 发出两个字节字符,而不是一个字节字符。如果你查看该文件,你会注意到 TAR 头文件在应该是正确的头文件之间(和文件的其余部分)之间有 null。这解释了为什么文件大小是原来的两倍。比如我要saveMysql的镜像,原本只有500M,但是save之后却1000MB。当你把tar文件传过去load,就会出现这个问题。

  • 解决方法

    • 不使用powershell,而去使用CMD(命令提示符),这样不会出现上述问题。CMD 不会向 STDOUT 发出多字节字符。如果在 Windows 上使用 CMD,保存文件的 STDOUT 方法在不同的作系统上都能正常工作。
    • 替换><来导出和导入镜像,docker save的-o选项和docker load的-i 选项选项可以直接指定输入和输出文件,避免使用标准输入输出流,从而绕过 PowerShell 的字符编码问题.
      1
      2
      3
      4
      
      # 导出镜像
      docker save [image] -o file.tar
      # 导入镜像
      docker load [image] -i file.tar
      
  • 参考