没有网络的机器怎么搬镜像?docker save / load 和 docker export / import 名字很像,结果完全不同。这篇实测导出的文件多大、装回来还是不是同一个镜像,以及两个命令各自丢了什么。
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)。
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。这个镜像很小,大镜像的耗时本文没有测。
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 更省。
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。