La última vez que lo verifiqué, Docker no tenía ningún medio para dar acceso al contenedor al puerto serie o USB del host . ¿Hay algún truco que permita hacer eso?
139
La última vez que lo verifiqué, Docker no tenía ningún medio para dar acceso al contenedor al puerto serie o USB del host . ¿Hay algún truco que permita hacer eso?
Hay un par de opciones. Puede usar el --device
indicador que puede usar para acceder a dispositivos USB sin --privileged
modo:
docker run -t -i --device=/dev/ttyUSB0 ubuntu bash
Alternativamente, suponiendo que su dispositivo USB esté disponible con controladores funcionando, etc. en el host /dev/bus/usb
, puede montarlo en el contenedor utilizando el modo privilegiado y la opción de volúmenes . Por ejemplo:
docker run -t -i --privileged -v /dev/bus/usb:/dev/bus/usb ubuntu bash
Tenga en cuenta que, como su nombre lo indica, --privileged
es inseguro y debe manejarse con cuidado.
Con las versiones actuales de Docker, puede usar la
--device
bandera para lograr lo que desea, sin necesidad de dar acceso a todos los dispositivos USB.Por ejemplo, si desea que solo sea
/dev/ttyUSB0
accesible dentro de su contenedor Docker, puede hacer algo como:fuente
--device
bandera, ¿cómo determino cuál/dev/<device>
es el dispositivo Android asociado en la máquina host, especialmente cuando uso Docker Quickstart Terminal (VirtualBox Host) para Windows o Mac?--device
funciona hasta que su dispositivo USB se desenchufe / vuelva a enchufar y luego deje de funcionar. Tienes que usar dispositivos cgroup. Para evitarlo .Podría usarlo,
-v /dev:/dev
pero eso no es seguro, ya que asigna todos los dispositivos desde su host al contenedor, incluidos los dispositivos de disco sin formato, etc. Básicamente, esto permite que el contenedor obtenga root en el host, que generalmente no es lo que desea.El uso del enfoque cgroups es mejor en ese sentido y funciona en dispositivos que se agregan después del contenedor como se inició.
Vea los detalles aquí: Acceso a dispositivos USB en Docker sin usar --privileged
Es un poco difícil de pegar, pero en pocas palabras, debes obtener el número principal de tu dispositivo de personaje y enviarlo a cgroup:
189 es el número principal de / dev / ttyUSB *, que puede obtener con 'ls -l'. Puede ser diferente en su sistema que en el mío:
Luego, inicie su contenedor de esta manera:
sin hacer esto, cualquier dispositivo que se haya enchufado o reiniciado nuevamente después de que se inicie el contenedor, obtendrá una nueva ID de bus y no se permitirá el acceso al contenedor.
fuente
189
debe reemplazarse.devices.allow
Puede encontrar una descripción de qué enviar aquí: kernel.org/doc/Documentation/cgroup-v1/devices.txtQuería extender las respuestas ya dadas para incluir soporte para dispositivos conectados dinámicamente que no se capturan
/dev/bus/usb
y cómo hacer que esto funcione cuando se usa un host de Windows junto con la máquina virtual boot2docker.Si está trabajando con Windows, deberá agregar cualquier regla USB para los dispositivos a los que desea que Docker acceda dentro del administrador de VirtualBox. Para hacer esto, puede detener la VM ejecutando:
Abra el VirtualBox Manager y agregue soporte USB con filtros según sea necesario.
Inicie la máquina virtual boot2docker:
Dado que los dispositivos USB están conectados a la máquina virtual boot2docker, los comandos deben ejecutarse desde esa máquina. Abra una terminal con la VM y ejecute el comando docker run:
Tenga en cuenta que cuando el comando se ejecuta de esta manera, solo se capturarán los dispositivos USB conectados anteriormente. El indicador de volúmenes solo es necesario si desea que esto funcione con dispositivos conectados después de que se inicie el contenedor. En ese caso, puede usar:
Tenga en cuenta que tuve que usar en
/dev
lugar de/dev/bus/usb
en algunos casos para capturar un dispositivo como/dev/sg2
. Solo puedo suponer que lo mismo sería cierto para dispositivos como/dev/ttyACM0
o/dev/ttyUSB0
.Los comandos de ejecución de Docker también funcionarán con un host Linux.
fuente
Otra opción es ajustar udev, que controla cómo se montan los dispositivos y con qué privilegios. Útil para permitir el acceso no root a dispositivos seriales. Si tiene dispositivos conectados permanentemente, la
--device
opción es la mejor opción. Si tiene dispositivos efímeros, esto es lo que he estado usando:1. Establecer la regla de udev
De forma predeterminada, los dispositivos en serie se montan para que solo los usuarios root puedan acceder al dispositivo. Necesitamos agregar una regla udev para que sean legibles por usuarios no root.
Cree un archivo llamado /etc/udev/rules.d/99-serial.rules. Agregue la siguiente línea a ese archivo:
KERNEL=="ttyUSB[0-9]*",MODE="0666"
MODE = "0666" dará a todos los usuarios permisos de lectura / escritura (pero no ejecución) para sus dispositivos ttyUSB. Esta es la opción más permisiva, y es posible que desee restringir esto aún más según sus requisitos de seguridad. Puede leer en udev para obtener más información sobre cómo controlar lo que sucede cuando un dispositivo se conecta a una puerta de enlace Linux.
2. Montar en la carpeta / dev del host al contenedor
Los dispositivos en serie a menudo son efímeros (se pueden conectar y desconectar en cualquier momento). Debido a esto, no podemos montar en el dispositivo directo o incluso en la carpeta / dev / serial, porque pueden desaparecer cuando se desconectan las cosas. Incluso si los vuelve a enchufar y el dispositivo vuelve a aparecer, técnicamente es un archivo diferente al que estaba montado, por lo que Docker no lo verá. Por esta razón, montamos toda la carpeta / dev desde el host al contenedor. Puede hacer esto agregando el siguiente comando de volumen a su comando de ejecución Docker:
-v /dev:/dev
Si su dispositivo está conectado permanentemente, entonces usar la opción --device o un montaje de volumen más específico es probablemente una mejor opción desde una perspectiva de seguridad.
3. Ejecute el contenedor en modo privilegiado
Si no usó la opción --device y se montó en toda la carpeta / dev, se le pedirá que ejecute el contenedor en modo privilegiado (voy a revisar las cosas de cgroup mencionadas anteriormente para ver si esto se puede eliminar ) Puede hacer esto agregando lo siguiente a su comando de ejecución Docker:
--privileged
4. Acceda al dispositivo desde la carpeta / dev / serial / by-id
Si su dispositivo se puede conectar y desconectar, Linux no garantiza que siempre se montará en la misma ubicación ttyUSBxxx (especialmente si tiene varios dispositivos). Afortunadamente, Linux creará un enlace simbólico automáticamente al dispositivo en la carpeta / dev / serial / by-id. El archivo en esta carpeta siempre se llamará igual.
Este es el resumen rápido, tengo un artículo de blog que entra en más detalles.
fuente
Es difícil para nosotros vincular un dispositivo USB específico a un contenedor acoplable que también es específico. Como puede ver, la forma recomendada de lograr es:
Unirá todos los dispositivos a este contenedor. No es seguro Todos los contenedores fueron otorgados para operarlos todos.
Otra forma es vincular dispositivos por devpath. Puede verse así:
o
--device
(mejor, noprivileged
):Mucho más seguro. Pero en realidad es difícil saber cuál es el devpath de un dispositivo específico.
He escrito este repositorio para resolver este problema.
https://github.com/williamfzc/usb2container
Después de implementar este servidor, puede obtener fácilmente toda la información de los dispositivos conectados a través de la solicitud HTTP:
y obten:
y atarlos a sus contenedores. Por ejemplo, puede ver que el DEVNAME de este dispositivo es
/dev/bus/usb/001/120
:Tal vez te ayude.
fuente
Con las últimas versiones de Docker, esto es suficiente:
Le dará acceso a todos los recursos del sistema (en / dev por ejemplo)
fuente
Además de las respuestas anteriores, para aquellos que desean una forma rápida de usar un dispositivo USB externo (HDD, unidad flash) que funcione dentro de la ventana acoplable y no utilicen el modo privilegiado:
Encuentre el devpath a su dispositivo en el host:
Puede reconocer su unidad por su capacidad de la lista con bastante facilidad. Copie esta ruta (para el siguiente ejemplo es
/dev/sda2
).Monta este devpath (preferible a
/media
):Luego puede usar esto como un parámetro para
docker run
gustar:o en docker componer en volúmenes:
Y ahora, cuando corres e ingresas a tu contenedor, deberías poder acceder a la unidad dentro del contenedor en
/media/<mount folder name>
DESCARGO DE RESPONSABILIDAD:
fuente
Si desea acceder dinámicamente a dispositivos USB que se pueden enchufar mientras el contenedor acoplable ya se está ejecutando, por ejemplo, acceda a una cámara web USB recién conectada en / dev / video0, puede agregar una regla cgroup al iniciar el contenedor. Esta opción no necesita un contenedor privilegiado y solo permite el acceso a tipos específicos de hardware.
Paso 1
Marque el número principal del dispositivo del tipo de dispositivo que desea agregar. Puede buscarlo en la documentación del kernel de Linux . O puede verificarlo para su dispositivo. Por ejemplo, para verificar el número principal del dispositivo para una cámara web conectada a / dev / video0, puede hacer una
ls -la /dev/video0
. Esto resulta en algo como:Donde el primer número (81) es el número principal del dispositivo. Algunos números principales de dispositivos comunes:
Paso 2
Agregue reglas cuando inicie el contenedor acoplable:
--device-cgroup-rule='c major_number:* rmw'
regla para cada tipo de dispositivo al que desee acceder-v /run/udev:/run/udev:ro
-v /dev:/dev
Envolver
Entonces, para agregar todas las cámaras web usb y dispositivos serial2usb a su contenedor docker, haga lo siguiente:
fuente