bigywater.tech
Docker · 22

docker save 的 tar 里有什么:层目录与 manifest.json

没有网络的机器怎么搬镜像?docker save / load 和 docker export / import 名字很像,结果完全不同。这篇实测导出的文件多大、装回来还是不是同一个镜像,以及两个命令各自丢了什么。

4001 KB
两个共用基础层的镜像一起 save,比分别 save 少的体积,约等于 alpine 基础层压缩后的大小
2 层 → 1 层
docker export 再 import 之后,镜像从 2 层变成 1 层
Env、Cmd 丢失
import 出来的镜像没有环境变量和默认命令,直接 run 会报 no command specified

save 导出什么

实测 · 本机执行输出
  docker save 退出码 0,用时 92 ms;tar 大小 4518 KB;docker image inspect 的 Size = 14290 KB
  tar 里共 9 个条目;顶层:['blobs', 'index.json', 'manifest.json', 'oci-layout']
  整个 tar 再 gzip(级别 6)后 4491 KB;压缩比 0.99(层本来就已经是 gzip,随机数据也不可压缩)

docker save 导出的是 OCI 布局的 tar,放的是压缩后的层:这个 2 层镜像是 4518 KB,而 docker image inspect 的 Size(14290 KB)是压缩内容加上解包后的层,不是 tar 的大小。再 gzip 一次没有用(0.99)。

load 装回来

实测 · 本机执行输出
  rmi 之后 docker image inspect 的退出码 1(非 0 说明已经没有)
  docker load 退出码 0,用时 100 ms;输出:Loaded image: bwlab-c17a:latest
  镜像 ID 前后相同吗?True;tag 恢复了吗?True
  运行(MODE 与 f.bin 大小):a 524288

删掉镜像再 docker load -i,镜像 ID、tag、运行结果都和之前一样,约 100 ms。这个镜像很小,大镜像的耗时本文没有测。

多个镜像一起 save

实测 · 本机执行输出
  a.tar 4518 KB + b.tar 4518 KB = 9037 KB;一起 save 的 ab.tar = 5036 KB(差 4001 KB,大约是 alpine 基础层压缩后的大小 4092319 字节 = 3996 KB 吗?True)

两个镜像共用 alpine 基础层:分开存 9037 KB,一起存 5036 KB,差的 4001 KB 与基础层压缩后的大小只差几 KB。要搬运一批相关镜像,放进同一个 tar 更省。

export / import

实测 · 本机执行输出
  docker export(容器的文件系统)退出码 0;tar 大小 9408 KB;523 个条目;含 f.bin 吗?True;含 manifest.json / index.json 吗?False
  docker import 退出码 0
  原镜像:层数 2,Env 含 MODE=a?True,Cmd = ['cat', '/f.bin']
  import 出来的镜像:层数 1,Env = None,Cmd = None
  import 出来的镜像 ID 与原镜像相同吗?False
  直接 docker run import 出来的镜像(没有给命令):退出码 125;docker: Error response from daemon: no command specified

docker export 导出的是容器的文件系统(未压缩的 9408 KB,523 个条目),没有任何镜像元数据。docker import 把它变成一层的新镜像,Env 和 Cmd 都没有了(None),ID 也不同,直接 run 会报 no command specified。需要保留镜像的历史、环境变量和命令时,用 save / load。

分步演示

镜像导出与导入
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Docker Desktop(Engine 29.8.2,容器跑在 Docker Desktop 自带的 Linux 虚拟机里,内核与宿主机的 macOS 不同);镜像为 linux/arm64;需要看虚拟机内部时用特权容器 + nsenter;计时用 time / date +%s%N,数字每次运行会有小幅抖动。镜像在本机构建(--provenance=false --sbom=false),大小来自 os.path.getsize,「f.bin」是 os.urandom 随机数据;docker export 用 docker create 出来的容器;实验后已删除镜像、容器和 tar 文件
    • 没有验证:大镜像的 save / load 耗时、docker save 的 tar 通过管道直接 docker load 到另一台机器、zstd 压缩、docker save 指定平台、多平台镜像的 save、import 时用 --change 恢复 CMD 等元数据
    京ICP备2026067502号-1京公网安备11010502063487号