我们正在开发一款应用程序,该应用程序将在现场部署到各种安装(而不是云)。我们的 OEM 合作伙伴要求我们为他们提供 ISO,以便能够快速配置新服务器。我们的应用程序是围绕容器构建的,我们有一个面向互联网的私人注册表设置,以便能够提取最新的通过版本。我还不确定 OEM 合作伙伴是否能够自己提取这些图像,因此我们正在研究预先打包 docker 图像和 ISO 的可能性,但遇到了一些困难。我们尝试过以下方法:
系统备份- 我们尝试使用我们首选的设置(由我们拥有的 ansible 角色定义)配置全新的 ubuntu 安装,然后使用 systemback 捕获结果。重新安装生成的 ISO 后,我们遇到了 docker 错误:
Error response from daemon: open /var/lib/docker/aufs/layers/blahblahblah: no such file or directory
类似于#22343chroot 监狱- 再次,我们尝试创建用户,安装 docker,但在尝试拉取镜像时,我们得到的提示是:
failed to register layer: Error processing tar file(exit status 1): invalid argument
无论我们拉取什么镜像(例如,即使是官方的 docker ubuntu 镜像)。Google 无法解决此错误。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
/ Before
,PartOf
等等)。
总的来说,我认为我不会花太多时间担心只加载/构建一次 - 特别是如果你要构建镜像(而不是加载它们),这将允许你通过更新其本地 Dockerfile 来更新容器。如果你的注册表不可用,这可能是一个有用的功能。
答案3
您可以通过预安装/var/lib/docker
树来实现这一点。此目录包含 Docker 环境中存在的所有图像、容器等,因此您需要从一个干净的目录开始创建/var/lib/docker
仅包含所需图像等的目录。当 Docker 启动时,它将使用已预安装图像的现有目录结构。