Docker - bir ana bilgisayar USB veya seri cihaza erişim sağlamanın bir yolu mu?


Yanıtlar:


194

Birkaç seçenek var. Sen kullanabilirsiniz --devicekullanımı olmadan erişim USB cihazları için kullanabilecekleri bayrağı --privilegedmodu:

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

Alternatif olarak, USB cihazınızın ana bilgisayarda çalışan sürücüler vb. İle mevcut olduğunu varsayarsak /dev/bus/usb, bunu ayrıcalıklı modu ve hacimler seçeneğini kullanarak konteynere monte edebilirsiniz . Örneğin:

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

Adından da anlaşılacağı gibi --privileged, güvenli değildir ve dikkatli kullanılmalıdır.


4
-V - imtiyazına gerek yok zaten tüm cihazlara erişim anlamına geliyor
Sanat

12
Windows docker istemcisi için böyle bir mekanizma var mı?
Pascal

Bu çözümü kullanarak, bir docker kapsayıcısındaki aygıtları görmüyorum ... İşte, stackoverflow.com/questions/37213812 sorunumun ayrıntıları . Herhangi bir yardım için teşekkür ederiz! Teşekkürler.
kashesandr

1
Docker zaten çalıştıktan sonra USB cihazı bağlıysa yine de çalışmaz.
Franklin Dattein

Yani, lsusb listeleyebilmesine rağmen cihazı / tty / USBX altında eşlemiyor.
Franklin Dattein

78

Docker'ın mevcut sürümleriyle, --devicetüm USB cihazlarına erişim izni vermeden bayrağı istediğiniz şeyi elde etmek için kullanabilirsiniz .

Örneğin, yalnızca /dev/ttyUSB0Docker kapsayıcısında erişilebilir olmasını istiyorsanız, aşağıdakine benzer bir şey yapabilirsiniz:

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

3
cihazın şu anda bir simge bağlantısı olamayacağını unutmayın. github.com/docker/docker/issues/13840
wligtenberg

6
--devicebayrağını kullanarak /dev/<device>, özellikle Windows veya Mac için Docker Quickstart Terminal'i (VirtualBox Host) kullanırken, ana makinedeki ilişkili Android cihazın hangisi olduğunu nasıl belirleyebilirim ?
DanCat

1
Cihazınızın adı hiçbir zaman değişmezse bu iyi çalışır. Ancak, / dev / bus / usb içindeki aygıtları kullanan dinamik bir şey kullanıyorsanız, bu işlem çalışmaz çünkü fişi takıp çıkarırken aygıt adı değişir. Bunun yerine yukarıdaki -v (hacimler) çözümüne ihtiyacınız olacak.
Brad Grissom

1
@DanCat udev kuralları, cihazınızın statik bir yola bağlanmasını sağlayabilir
C. Reed

1
Neden kimse sadece bir usb cihaza erişim ile ilgilensin? USB cihazlarının qnd bağlantısı kesilmiş olması ve uygulamaların çalışması sırasında yapılması gerekir. USB SATA ya da başka bir şey değil, bir şeyin her zaman orada olmasını bekleyemezsiniz ... Ve insanların sadece tek seferler için docker aracılığıyla uygulamaları başlattıklarını ve usb cihazlarının bağlantısı kesilir kesilmez çıktıklarını düşünmüyorum, değil mi? Daha çok hizmet tipi uygulamalar gibi düşünürdüm, tek çalışma kavanozları değil ... Ama teşekkürler, gerçekten, bu çok sınırlı senaryonun uygun olacağı bazılarına yardımcı olabilir
Arturas M

17

--deviceUSB cihazınız fişi çekilinceye / fişi çekilinceye kadar çalışır ve daha sonra çalışmayı durdurur. Cgroup cihazlarını kullanmak zorundasınız .
Sadece kullanabilirsiniz, -v /dev:/devancak ham disk aygıtları vb. Temel olarak bu, konteynerin ana bilgisayar üzerinde kök kazanmasına izin verir, bu genellikle istediğiniz şey değildir.
Cgroups yaklaşımını kullanmak bu açıdan daha iyidir ve kaptan sonra başlatıldıktan sonra eklenen cihazlarda çalışır.

Ayrıntıları buradan görebilirsiniz: USB Aygıtlarına Docker'da --privileged kullanmadan erişme

Yapıştırmak biraz zor, ama kısaca, karakter cihazınız için büyük numarayı almanız ve bunu gruba göndermeniz gerekiyor:

189, 'ls -l' ile alabileceğiniz en büyük / dev / ttyUSB * sayısıdır. Sisteminizde benimkinden farklı olabilir:

root@server:~# echo 'c 189:* rwm' > /sys/fs/cgroup/devices/docker/$A*/devices.allow  
(A contains the docker containerID)

Ardından kabınızı şu şekilde başlatın:

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

bunu yapmazsanız, kap başlatıldıktan sonra yeni takılan veya yeniden başlatılan herhangi bir aygıt yeni bir veri yolu kimliği alır ve kapta erişimine izin verilmez.


7
Bunu -1 yapan kişilere, lütfen yardım edin ve nelerin iyileştirilmesini istediğinizi söyleyin. Bu sayfayı, yaptığımız soruna çarpan başkalarına yardım etmek için yazdım. Ben de paylaşmak ve stackoverflow da millet yardım etmeye çalışıyorum kapalı olduğunu söyleyerek biraz dürüst olacağım: - /
Marc Merlin

Cevabımı okursanız, '-v / dev: / dev' birimini eklemenin dinamik olarak takılan cihazlara erişim vereceğini göreceksiniz.
rppilot

5
rrpilot: -v / dev: / dev size / dev / sda ve kapsayıcıdaki root kullanıcısına göstermek istemediğiniz diğer şeyleri içeren tüm / dev öğelerini verir. Başka bir deyişle, çözümünüz işe yarıyor, ancak güvensiz. Benimki bu problemin üstesinden geliyor. Bunu belirtmek için cevabımı düzenleyeceğim.
Marc Merlin

1
Yanıt, büyük sayının nasıl alınacağını göstererek ve 189bunun değiştirilmesi gerektiğini açıklayarak daha iyi yapılabilir. Nelerin gönderileceğine ilişkin bir açıklama devices.allowburada bulunabilir: kernel.org/doc/Documentation/cgroup-v1/devices.txt
Craig Younkins

1
Docker'ın bunu biraz daha basitleştiren yeni bir özelliği var: "--device-cgroup-rule" ( docs.docker.com/engine/reference/commandline/create/… )
tianon

14

Ben zaten yakalanmayan dinamik olarak bağlı cihazlar için destek dahil etmek için verilen cevapları uzatmak /dev/bus/usbve boot2docker VM ile birlikte bir Windows ana bilgisayar kullanırken bu çalışmayı nasıl almak istedim.

Windows ile çalışıyorsanız, Docker'ın VirtualBox yöneticisi içinden erişmesini istediğiniz cihazlar için herhangi bir USB kuralı eklemeniz gerekir. Bunu yapmak için VM'yi çalıştırarak durdurabilirsiniz:

host:~$ docker-machine stop default

VirtualBox Manager'ı açın ve gerektiği gibi filtrelerle USB desteği ekleyin.

Boot2docker VM'sini başlatın:

host:~$ docker-machine start default

USB aygıtları boot2docker VM'sine bağlandığından, komutların o makineden çalıştırılması gerekir. VM ile bir terminal açın ve docker run komutunu çalıştırın:

host:~$ docker-machine ssh
docker@default:~$ docker run -it --privileged ubuntu bash

Komut bu şekilde çalıştırıldığında, yalnızca önceden bağlanmış USB aygıtlarının yakalanacağını unutmayın. Birimler bayrağı yalnızca bunun, kapsayıcı başlatıldıktan sonra bağlı aygıtlarla çalışmasını istiyorsanız gereklidir. Bu durumda şunları kullanabilirsiniz:

docker@default:~$ docker run -it --privileged -v /dev:/dev ubuntu bash

Not, bazı durumlarda /devbunun /dev/bus/usbgibi bir cihazı yakalamak için kullanmak zorunda kaldım /dev/sg2. Aynı şeyin /dev/ttyACM0veya gibi cihazlar için geçerli olacağını varsayabilirim /dev/ttyUSB0.

Docker çalıştırma komutları bir Linux ana bilgisayarıyla da çalışacaktır.


Bunun yerine / dev: / dev montajında ​​iyi bir nokta. Bu, diğer cihazları yakalama konusunda daha fazla esneklik sağlar ve ayrıca dinamik öğeye yardımcı olur.
kotakotakota

ayrıca ana makinenizin güvenliğini ve yalıtımını da tehlikeye atar.
Exadra37

@ Exadra37 Olur ... ve eğer uygulamanızda önemliyse, bunu kullanmamalısınız. Bununla birlikte, umursamadığınız ve izolasyonu için docker'ı kullanmadığınız bazı uygulamalar olduğunu not etmek önemlidir. Benim özel durumumda, Windows'ta paketlenmiş bir Linux uygulaması çalıştırabilirsiniz.
rrpilot

3

Başka bir seçenek, cihazların nasıl monte edildiğini ve hangi ayrıcalıklarla denetlendiğini udev'i ayarlamaktır. Seri cihazlara root olmayan erişime izin vermek için kullanışlıdır. Cihazları kalıcı olarak bağladıysanız, --deviceseçenek en iyi yoldur. Geçici aygıtlarınız varsa, kullandığım şey şudur:

1. udev kuralını ayarlayın

Varsayılan olarak, seri aygıtlar aygıta yalnızca kök kullanıcıların erişebileceği şekilde bağlanmıştır. Kök olmayan kullanıcılar tarafından okunabilmesi için bir udev kuralı eklememiz gerekir.

/Etc/udev/rules.d/99-serial.rules adlı bir dosya oluşturun. Bu dosyaya aşağıdaki satırı ekleyin:

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

MODE = "0666", tüm kullanıcılara ttyUSB aygıtlarınız için okuma / yazma (yürütme değil) izinleri verir. Bu en uygun seçenektir ve güvenlik gereksinimlerinize bağlı olarak bunu daha fazla kısıtlamak isteyebilirsiniz. Bir aygıt Linux ağ geçidine takıldığında ne olacağını kontrol etme hakkında daha fazla bilgi edinmek için udev'de okuyabilirsiniz.

2. Ana bilgisayardan konteynere / dev klasörünü ekleyin

Seri cihazlar genellikle kısa ömürlüdür (herhangi bir zamanda takılabilir ve çıkarılabilir). Bu nedenle, doğrudan cihaza veya / dev / seri klasörüne bağlanamayız, çünkü işler çıkarıldığında bunlar kaybolabilir. Bunları tekrar taksanız ve cihaz tekrar görünse bile, teknik olarak takılı olandan farklı bir dosyadır, bu nedenle Docker bunu görmez. Bu nedenle, / dev klasörünün tamamını ana bilgisayardan konteynere bağlarız. Docker çalıştırma komutunuza aşağıdaki ses komutu ekleyerek bunu yapabilirsiniz:

-v /dev:/dev

Cihazınız kalıcı olarak bağlıysa, --device seçeneğini veya daha spesifik bir ses düzeyi montajını kullanmak, güvenlik açısından muhtemelen daha iyi bir seçenektir.

3. Kapsayıcıyı ayrıcalıklı modda çalıştırın

--Device seçeneğini kullanmadıysanız ve tüm / dev klasörüne monte ettiyseniz, kapsayıcı ayrıcalıklı modda çalıştırmanız istenir (bunun kaldırılıp kaldırılamayacağını görmek için yukarıda belirtilen grup öğelerini kontrol edeceğim. ). Docker çalıştırma komutunuza aşağıdakileri ekleyerek bunu yapabilirsiniz:

--privileged

4. Cihaza / dev / serial / by-id klasöründen erişin

Cihazınız takılıp çıkarılabilirse, Linux her zaman aynı ttyUSBxxx konumuna monte edileceğini garanti etmez (özellikle birden fazla cihazınız varsa). Neyse ki, Linux / dev / serial / by-id klasöründeki aygıta otomatik olarak bir sembolik bağlantı yapacak. Bu klasördeki dosya her zaman aynı şekilde adlandırılacaktır.

Bu hızlı özet, daha fazla ayrıntıya giren bir blog makalem var .


2

Belirli bir USB cihazını, aynı zamanda belirli bir docker konteynerine bağlamak bizim için zor. Gördüğünüz gibi, ulaşmanın önerilen yolu:

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

Tüm cihazları bu kaba bağlar. Güvensiz. Her konteynerin hepsini işletmesi için izin verildi.

Başka bir yol, aygıtları devpath ile bağlamaktır. Şuna benzeyebilir:

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

veya --device(daha iyisi, hayır privileged):

docker run -t -i --device /dev/bus/usb/001/002 ubuntu bash

Daha güvenli. Ancak aslında belirli bir cihazın geliştirmenin ne olduğunu bilmek zordur.

Bu sorunu çözmek için bu depoyu yazdım.

https://github.com/williamfzc/usb2container

Bu sunucuyu dağıttıktan sonra, bağlı tüm cihazların bilgilerini HTTP isteği yoluyla kolayca alabilirsiniz:

curl 127.0.0.1:9410/api/device

ve Al:

{
    "/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"
    },
    ...
}

ve kaplarınıza bağlayın. Örneğin, bu cihazın DEVNAME'inin /dev/bus/usb/001/120:

docker run -t -i --device /dev/bus/usb/001/120 ubuntu bash

Belki yardımcı olacaktır.


0

Docker'ın en son sürümlerinde bu yeterlidir:

docker run -ti --privileged ubuntu bash

Tüm sistem kaynaklarına erişim sağlar (örneğin / dev'de)


2
priviledged güvenlik için kullanmak için korkunç bir seçenektir, evet olsa da işe yarıyor.
Marc Merlin

2
Arduino gibi şeyleri programlamak için kullanılırsa bu çözüm iyidir
Jose Cabrera Zuniga

0

İç liman işçisi çalışma ve harici bir USB aygıtı (HDD, flash sürücü) kullanmak için hızlı bir yol isteyenler için yukarıdaki cevapları, ekleme değil priviledged modunu kullanarak:

Cihazdaki ana makinedeki geliştirmeyi bulun:

sudo fdisk -l

Sürücünüzü listeden kolayca kapasitesi ile tanıyabilirsiniz. Bu yolu kopyalayın (aşağıdaki örnek için /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

Bu geliştiriciyi bağlayın (tercih edilir /media):

sudo mount <drive path> /media/<mount folder name>

Daha sonra bunu docker runbeğenmek için bir param olarak kullanabilirsiniz:

docker run -it -v /media/<mount folder name>:/media/<mount folder name>

veya docker'da birimler altında oluştur:

services:
  whatevermyserviceis:
    volumes:
      - /media/<mount folder name>:/media/<mount folder name>

Ve şimdi konteynırınızı çalıştırıp girdiğinizde, konteynerin içindeki sürücüye şu adresten erişebilmelisiniz: /media/<mount folder name>

YASAL UYARI:

  1. Bu muhtemelen web kamerası vb. Gibi seri aygıtlar için çalışmaz. Bunu sadece USB depolama sürücüleri için test ettim.
  2. Aygıtları düzenli olarak yeniden bağlamanız ve bağlantısını kesmeniz gerekirse, bu yöntem can sıkıcı olacaktır ve montaj yolunu sıfırlayıp kapsayıcıyı yeniden başlatmadığınız sürece de işe yaramaz.
  3. Dokümanlarda belirtildiği gibi docker 17.06 + kullandım

0

Bağlantı istasyonu kapsayıcısı çalışırken takılı olan USB aygıtlarına dinamik olarak erişmek istiyorsanız, örneğin / dev / video0'da yeni bağlanmış bir USB web kamerasına erişin, kapsayıcıyı başlatırken bir grup grubu kuralı ekleyebilirsiniz. Bu seçenek - ayrıcalıklı bir kapsayıcıya ihtiyaç duymaz ve yalnızca belirli donanım türlerine erişime izin verir.

Aşama 1

Eklemek istediğiniz cihazın türünün büyük sayısını kontrol edin. İçeri açın bakın Linux çekirdeği belgelerinde . Veya cihazınız için kontrol edebilirsiniz. Örneğin, / dev / video0'a bağlı bir web kamerasının cihaz ana numarasını kontrol etmek için bir ls -la /dev/video0. Bu şöyle bir şeyle sonuçlanır:

crw-rw----+ 1 root video 81, 0 Jul  6 10:22 /dev/video0

İlk sayı (81) cihazın ana numarasıdır. Bazı yaygın cihaz ana numaraları:

  • 81: usb web kameraları
  • 188: USB - Seri Dönüştürücüler

Adım 2

Docker kapsayıcısını başlattığınızda kural ekleyin:

  • --device-cgroup-rule='c major_number:* rmw'Erişmek istediğiniz her cihaz türü için bir kural ekleyin
  • Docker kapsayıcılarının USB aygıtlarınızla daha fazla bilgi alabilmesi için udev bilgilerine erişim ekleyin -v /run/udev:/run/udev:ro
  • / Dev birimini ile docker konteynerinize eşleyin -v /dev:/dev

Sarmak

Docker kabınıza tüm usb web kameralarını ve serial2usb cihazlarını eklemek için şunları yapın:

docker run -it -v /dev:/dev --device-cgroup-rule='c 188:* rmw' --device-cgroup-rule='c 81:* rmw' ubuntu bash
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.