Устройство устройства в контейнере Linux?

14

Я пытаюсь использовать устройство цикла внутри контейнера, чтобы смонтировать файл образа:

> sudo losetup /dev/loop0 test.img
losetup: /dev/loop0: failed to set up loop device: No such file or directory

/dev/loop0 на самом деле не существует, и

> sudo mknod /dev/loop0 b 7 0
mknod: ‘/dev/loop0’: Operation not permitted

Как я могу сделать эту работу? Требуется ли контейнеру какое-либо разрешение cgroup, которого у него может не быть?

Йоханнес Эрнст
источник

Ответы:

17

Если вы используете systemd-nspawn, запустите ваш контейнер с --capability=CAP_MKNODключом командной строки. Это позволит вам создавать узлы устройства внутри вашего контейнера. Затем создайте устройство петли, как это:

# mknod /dev/loop0 b 7 0

Помните, что это устройство петли используется совместно с хостом и также вызывается /dev/loop0там. И что теперь возможно получить доступ к хост-устройствам, если вы знаете старшие и младшие номера. Могут быть и другие последствия, о которых я не задумывался. Имейте в виду.

Троэльс Фольке
источник
Кто-нибудь может подтвердить, что --capability=CAP_MKNODвсе еще работает? Для меня это, кажется, не имеет никакого эффекта, я Operation not permittedдаже с этим согласен, как и этот пользователь и этот пользователь .
nh2
2
Я заставил его работать сейчас, но в дополнение к предоставлению --capability=CAP_MKNODмне пришлось установить DeviceAllow=block-loop rwmмодуль systemd-nspawn, чтобы он заработал ( отсюда возникла эта идея ).
nh2
Мне пришлось добавить, --device-cgroup-rule="b 7:* rmw"чтобы docker runразрешить полный доступ к устройствам обратной петли (но нет других, так как нет --privilege). Найден через docs.docker.com/edge/engine/reference/commandline/create/… и протестирован на докере 18.06.1-ce (документ утверждает, что он применим только к Docker Edge)
RobM
9

Петлевые устройства предоставляются модулем ядра. Поэтому вам нужны особые привилегии для доступа к ним. Вам также нужно, чтобы они были выставлены в ваш контейнер, или вам нужно вручную создавать файлы устройства.

Быстрый ответ

docker run --privileged=true ...

Альтернатива

sudo losetup /dev/loop0 test.img
mount /dev/loop0 /mnt
docker run -v /mnt:/mnt ...

Это почти работает

docker run --device=/dev/loop-control:/dev/loop-control --device=/dev/loop0:/dev/loop0 --cap-add SYS_ADMIN ...

Однако я получаю эту ошибку:

root@5c033d5f8625:/# sudo mount /dev/loop0 /mnt
mount: block device /dev/loop0 is write-protected, mounting read-only
mount: cannot mount block device /dev/loop0 read-only

Смотрите эту ссылку для получения дополнительной информации .


Примечание на man-странице systemd-nspawn:

systemd-nspawn ограничивает доступ к различным интерфейсам ядра в контейнере только для чтения, таким как / sys, / proc / sys или / sys / fs / selinux. Сетевые интерфейсы и системные часы не могут быть изменены изнутри контейнера. Узлы устройства не могут быть созданы. Хост-система не может быть перезагружена, и модули ядра не могут быть загружены из контейнера.

Matt
источник