마지막으로 확인한 Docker는 컨테이너에 호스트 직렬 또는 USB 포트에 대한 액세스 권한을 부여 할 수단이 없었습니다 . 그렇게 할 수있는 트릭이 있습니까?
마지막으로 확인한 Docker는 컨테이너에 호스트 직렬 또는 USB 포트에 대한 액세스 권한을 부여 할 수단이 없었습니다 . 그렇게 할 수있는 트릭이 있습니까?
답변:
몇 가지 옵션이 있습니다. 모드를 --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
인 불안 및 취급시주의해야한다.
Docker의 현재 버전에서는 --device
플래그를 사용하여 모든 USB 장치에 액세스하지 않고도 원하는 것을 얻을 수 있습니다.
예를 들어 /dev/ttyUSB0
Docker 컨테이너 내 에서만 액세스 할 수 있도록 하려면 다음과 같이하십시오.
docker run -t -i --device=/dev/ttyUSB0 ubuntu bash
--device
플래그를 사용하여 /dev/<device>
특히 Windows 또는 Mac 용 Docker Quickstart Terminal (VirtualBox Host)을 사용할 때 호스트 시스템의 관련 Android 장치를 어떻게 결정 합니까?
--device
USB 장치의 플러그를 뽑았다가 다시 꽂아서 작동을 멈출 때까지 작동합니다. cgroup 장치 를 사용해야 합니다 .
그냥 사용할 수는 -v /dev:/dev
있지만 원시 디스크 장치 등을 포함하여 호스트의 모든 장치를 컨테이너에 매핑하므로 안전하지 않습니다. 기본적으로 이것은 컨테이너가 호스트에서 루트를 얻도록 허용합니다. 일반적으로 원하는 것은 아닙니다.
cgroups 접근 방식을 사용하는 것이 그 점에서 더 좋으며 컨테이너가 시작된 후에 추가되는 장치에서 작동합니다.
여기에서 자세한 내용을 참조하십시오 : 액세스 USB 장치에서 고정 표시기 --privileged 사용하지 않고
붙여 넣기가 약간 어렵지만 간단히 말해서 캐릭터 장치의 주요 번호를 가져 와서 cgroup에 보내야합니다.
189는 'ls -l'로 얻을 수있는 / dev / ttyUSB *의 주요 수입니다. 시스템과 내 시스템이 다를 수 있습니다.
root@server:~# 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
이 작업을 수행하지 않으면 컨테이너가 시작된 후 새로 연결되거나 재부팅되는 장치가 새 버스 ID를 가져오고 컨테이너에서 액세스 할 수 없습니다.
189
교체해야 할 것을 명확히하면 더 나은 답을 얻을 수 있습니다. 보낼 내용에 대한 설명은 devices.allow
여기에서 찾을 수 있습니다 : kernel.org/doc/Documentation/cgroup-v1/devices.txt
나는 캡처되지 않은 동적으로 연결된 장치에 대한 지원 /dev/bus/usb
과 boot2docker VM과 함께 Windows 호스트를 사용할 때이 작업을 수행하는 방법을 포함하기 위해 이미 주어진 답변을 확장하고 싶었습니다 .
Windows로 작업하는 경우 Docker가 VirtualBox 관리자 내에서 액세스하려는 장치에 대한 USB 규칙을 추가해야합니다. 이렇게하려면 다음을 실행하여 VM을 중지 할 수 있습니다.
host:~$ docker-machine stop default
VirtualBox Manager를 열고 필요에 따라 필터를 사용하여 USB 지원을 추가하십시오.
boot2docker VM을 시작하십시오.
host:~$ docker-machine start default
USB 장치가 boot2docker VM에 연결되어 있으므로 해당 시스템에서 명령을 실행해야합니다. VM으로 터미널을 열고 docker run 명령을 실행하십시오.
host:~$ docker-machine ssh
docker@default:~$ docker run -it --privileged ubuntu bash
명령이 이와 같이 실행되면 이전에 연결된 USB 장치 만 캡처됩니다. 볼륨 플래그는 컨테이너가 시작된 후 연결된 장치에서이 기능을 사용하려는 경우에만 필요합니다. 이 경우 다음을 사용할 수 있습니다.
docker@default:~$ docker run -it --privileged -v /dev:/dev ubuntu bash
참고, 내가 사용했다 /dev
대신 /dev/bus/usb
같은 장치를 캡처하는 경우에 /dev/sg2
. 난 단지 같은 같은 장치에 대해 사실이 될 것이라고 가정 할 수있다 /dev/ttyACM0
나 /dev/ttyUSB0
.
docker run 명령은 Linux 호스트에서도 작동합니다.
또 다른 옵션은 udev를 조정하여 장치를 마운트하는 방법과 권한을 제어하는 것입니다. 직렬 장치에 루트가 아닌 액세스를 허용하는 데 유용합니다. 영구적으로 장치를 연결 한 경우 --device
옵션이 가장 좋습니다. 임시 장치가있는 경우 다음과 같이 사용합니다.
기본적으로 직렬 장치는 루트 사용자 만 장치에 액세스 할 수 있도록 마운트됩니다. 루트가 아닌 사용자가 읽을 수 있도록 udev 규칙을 추가해야합니다.
/etc/udev/rules.d/99-serial.rules라는 파일을 작성하십시오. 해당 파일에 다음 줄을 추가하십시오.
KERNEL=="ttyUSB[0-9]*",MODE="0666"
MODE = "0666"은 모든 사용자에게 ttyUSB 장치에 대한 읽기 / 쓰기 (실행은 아님) 권한을 부여합니다. 가장 허용 가능한 옵션이며 보안 요구 사항에 따라 더 제한 할 수 있습니다. 장치가 Linux 게이트웨이에 연결될 때 발생하는 상황을 제어하는 방법에 대한 자세한 내용은 udev를 참조하십시오.
직렬 장치는 종종 일시적입니다 (언제든지 연결하거나 분리 할 수 있음). 이로 인해 직접 장치 또는 / dev / serial 폴더에 마운트 할 수 없습니다. 플러그를 뽑으면 사라질 수 있기 때문입니다. 다시 연결해도 장치가 다시 표시 되더라도 기술적으로 마운트 된 파일과 다른 파일이므로 Docker에서 볼 수 없습니다. 이러한 이유로 전체 / dev 폴더를 호스트에서 컨테이너로 마운트합니다. Docker run 명령에 다음 volume 명령을 추가하여이 작업을 수행 할 수 있습니다.
-v /dev:/dev
장치가 영구적으로 연결된 경우 --device 옵션 또는보다 구체적인 볼륨 마운트를 사용하는 것이 보안 측면에서 더 나은 옵션 일 수 있습니다.
--device 옵션을 사용하지 않고 전체 / dev 폴더에 마운트 한 경우 컨테이너 권한 모드를 실행해야합니다 (위에서 언급 한 cgroup 항목을 확인하여 제거 할 수 있는지 확인합니다). ). Docker run 명령에 다음을 추가하여이를 수행 할 수 있습니다.
--privileged
장치를 연결 및 분리 할 수있는 경우 Linux는 항상 동일한 ttyUSBxxx 위치 (특히 여러 장치가있는 경우)에 마운트되도록 보장하지 않습니다. 다행히 리눅스는 / dev / serial / by-id 폴더에있는 장치에 자동으로 심볼릭 링크를 만듭니다. 이 폴더의 파일 이름은 항상 동일합니다.
이것은 빠른 요약 입니다. 자세한 내용을 다루는 블로그 기사 가 있습니다.
특정 USB 장치를 도커 컨테이너에 바인딩하는 것도 어렵습니다. 보다시피, 권장되는 달성 방법은 다음과 같습니다.
docker run -t -i --privileged -v /dev/bus/usb:/dev/bus/usb ubuntu bash
모든 장치를이 컨테이너에 바인딩합니다. 안전하지 않습니다. 모든 컨테이너는 모든 컨테이너를 작동하도록 허가되었습니다.
다른 방법은 devpath로 장치를 바인딩하는 것입니다. 다음과 같이 보일 수 있습니다.
docker run -t -i --privileged -v /dev/bus/usb/001/002:/dev/bus/usb/001/002 ubuntu bash
또는 --device
(더 나은, 아니오 privileged
) :
docker run -t -i --device /dev/bus/usb/001/002 ubuntu bash
훨씬 더 안전합니다. 그러나 실제로는 특정 장치의 경로가 무엇인지 알기가 어렵습니다.
이 문제를 해결하기 위해이 레포를 작성했습니다.
https://github.com/williamfzc/usb2container
이 서버를 배포 한 후 HTTP 요청을 통해 연결된 모든 장치 정보를 쉽게 얻을 수 있습니다.
curl 127.0.0.1:9410/api/device
그리고 얻다:
{
"/devices/pci0000:00/0000:00:14.0/usb1/1-13": {
"ACTION": "add",
"DEVPATH": "/devices/pci0000:00/0000:00:14.0/usb1/1-13",
"DEVTYPE": "usb_device",
"DRIVER": "usb",
"ID_BUS": "usb",
"ID_FOR_SEAT": "xxxxx",
"ID_MODEL": "xxxxx",
"ID_MODEL_ID": "xxxxx",
"ID_PATH": "xxxxx",
"ID_PATH_TAG": "xxxxx",
"ID_REVISION": "xxxxx",
"ID_SERIAL": "xxxxx",
"ID_SERIAL_SHORT": "xxxxx",
"ID_USB_INTERFACES": "xxxxx",
"ID_VENDOR": "xxxxx",
"ID_VENDOR_ENC": "xxxxx",
"ID_VENDOR_FROM_DATABASE": "",
"ID_VENDOR_ID": "xxxxx",
"INTERFACE": "",
"MAJOR": "189",
"MINOR": "119",
"MODALIAS": "",
"PRODUCT": "xxxxx",
"SEQNUM": "xxxxx",
"SUBSYSTEM": "usb",
"TAGS": "",
"TYPE": "0/0/0",
"USEC_INITIALIZED": "xxxxx",
"adb_user": "",
"_empty": false,
"DEVNAME": "/dev/bus/usb/001/120",
"BUSNUM": "001",
"DEVNUM": "120",
"ID_MODEL_ENC": "xxxxx"
},
...
}
용기에 묶습니다 예를 들어이 장치의 DEVNAME이 다음과 같이 표시됩니다 /dev/bus/usb/001/120
.
docker run -t -i --device /dev/bus/usb/001/120 ubuntu bash
아마 도움이 될 것입니다.
최신 버전의 도커로 충분합니다.
docker run -ti --privileged ubuntu bash
모든 시스템 리소스에 액세스 할 수 있습니다 (예 : / dev)
고정 모드를 사용 하지 않고 도커 내부에서 작동하는 외부 USB 장치 (HDD, 플래시 드라이브)를 빠르게 사용하려는 사람들을 위해 위의 답변에 추가 하십시오.
호스트에서 장치에 대한 devpath를 찾으십시오.
sudo fdisk -l
목록에서 드라이브 용량에 따라 드라이브를 쉽게 인식 할 수 있습니다. 이 경로를 복사하십시오 (다음 예에서는 /dev/sda2
).
Disque /dev/sda2 : 554,5 Go, 57151488 octets, 111624 secteurs
Unités : secteur de 1 × 512 = 512 octets
Taille de secteur (logique / physique) : 512 octets / 512 octets
taille d'E/S (minimale / optimale) : 512 octets / 512 octets
이 devpath를 마운트하십시오 ( /media
).
sudo mount <drive path> /media/<mount folder name>
그런 다음 이것을 원하는 매개 변수로 사용할 수 있습니다 docker run
.
docker run -it -v /media/<mount folder name>:/media/<mount folder name>
또는 docker에서 볼륨 아래로 작성하십시오.
services:
whatevermyserviceis:
volumes:
- /media/<mount folder name>:/media/<mount folder name>
이제 컨테이너를 실행하고 들어가면 컨테이너 내부의 드라이브에 액세스 할 수 있어야합니다. /media/<mount folder name>
부인 성명:
도커 컨테이너가 이미 실행중인 동안 연결할 수있는 USB 장치에 동적으로 액세스하려면 (예 : / dev / video0에서 방금 연결된 USB 웹캠에 액세스) 컨테이너를 시작할 때 cgroup 규칙을 추가 할 수 있습니다. 이 옵션은-전용 컨테이너가 필요하지 않으며 특정 유형의 하드웨어에만 액세스 할 수 있습니다.
추가하려는 장치 유형의 장치 주 번호를 확인하십시오. 리눅스 커널 문서 에서 찾아 볼 수있다 . 또는 장치를 확인할 수 있습니다. 예를 들어 / dev / video0에 연결된 웹캠의 장치 주 번호를 확인하려면을 수행 할 수 있습니다 ls -la /dev/video0
. 결과는 다음과 같습니다.
crw-rw----+ 1 root video 81, 0 Jul 6 10:22 /dev/video0
첫 번째 숫자 (81)는 장치 주 번호입니다. 일반적인 장치 주요 번호 :
도커 컨테이너를 시작할 때 규칙을 추가하십시오.
--device-cgroup-rule='c major_number:* rmw'
액세스하려는 모든 유형의 장치에 대한 규칙 추가-v /run/udev:/run/udev:ro
-v /dev:/dev
따라서 모든 USB 웹캠 및 serial2usb 장치를 docker 컨테이너에 추가하려면 다음을 수행하십시오.
docker run -it -v /dev:/dev --device-cgroup-rule='c 188:* rmw' --device-cgroup-rule='c 81:* rmw' ubuntu bash