是否可以在docker容器中安装ISO?

时间:2014-02-25 23:50:37

标签: linux mount centos6 docker

我正在使用一个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这似乎是一个持续的主题。

我想知道是否有办法规避这种限制?

2 个答案:

答案 0 :(得分:24)

要在容器中安装ISO,您需要做两件事:

  • 访问循环设备,
  • 安装文件系统的权限。

默认情况下,Docker会锁定这两件事;这就是你收到错误信息的原因。

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

docker run --privileged ...

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

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

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

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

答案 1 :(得分:6)

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

我的容器开始变成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图像。

我知道这远不是一个理智的解决方案,所以如果其他人能够提出更好的计划我都会听到。