docker export / docker import 与 docker save / docker load 的区别
在 Docker 中,这两对命令(export/import 和 save/load``)看起来非常相似,都是用来将 Docker 镜像或容器保存为本地的 tar` 归档文件,并用于在不同机器之间迁移。
但它们的核心设计理念、操作对象和底层实现有着本质的区别。
以下是详细的对比分析:
一、 快速对比表
| 特性 | docker export / import |
docker save / load |
|---|---|---|
| 操作对象 | 容器 (Container) (正在运行或已停止) | 镜像 (Image) |
| 是否保留历史/层 (Layers) | 否 (丢弃所有历史和元数据,合并为一层) | 是 (保留完整的历史、分层和元数据) |
| 文件大小 | 通常较小 (因为去掉了历史层) | 通常较大 (包含所有历史层和元数据) |
| 解压后的状态 | 成为一个新镜像,丢失原有的 ENTRYPOINT、CMD、ENV 等设置 |
恢复为原镜像,保留所有设置 (如 ENTRYPOINT、VOLUME 等) |
| 适用场景 | 制作基础镜像、瘦身镜像、快速导出容器文件系统 | 镜像备份、在无网环境中迁移完整镜像(含版本历史) |
二、 详细区别解析
1. 操作对象的不同
export/import面向“容器”:- 你导出的是一个容器的当前状态(文件系统快照)。
- 命令:
docker export <container_id> > my_container.tar
save/load面向“镜像”:- 你备份的是一个完整的镜像(包含它所有的历史层)。
- 命令:
docker save <image_name> > my_image.tar
2. 镜像层(Layers)与历史记录
export/import(扁平化 Flat):export会将容器的文件系统“拍扁”。它会丢弃所有的历史提交记录(docker history)和镜像分层信息,将所有文件合并成一个单一的层。- 当你用
import导入时,它会变成一个全新的、只有一层的镜像。
save/load(完整保留):save会完整保留镜像的每一个分层(Layers)以及所有的元数据。- 当你用
load导入时,你可以通过docker history看到该镜像完整的构建历史。
3. 元数据(Metadata)的丢失与保留
export/import会丢失元数据:- 导出的 tar 包里只有文件,没有 Docker 的配置信息(如
ENV环境变量、EXPOSE端口、ENTRYPOINT启动命令、VOLUME挂载点等)。 - 注意:使用
docker import导入时,默认是没有启动命令的。你必须在导入时手动指定,或者在写Dockerfile时重新指定,否则镜像无法直接运行。- 示例:
docker import --change "ENV PATH /usr/local/bin:$PATH" my_container.tar my_new_image:latest
- 示例:
- 导出的 tar 包里只有文件,没有 Docker 的配置信息(如
save/load完美保留元数据:- 导入后,镜像的所有默认配置(启动命令、环境变量等)与原镜像一模一样,可以直接
docker run运行。
- 导入后,镜像的所有默认配置(启动命令、环境变量等)与原镜像一模一样,可以直接
三、 常用命令示例
1. 使用 export / import(容器 ➡️ 镜像)
bash
# 1. 将正在运行的容器导出为 tar 包
docker export my_running_container > ubuntu_flat.tar
# 2. 将 tar 包导入为一个新镜像(注意:需要指定镜像名和标签)
docker import ubuntu_flat.tar my_new_ubuntu:v1
# 3. (可选) 导入时重写启动命令
docker import --change "CMD ['/bin/bash']" ubuntu_flat.tar my_new_ubuntu:v1
2. 使用 save / load(镜像 ➡️ 镜像)
bash
# 1. 将本地镜像保存为 tar 包
docker save my_image:latest > my_image.tar
# 或者保存多个镜像到一个包
docker save -o images.tar ubuntu:latest alpine:latest
# 2. 在另一台机器上加载该镜像(会自动识别原有的镜像名和标签)
docker load < my_image.tar
四、 总结:我该用哪一个?
选择
save/load的场景(最常用):- 你需要在不同的服务器之间完整迁移一个服务,且希望保留它的所有配置(如
ENTRYPOINT)。 - 你在离线环境中部署软件,需要确保镜像的完整性和一致性。
- 你需要在不同的服务器之间完整迁移一个服务,且希望保留它的所有配置(如
选择
export/import的场景:- 你想“瘦身”镜像。如果一个镜像经过多次修改变得非常臃肿,你可以运行它,然后
export出来再import,这样历史脏数据就会被清理掉,镜像体积会变小。 - 你想导出一个容器里的文件系统,作为其他系统的根文件系统(Rootfs),或者作为定制基础镜像的起点。
- 你想“瘦身”镜像。如果一个镜像经过多次修改变得非常臃肿,你可以运行它,然后