Возможно ли установить ISO внутри контейнера докеров?

Я использую контейнер-докер (на основе официального изображения 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'.)

Похоже, что ядро ​​было скомпилировано без поддержки устройства loop. Можно ли строить изображения докеров, которые поддерживают устройства loop? Я не мог найти никакой информации об этом, однако, глядя на этот поток, кажется, что это может быть продолжающаяся тема.

Интересно, есть ли способ обойти это ограничение?

Ответ 1

Чтобы смонтировать ISO внутри контейнера, вам нужны две вещи:

  • доступ к петлевым устройствам,
  • разрешение на монтирование файловых систем.

По умолчанию Docker блокирует обе вещи; вот почему вы получаете это сообщение об ошибке.

Самое простое решение - запустить контейнер в привилегированном режиме:

docker run --privileged ...

Более детальное решение состоит в том, чтобы погрузиться в возможности cgroup и контейнера устройств, чтобы получить необходимые разрешения.

Обратите внимание, что вы не можете выполнять привилегированные операции как часть Dockerfile; то есть, если вам нужно смонтировать этот ISO в Dockerfile, вы не сможете это сделать.

Тем не менее, я рекомендую вам взглянуть на Xorriso и, в частности, на инструмент osirrox, который позволяет извлекать файлы из образов ISO точно так же, как вы извлекаете файл tar, не требуя какого-либо специального доступа, например:

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

Ответ 2

У меня такое чувство, что это не очень хороший способ решить мою проблему, но это то, что я сделал пока, пока не появится более разумная идея.

Мой контейнер начинается с bash, из этой оболочки я могу добавлять устройства цикла, используя:

# 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 (который используется докером, по внешнему виду), но я не смог получить много информации об этом.

Пока что это решение будет хорошо для меня - я просто должен быть осторожным, чтобы помнить umount изображение, когда я закончил с ним.

Я знаю, что это далеко не разумное решение, поэтому, если кто-то еще может придумать лучший план, я все уши.

Ответ 3

Я сомневаюсь в этом ядре. Это больше похоже на то, что в вашем контейнере-докере нет встроенных устройств. Пробовали ли вы использовать losetup?