Son kontrol ettiğimde, Docker'ın ana seri veya USB bağlantı noktasına konteyner erişimi vermek için hiçbir yolu yoktu . Bunu yapmanıza izin veren bir hile var mı?
Son kontrol ettiğimde, Docker'ın ana seri veya USB bağlantı noktasına konteyner erişimi vermek için hiçbir yolu yoktu . Bunu yapmanıza izin veren bir hile var mı?
Yanıtlar:
Birkaç seçenek var. Sen kullanabilirsiniz --device
kullanımı olmadan erişim USB cihazları için kullanabilecekleri bayrağı --privileged
modu:
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.
Docker'ın mevcut sürümleriyle, --device
tüm USB cihazlarına erişim izni vermeden bayrağı istediğiniz şeyi elde etmek için kullanabilirsiniz .
Örneğin, yalnızca /dev/ttyUSB0
Docker 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
--device
bayrağı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 ?
--device
USB 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:/dev
ancak 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.
189
bunun değiştirilmesi gerektiğini açıklayarak daha iyi yapılabilir. Nelerin gönderileceğine ilişkin bir açıklama devices.allow
burada bulunabilir: kernel.org/doc/Documentation/cgroup-v1/devices.txt
Ben zaten yakalanmayan dinamik olarak bağlı cihazlar için destek dahil etmek için verilen cevapları uzatmak /dev/bus/usb
ve 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 /dev
bunun /dev/bus/usb
gibi bir cihazı yakalamak için kullanmak zorunda kaldım /dev/sg2
. Aynı şeyin /dev/ttyACM0
veya 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.
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, --device
seçenek en iyi yoldur. Geçici aygıtlarınız varsa, kullandığım şey şudur:
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.
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.
--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
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 .
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.
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)
İç 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 run
beğ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:
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.
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ı:
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-v /run/udev:/run/udev:ro
-v /dev:/dev
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