是否可以在 docker 容器内安装 ISO? [关闭]

Posted

技术标签:

【中文标题】是否可以在 docker 容器内安装 ISO? [关闭]【英文标题】:Is it possible to mount an ISO inside a docker container? [closed] 【发布时间】:2014-03-28 12:54:22 【问题描述】:

我正在使用一个 docker 容器(基于官方 centos:6.4 映像)来构建一个 ISO,然后我需要安装并验证它。我无法使用以下方法安装 ISO:

sudo mount -o loop /path/to/iso /mnt

给予:

mount: Could not find any loop device. Maybe this kernel does not know
   about the loop device? (If so, recompile or `modprobe loop'.)

看起来内核编译时没有循环设备支持。是否可以构建支持循环设备的 docker 映像?我找不到任何关于此的信息,但是,查看this thread 似乎这可能是一个持续的话题。

不知道有没有办法绕过这个限制?

【问题讨论】:

我怀疑是内核。看起来您的 docker 容器中没有循环设备。您是否尝试过使用losetup 您好,感谢您的回复。你能给我更多关于你的建议的信息吗? losetup 手册页上的示例表明 /dev 中的循环条目存在,在这种情况下它们不存在(/dev 的内容:console full kmsg mapper null ptmx pts random shm stderr stdin stdout tty tty1 urandom zero)。看起来使用 dmsetup 可能是一种选择,但同样,没有太多关于如何做到这一点的信息。 losetup -f 带给你什么? 和我从 mount 命令得到的一样:losetup: Could not find any loop device. Maybe this kernel does not know about the loop device? (If so, recompile or modprobe loop.) 它在容器外做什么?可能只是容器禁止它。请记住,容器中的内核与外部相同。 【参考方案1】:

我觉得这不是解决我的问题的好方法,但这是我目前所做的,直到一个更理智的想法出现。

我的容器开始进入 bash,我可以从这个 shell 添加循环设备:

# mknod /dev/loop0 -m0660 b 7 0
# mknod /dev/loop1 -m0660 b 7 1
...
# mknod /dev/loop9 -m0660 b 7 9

现在,我有可用的循环设备,所以我可以挂载 ISO。但是,我注意到第一个可用的循环设备是/dev/loop2

bash-4.1# losetup -f
/dev/loop2

这意味着 loop0 和 loop1 已经在使用中,这一点通过以下方式确认:

bash-4.1# losetup -a
/dev/loop0: [fd00]:1978974 (/dev/loop0)
/dev/loop1: [fd00]:1978975 (/dev/loop1)
/dev/loop2: [fd00]:2369514 (/path/to/my/iso)

而且,这就是为什么我认为这个解决方案不好,从容器外部:

12:36:02 $ losetup -a
/dev/loop0: []: (/var/lib/docker/devicemapper/devicemapper/data)
/dev/loop1: []: (/var/lib/docker/devicemapper/devicemapper/metadata)
/dev/loop2: []: (/path/to/my/iso)

所以看起来我在容器中创建的前 2 个循环设备映射到容器外部的 loop0 和 loop1,这就是它们无法使用的原因。我想一定有一种方法可以使用 devicemapper 设置这些设备(从外观上看,docker 正在使用它),但我无法找到很多关于此的信息。

目前,这个解决方案对我来说没问题 - 我只需要小心记住在我完成后将图像发送到umount

我知道这远非理智的解决方案,所以如果其他人能提出更好的计划,我会全力以赴。

【讨论】:

我今天就是这样实现的。找不到任何其他好的解决方案。主要问题是与主机共享循环设备。我们应该注意这种行为。 太棒了!!!当我遇到您的解决方案时,我已经对failed to setup loop device for /images/foo.img 进行了一个多小时的故障排除。按照您的描述手动创建了一些循环设备,并且 BOOM! 像冠军一样工作!【参考方案2】:

要将 ISO 挂载到容器中,您需要做两件事:

访问循环设备, 挂载文件系统的权限。

默认情况下,Docker 会锁定这两个东西;这就是您收到该错误消息的原因。

最简单的解决方案是以特权模式启动容器:

docker run --privileged ...

更细粒度的解决方案是深入了解设备 cgroup 和容器功能以提供所需的权限。

请注意,您不能将特权操作作为 Dockerfile 的一部分执行;即,如果您需要将该 ISO 挂载到 Dockerfile 中,您将无法执行此操作。

但是,我建议您查看Xorriso,特别是osirrox 工具,它可以让您像提取tar 文件一样从ISO 映像中提取文件,而无需任何特殊访问,例如:

osirrox -indev /path/to/iso -extract / /full-iso-contents

【讨论】:

来回环,留下osirrox。谢谢! 如果-indev iso 文件不存在,这样使用osirrox 不会产生错误。似乎是设计使然? -dev如果没有 ISO 映像,则创建一个空白。-indev设置输入驱动器并加载 ISO 映像(如果存在)。适用与 -dev 相同的规则和限制。

以上是关于是否可以在 docker 容器内安装 ISO? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在具有高山风味的 docker 容器内构建 AOSP?

在 Docker 容器内开发时启用 VS Code IntelliSense

是否可以在 docker 容器内使用“externalbrowser”身份验证器与 Snowflake 进行连接身份验证?

为啥docker容器内无法启动tomcat,容器外可以

Docker安装

虚拟化技术—docker容器—安装篇