这是一个非常常见的需求,尤其是在从 Docker 过渡到 Podman 或者两者混合使用的环境中。你完全可以利用已经在 Docker 中下载好的本地镜像,而无需为 Podman 重新下载一遍,这能节省大量的时间和带宽。
实现这个目标主要有两种方法:导出/导入 和 共享存储。
方法一:导出为 Tar 包,再导入 Podman (最通用、最推荐)
这个方法就像打包和解包,它不依赖于 Docker 和 Podman 的底层存储结构,因此兼容性最好,适用于任何系统。
步骤:
-
在 Docker 中保存镜像为 Tar 文件: 首先,找到你想要迁移的 Docker 镜像的名称和标签 (TAG)。你可以用
docker images查看。# 语法: docker save -o <输出文件名.tar> <镜像名:标签> # 示例: docker save -o gitlab-ce.tar docker.io/gitlab/gitlab-ce:18.8.0-ce.0执行后,你会在当前目录下得到一个名为
gitlab-ce.tar的文件。 -
在 Podman 中加载这个 Tar 文件: 现在,使用
podman load命令将这个文件导入到 Podman 的本地存储中。# 语法: podman load -i <文件名.tar> # 示例: podman load -i gitlab-ce.tar -
验证镜像是否导入成功: 使用
podman images命令检查镜像是否已经存在于 Podman 的列表中。podman images你应该能看到
docker.io/gitlab/gitlab-ce这个镜像。
优点:
- 100% 可靠: 这种方法与底层存储驱动无关,总是有效。
- 可移植: 生成的
.tar文件可以被复制到任何其他安装了 Podman 或 Docker 的机器上使用。 - 干净隔离: 两个工具的存储保持独立,互不影响。
缺点:
- 需要额外的磁盘空间: 在导出和导入的过程中,你需要临时占用一份镜像大小的磁盘空间来存放
.tar文件。 - 手动操作: 对于每个需要迁移的镜像,都需要执行一次
save和load。
方法二:共享 Docker 的存储 (仅限特定情况)
警告: 这个方法有风险,只建议在临时测试或特定高级场景下使用。它可能会因为 Docker 和 Podman 版本更新导致存储驱动不兼容而损坏你的镜像存储。对于生产环境或重要数据,强烈不推荐此方法。
这个方法的思路是告诉 Podman 直接去读取 Docker 的镜像存储目录。
步骤 (以 Linux 为例):
-
找到 Docker 的存储目录: Docker 的数据通常存储在
/var/lib/docker。 -
修改 Podman 的存储配置: 你需要用
sudo权限编辑 Podman 的存储配置文件/etc/containers/storage.conf。sudo nano /etc/containers/storage.conf -
修改
graphroot和driver:- 找到
driver这一行,确保它和 Docker 使用的存储驱动一致 (通常是overlay)。 - 找到
graphroot这一行,这是镜像存储的根目录。把它修改为 Docker 的目录。 - 在修改前,请务必备份原始的
storage.conf文件!
# /etc/containers/storage.conf [storage] driver = "overlay" # 将 graphroot 指向 Docker 的存储位置 graphroot = "/var/lib/docker/overlay2" # 注意:路径可能是 overlay2 [storage.options] # ... 其他选项注意: Docker 的实际镜像数据可能在
/var/lib/docker/overlay2或其他子目录,你需要先确认。 - 找到
-
重启 Podman 相关进程 (如果需要) 或直接使用。
为什么不推荐这个方法?
- 风险极高: Docker 和 Podman 可能同时或交替地操作同一个存储目录,这很容易导致元数据损坏,使你的所有镜像(包括 Docker 的和 Podman 的)都无法使用。
- 版本依赖: Docker 或 Podman 的任何一次小版本更新都可能改变存储格式,导致不兼容。
- 权限问题:
/var/lib/docker目录通常由root用户拥有,这使得 rootless Podman 无法使用这种方法。
结论
对于你的情况,请使用方法一(导出/导入)。
假设你之前在 Docker 中已经成功下载了 gitlab/gitlab-ce:18.8.0-ce.0,你只需要执行以下两步,就可以让 Podman 用上它,而无需再次从网络下载:
# 1. 从 Docker 导出
docker save -o gitlab.tar docker.io/gitlab/gitlab-ce:18.8.0-ce.0
# 2. 导入到 Podman
podman load -i gitlab.tar
# 3. 现在可以正常使用 podman-compose 了
podman-compose -f compose.yml up
这样,当 podman-compose 尝试创建容器时,podman 会在本地找到这个已经导入的镜像,直接使用,从而跳过漫长的下载过程。
接下来,我们可以探讨以下相关主题:
- 如何编写一个简单的脚本来批量迁移多个 Docker 镜像到 Podman?
- Podman 和 Docker 在镜像分层 (layers) 的共享机制上有什么异同?
- 在没有 Docker 的情况下,如何使用
skopeo或buildah工具来直接操作和转换镜像?