返回

Docker镜像导出与导入:Windows到Mac完美迁移

Linux

如何将本地 Docker 镜像导出为 tar 包并在另一台电脑上加载?

你是不是遇到过这样的情况:在 Windows 电脑上构建了一个好用的 Docker 镜像,想把它弄到 Mac 上用,但是直接用 docker save 或者 docker export 命令却总报错? 别急,这篇博客就来帮你解决这个问题。

碰到的问题:

$ docker ps
CONTAINER ID        IMAGE                        COMMAND             CREATED                  STATUS              PORTS
52f36432c9a7        visionai/clouddream:latest   "/bin/bash"         Less than a second ago   Up 3 minutes

想把这个 visionai/clouddream:latest 镜像导出成 tar 包,然后放到 U 盘里,再导入到 Mac 电脑。 尝试了:

$ docker save -o visionai/clouddream clouddream.tar
Error response from daemon: No such image: clouddream.tar

$ docker export visionai/clouddream > clouddream.tar
Error response from daemon: No such container: visionai/clouddream

结果都失败了。

问题原因分析:

犯错的原因其实挺简单,主要是混淆了几个概念,还有命令的用法不太对:

  1. docker save vs. docker export 最主要的区别,docker save 保存的是镜像(image),可以包含多个版本(tag);而 docker export 导出的是容器(container)的文件系统,只能导出当前状态,而且会丢失历史记录和元数据(比如环境变量、启动命令等)。咱们要迁移的是镜像,所以应该用 docker save
  2. docker save 的参数顺序: -o 参数是用来指定输出文件名的,应该放在镜像名称 之前。 正确的语法是 docker save -o <输出文件名> <镜像名>:<标签>
  3. docker export 的对象: docker export 是用来导出 容器 的,不是镜像。而且,应该提供 容器 ID容器名称,不是镜像名称。

解决方案:

搞清楚原因之后,解决方法就很清晰了。 下面一步步教你怎么做:

1. 使用 docker save 保存镜像

正确的命令应该是这样:

docker save -o clouddream.tar visionai/clouddream:latest

或者也可以使用镜像id:

docker images
docker save -o clouddream.tar <image_id>
  • 原理: docker save 会把指定的镜像(包括它的所有层、父镜像、标签等)打包成一个 tar 文件。
  • 解释:
    • -o clouddream.tar: 指定输出文件名为 clouddream.tar。你可以根据自己的喜好修改。
    • visionai/clouddream:latest: 要保存的镜像名称和标签。一定要写全,包括 tag (例子里是 latest)。 如果你不指定 tag,它会默认保存所有 tag 的镜像,文件会比较大。
  • 如果输出没有任何提示符就代表成功.

现在,你的镜像就被保存到了 clouddream.tar 文件里。 把这个文件拷到 U 盘。

2. 在 Mac 上使用 docker load 加载镜像

到了 Mac 电脑,插上 U 盘,打开终端,执行:

docker load -i clouddream.tar
  • 原理: docker load 会从 tar 文件中读取镜像信息,并将其加载到本地 Docker 环境。
  • 解释:
    • -i clouddream.tar: 指定输入的 tar 文件名。

执行完这个命令,镜像就被加载到你的 Mac 上了。你可以用 docker images 命令查看:

docker images

你应该能看到 visionai/clouddream 镜像,而且 tag 是 latest

3. (可选)基于加载的镜像创建容器。

docker run -it visionai/clouddream:latest /bin/bash

创建一个新的 bash.

  • 安全提示: 虽然这个例子没啥安全问题,但平时如果从不可信的来源获取镜像 tar 包,一定要小心! 里面的镜像可能被篡改过,包含恶意代码。

进阶使用技巧

  1. 保存多个镜像: docker save 可以一次保存多个镜像。 比如:

    docker save -o myimages.tar image1:tag1 image2:tag2 image3
    

    注意如果 image3 没有写tag,将包含所有的tag.

  2. 压缩输出文件: 如果镜像很大,可以结合 gzip 命令来压缩输出文件,节省空间:

    docker save visionai/clouddream:latest | gzip > clouddream.tar.gz
    

    加载的时候,相应地用 gunzip 解压:

    gunzip -c clouddream.tar.gz | docker load
    
  3. ** 使用--quiet或者-q使加载镜像的过程更安静。**

docker load中使用, 可以隐藏加载时的细节过程。

 docker load -q -i clouddream.tar
 ```

4. **利用管道的优势。** 

如果你在同一台机器上有两个不同的docker daemon实例(比如测试环境和生成环境),你甚至不需要创建一个临时tar文件就可以做到移动一个镜像.

```bash
docker save image:tag | docker -H tcp://other-docker-host:2375 load

注意这需要配置你的docker客户端可以不用TLS就链接远端的docker daemon, 需要特别小心配置.

小结

总的来说, 操作还是比较简单的。 牢记 docker save 用于镜像,docker export 用于容器, 参数顺序别搞错,就没问题了。