使用 ISO 预加载 Docker 镜像以便重新分发

使用 ISO 预加载 Docker 镜像以便重新分发

我们正在开发一款应用程序,该应用程序将在现场部署到各种安装(而不是云)。我们的 OEM 合作伙伴要求我们为他们提供 ISO,以便能够快速配置新服务器。我们的应用程序是围绕容器构建的,我们有一个面向互联网的私人注册表设置,以便能够提取最新的通过版本。我还不确定 OEM 合作伙伴是否能够自己提取这些图像,因此我们正在研究预先打包 docker 图像和 ISO 的可能性,但遇到了一些困难。我们尝试过以下方法:

  1. 系统备份- 我们尝试使用我们首选的设置(由我们拥有的 ansible 角色定义)配置全新的 ubuntu 安装,然后使用 systemback 捕获结果。重新安装生成的 ISO 后,我们遇到了 docker 错误:Error response from daemon: open /var/lib/docker/aufs/layers/blahblahblah: no such file or directory类似于#22343

  2. chroot 监狱- 再次,我们尝试创建用户,安装 docker,但在尝试拉取镜像时,我们得到的提示是:failed to register layer: Error processing tar file(exit status 1): invalid argument无论我们拉取什么镜像(例如,即使是官方的 docker ubuntu 镜像)。Google 无法解决此错误。

  3. RancherOS- 在这里我们找到了说明预打包 docker 镜像但不知道如何将它们与 iso 捆绑在一起。看起来我们的用例与第 1449 章但没有真正的解决方案。

现在我能想到的下一步尝试就是将docker save我们的图像和 tarball 包含在 ISO 中,然后在第一次启动 iso 时运行一个脚本来检查 docker 图像是否存在,如果不存在,则docker load对每个图像执行一次,然后运行它们,虽然这看起来非常不可靠,所以我想知道是否有人有这方面的经验,并且可以给我指出正确的方向。

答案1

Docker 保存/加载正是我在这里要做的。

直接预填充 /var/lib/docker(无论是通过软件包安装还是从 CD/DVD 复制)似乎非常不方便。而且它还依赖于您使用的存储引擎。

Docker 自己的保存/加载是 Docker 将图像放入和取出本地图像缓存的方式,并且完全不受 Docker 安装使用的存储引擎的影响。

答案2

@迈克尔·汉普顿的回答对我来说似乎是正确的。

我建议您将相关的 systemd 脚本打包到您的 ISO 中,并让这些脚本处理加载或构建您的图像。

因此,对于 nginx 容器来说,你的单元文件可能看起来像这样:

[Unit]
Description=nginx
After=docker.service
Requires=docker.service


[Service]
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker kill nginx
ExecStartPre=-/usr/bin/docker rm nginx
ExecStartPre=-/usr/bin/docker load /path/to/compressed/image
ExecStart=/usr/bin/docker run --rm [your config here]

如果您更喜欢构建而不是加载,那么您也可以这样做,方法是替换:

ExecStartPre=-/usr/bin/docker load /path/to/compressed/image

和:

ExecStartPre=-/usr/bin/docker build --rm -t 'my-nginx:latest' /path/to/folder_with_Dockerfile

您还可以使用 systemd 依赖项来确保以正确的顺序启动,和/或将容器链接在一起(例如,参见 systemd 的After/ BeforePartOf等等)。

总的来说,我认为我不会花太多时间担心只加载/构建一次 - 特别是如果你要构建镜像(而不是加载它们),这将允许你通过更新其本地 Dockerfile 来更新容器。如果你的注册表不可用,这可能是一个有用的功能。

答案3

您可以通过预安装/var/lib/docker树来实现这一点。此目录包含 Docker 环境中存在的所有图像、容器等,因此您需要从一个干净的目录开始创建/var/lib/docker仅包含所需图像等的目录。当 Docker 启动时,它将使用已预安装图像的现有目录结构。

相关内容