Подтвердить что ты не робот

Docker - способ дать доступ к хосту USB или последовательному устройству?

В прошлый раз, когда я проверял, у Docker не было никаких средств, чтобы предоставить контейнеру доступ к последовательному порту хоста или порту USB. Есть ли хитрость, которая позволяет это сделать?

4b9b3361

Ответ 1

Есть несколько вариантов. Вы можете использовать флаг --device, который можно использовать для доступа к USB-устройствам без режима --privileged:

docker run -t -i --device=/dev/ttyUSB0 ubuntu bash

В качестве альтернативы, если ваше USB-устройство доступно с работающими драйверами и т.д. на хосте в /dev/bus/usb, вы можете подключить его в контейнере, используя привилегированный режим и параметр томов. Например:

docker run -t -i --privileged -v /dev/bus/usb:/dev/bus/usb ubuntu bash

Обратите внимание, что, как следует из названия, --privileged небезопасен , и с ним следует обращаться осторожно.

Ответ 2

В текущих версиях Docker вы можете использовать флаг --device для достижения того, чего вы хотите, без необходимости предоставлять доступ ко всем USB-устройствам.

Например, если вы хотите сделать доступным только /dev/ttyUSB0 в вашем контейнере Docker, вы можете сделать что-то вроде:

docker run -t -i --device=/dev/ttyUSB0 ubuntu bash

Ответ 3

Я хотел бы расширить уже предоставленные ответы, чтобы включить поддержку динамически подключенных устройств, которые не перехватываются с /dev/bus/usb и как заставить это работать при использовании хоста Windows вместе с виртуальной машиной boot2docker.

Если вы работаете с Windows, вам нужно добавить все правила USB для устройств, к которым вы хотите, чтобы Docker имел доступ в диспетчере VirtualBox. Для этого вы можете остановить виртуальную машину, запустив:

host:~$ docker-machine stop default

Откройте VirtualBox Manager и добавьте поддержку USB с фильтрами по мере необходимости.

Запустите boot2docker VM:

host:~$ docker-machine start default

Поскольку устройства USB подключены к виртуальной машине boot2docker, команды необходимо запускать с этого компьютера. Откройте терминал с виртуальной машиной и выполните команду docker run:

host:~$ docker-machine ssh
[email protected]:~$ docker run -it --privileged ubuntu bash

Обратите внимание, что когда команда запускается следующим образом, захватываются только ранее подключенные USB-устройства. Флаг томов требуется только в том случае, если вы хотите, чтобы он работал с устройствами, подключенными после запуска контейнера. В этом случае вы можете использовать:

[email protected]:~$ docker run -it --privileged -v /dev:/dev ubuntu bash

Обратите внимание, что в некоторых случаях мне приходилось использовать /dev вместо /dev/bus/usb для захвата устройства вроде /dev/sg2. Я могу только предположить, что то же самое будет верно для таких устройств, как /dev/ttyACM0 или /dev/ttyUSB0.

Команды docker run также будут работать с хостом Linux.

Ответ 4

--device работает до тех пор, пока ваше USB-устройство не будет отключено/повторно подключено, а затем перестанет работать. Вы должны использовать cgroup devices.allow обойти это.
Вы можете просто использовать -v /dev:/dev, но это небезопасно, поскольку оно отображает все устройства вашего хоста в контейнер, включая устройства с необработанным диском и так далее. По сути, это позволяет контейнеру получить права root на хосте, что обычно не то, что вам нужно.
Использование подхода cgroups лучше в этом отношении и работает на устройствах, которые добавляются после контейнера при запуске.

Подробности здесь: Доступ к USB-устройствам в Docker без использования --privileged

Его немного сложно вставить, но в двух словах, вам нужно получить основной номер для вашего устройства персонажа и отправить его в cgroup:

189 - это главное число /dev/ttyUSB *, которое вы можете получить с помощью 'ls -l'. В вашей системе он может отличаться от моего:

[email protected]:~# echo 'c 189:* rwm' > /sys/fs/cgroup/devices/docker/$A*/devices.allow  
(A contains the docker containerID)

Затем запустите свой контейнер следующим образом:

docker run -v /dev/bus:/dev/bus:ro -v /dev/serial:/dev/serial:ro -i -t --entrypoint /bin/bash debian:amd64

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

Ответ 5

Другой вариант - настроить udev, который управляет монтированием устройств и какими привилегиями. Полезно, чтобы разрешить доступ без полномочий root к последовательным устройствам. Если у вас есть постоянно подключенные устройства, --device опцией --device. Если у вас есть эфемерные устройства, вот что я использовал:

1. Установите правило Udev

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

Создайте файл с именем /etc/udev/rules.d/99-serial.rules. Добавьте следующую строку в этот файл:

KERNEL=="ttyUSB[0-9]*",MODE="0666"

MODE = "0666" предоставит всем пользователям права на чтение/запись (но не выполнение) для ваших устройств ttyUSB. Это наиболее допустимый вариант, и вы можете ограничить его в зависимости от ваших требований безопасности. Вы можете прочитать об udev, чтобы узнать больше об управлении тем, что происходит, когда устройство подключено к шлюзу Linux.

2. Смонтировать в /dev папку с хоста на контейнер

Последовательные устройства часто бывают эфемерными (их можно подключать и отключать в любое время). Из-за этого мы не можем смонтировать в прямом устройстве или даже в папке /dev/serial, потому что они могут исчезнуть при отключении. Даже если вы подключите их снова и устройство снова появится, это технически файл, отличный от того, что был смонтирован, поэтому Docker его не увидит. По этой причине мы монтируем всю папку /dev с хоста в контейнер. Вы можете сделать это, добавив следующую команду громкости в команду запуска Docker:

-v/dev: /dev

Если ваше устройство постоянно подключено, то использование опции --device или более точного монтирования тома, вероятно, является лучшим вариантом с точки зрения безопасности.

3. Запустите контейнер в привилегированном режиме.

Если вы не использовали опцию --device и монтировали ее во всей папке /dev, вам потребуется запустить контейнер в привилегированном режиме (я собираюсь проверить материал cgroup, упомянутый выше, чтобы увидеть, можно ли это удалить). Вы можете сделать это, добавив следующее в команду запуска Docker:

--privileged

4. Доступ к устройству из папки /dev/serial/by-id

Если ваше устройство может быть подключено и отключено, Linux не гарантирует, что оно всегда будет установлено в одном и том же месте ttyUSBxxx (особенно если у вас несколько устройств). К счастью, Linux автоматически создаст символическую ссылку на устройство в папке /dev/serial/by-id. Файл в этой папке всегда будет называться одинаково.

Это краткое изложение, у меня есть статья в блоге, в которой более подробно.

Ответ 6

Для последних версий Docker этого достаточно:

docker run -ti --privileged ubuntu bash

Это даст доступ ко всем системным ресурсам (например, в /dev)

Ответ 7

Уважаемый Грег/Бхаргав Рао/Мачавити, мы потратили много часов на решение этой проблемы, и слишком много страниц (включая стекопоток) дали ответ, который был не очень полезен для USB-устройств, которые приходят и уходят, когда контейнер работает.
Поэтому я написал сообщение в блоге, чтобы объяснить все уровни этой проблемы и решение для каждого слоя. Там нет рекламы, я ничем не выигрываю, кроме как помогать другим не тратить время на поиск правильного решения. Вы смотрели на страницу?
Теперь, когда вы удалили мое сообщение, кажется, что даже если я отредактирую его, это не имеет значения, так как оно все еще удалено, я, очевидно, не могу связаться с вами, чтобы помочь с тем, как я должен отредактировать его, чтобы восстановить его, и я по-видимому, осталось сделать это новое не по теме сообщение, которое вы, вероятно, тоже удалите.
Учитывая, что мое намерение состояло в том, чтобы действительно помочь другим с этой проблемой, можете ли вы предложить, что я должен делать? Я бы предпочел не вставлять всю веб-страницу в сообщение, если в этом есть смысл, много текста.
Я уже начал редактировать предыдущий пост, пока не понял, что это бессмысленно, так как он был удален.
Пожалуйста, порекомендуйте. Вы можете прокомментировать этот пост о том, как я должен изменить содержание дальше, если версия ниже не в порядке, и я могу удалить этот заголовок после этого.


--device работает до тех пор, пока ваше USB-устройство не будет отключено/повторно подключено, а затем перестанет работать. Вы должны использовать cgroup devices.allow обойти это.

Подробности здесь: http://marc.merlins.org/perso/linux/post_2018-12-20_Accessing-USB-Devices-In-Docker-ttyUSB0-dev-bus-usb--for-fastboot-adb_-without-using- privileged.html

Его немного сложно вставить, но в двух словах, вам нужно получить главный номер для вашего устройства персонажа и отправить его в cgroup:
root @server: ~ # echo 'c 189: * rwm'>/sys/fs/cgroup/devices/docker/$A*/devices.allow
(A содержит идентификатор контейнера Docker)

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