Terakhir kali saya memeriksa, Docker tidak memiliki sarana untuk memberikan akses kontainer ke serial host atau port USB . Apakah ada trik yang memungkinkan melakukan itu?
Terakhir kali saya memeriksa, Docker tidak memiliki sarana untuk memberikan akses kontainer ke serial host atau port USB . Apakah ada trik yang memungkinkan melakukan itu?
Jawaban:
Ada beberapa opsi. Anda dapat menggunakan --devicebendera yang dapat digunakan untuk mengakses perangkat USB tanpa --privilegedmode:
docker run -t -i --device=/dev/ttyUSB0 ubuntu bash
Atau, dengan asumsi perangkat USB Anda tersedia dengan driver yang berfungsi, dll. Pada host di /dev/bus/usb, Anda dapat memasang ini di wadah menggunakan mode hak istimewa dan opsi volume . Sebagai contoh:
docker run -t -i --privileged -v /dev/bus/usb:/dev/bus/usb ubuntu bash
Perhatikan bahwa seperti namanya, --privilegedadalah tidak aman dan harus ditangani dengan hati-hati.
Dengan versi Docker saat ini, Anda dapat menggunakan --deviceflag untuk mencapai apa yang Anda inginkan, tanpa perlu memberikan akses ke semua perangkat USB.
Misalnya, jika Anda ingin membuatnya hanya /dev/ttyUSB0dapat diakses di dalam container Docker Anda, Anda dapat melakukan sesuatu seperti:
docker run -t -i --device=/dev/ttyUSB0 ubuntu bash
--devicebendera, bagaimana cara menentukan /dev/<device>perangkat Android yang terkait di mesin host, terutama saat menggunakan Terminal Quickstart Docker (VirtualBox Host) untuk Windows atau Mac?
--devicebekerja sampai perangkat USB Anda dicabut / dicolokkan dan kemudian berhenti bekerja. Anda harus menggunakan perangkat cgroup. Izinkan untuk menyiasatinya.
Anda bisa saja menggunakan -v /dev:/devtapi itu tidak aman karena memetakan semua perangkat dari host Anda ke dalam wadah, termasuk perangkat disk mentah dan sebagainya. Pada dasarnya ini memungkinkan container untuk mendapatkan root pada host, yang biasanya bukan yang Anda inginkan.
Menggunakan pendekatan cgroups lebih baik dalam hal itu dan berfungsi pada perangkat yang ditambahkan setelah penampung saat dimulai.
Lihat detailnya di sini: Mengakses Perangkat USB Di Docker tanpa menggunakan --privileged
Agak sulit untuk menempelkannya, tetapi secara singkat, Anda perlu mendapatkan nomor mayor untuk perangkat karakter Anda dan mengirimkannya ke cgroup:
189 adalah angka utama dari / dev / ttyUSB *, yang bisa Anda dapatkan dengan 'ls -l'. Ini mungkin berbeda di sistem Anda dari pada milik saya:
root@server:~# echo 'c 189:* rwm' > /sys/fs/cgroup/devices/docker/$A*/devices.allow
(A contains the docker containerID)
Kemudian mulai wadah Anda seperti ini:
docker run -v /dev/bus:/dev/bus:ro -v /dev/serial:/dev/serial:ro -i -t --entrypoint /bin/bash debian:amd64
tanpa melakukan ini, perangkat yang baru dicolokkan atau di-boot ulang setelah penampung dimulai, akan mendapatkan ID bus baru dan tidak akan diizinkan akses di penampung.
189harus diganti. Penjelasan tentang apa yang harus dikirim devices.allowdapat ditemukan di sini: kernel.org/doc/Documentation/cgroup-v1/devices.txt
Saya ingin memperluas jawaban yang sudah diberikan untuk menyertakan dukungan untuk perangkat yang terhubung secara dinamis yang tidak ditangkap dengan /dev/bus/usbdan cara membuatnya berfungsi saat menggunakan host Windows bersama dengan VM boot2docker.
Jika Anda bekerja dengan Windows, Anda harus menambahkan aturan USB apa pun untuk perangkat yang Anda ingin akses Docker dalam manajer VirtualBox. Untuk melakukan ini, Anda dapat menghentikan VM dengan menjalankan:
host:~$ docker-machine stop default
Buka VirtualBox Manager dan tambahkan dukungan USB dengan filter sesuai kebutuhan.
Mulai VM boot2docker:
host:~$ docker-machine start default
Karena perangkat USB terhubung ke VM boot2docker, perintah harus dijalankan dari mesin itu. Buka terminal dengan VM dan jalankan perintah jalankan buruh pelabuhan:
host:~$ docker-machine ssh
docker@default:~$ docker run -it --privileged ubuntu bash
Catatan, ketika perintah dijalankan seperti ini, maka hanya perangkat USB yang terhubung sebelumnya yang akan ditangkap. Bendera volume hanya diperlukan jika Anda ingin ini bekerja dengan perangkat yang terhubung setelah penampung dimulai. Dalam hal ini, Anda dapat menggunakan:
docker@default:~$ docker run -it --privileged -v /dev:/dev ubuntu bash
Catatan, saya harus menggunakan /devalih-alih /dev/bus/usbdalam beberapa kasus untuk menangkap perangkat seperti /dev/sg2. Saya hanya dapat berasumsi bahwa hal yang sama berlaku untuk perangkat seperti /dev/ttyACM0atau /dev/ttyUSB0.
Perintah menjalankan buruh pelabuhan akan bekerja dengan host Linux juga.
Jika Anda ingin mengakses perangkat USB secara dinamis yang dapat dicolokkan saat penampung buruh pelabuhan sudah berjalan, misalnya mengakses webcam usb yang baru saja terpasang di / dev / video0, Anda dapat menambahkan aturan cgroup saat memulai penampung. Opsi ini tidak memerlukan kontainer --privileged dan hanya mengizinkan akses ke jenis perangkat keras tertentu.
Periksa nomor utama perangkat dari jenis perangkat yang ingin Anda tambahkan. Anda dapat mencarinya di dokumentasi kernel linux . Atau Anda dapat memeriksanya untuk perangkat Anda. Misalnya untuk memeriksa nomor utama perangkat untuk webcam yang terhubung ke / dev / video0, Anda dapat melakukan ls -la /dev/video0. Ini menghasilkan sesuatu seperti:
crw-rw----+ 1 root video 81, 0 Jul 6 10:22 /dev/video0
Dimana angka pertama (81) adalah angka utama perangkat. Beberapa nomor utama perangkat umum:
Tambahkan aturan saat Anda memulai container buruh pelabuhan:
--device-cgroup-rule='c major_number:* rmw'aturan untuk setiap jenis perangkat yang ingin Anda akses-v /run/udev:/run/udev:ro-v /dev:/devJadi untuk menambahkan semua webcam usb dan perangkat serial2usb ke container docker Anda, lakukan:
docker run -it -v /dev:/dev --device-cgroup-rule='c 188:* rmw' --device-cgroup-rule='c 81:* rmw' ubuntu bash
Pilihan lainnya adalah menyesuaikan udev, yang mengontrol bagaimana perangkat dipasang dan dengan hak istimewa apa. Berguna untuk mengizinkan akses non-root ke perangkat serial. Jika Anda memiliki perangkat yang terpasang secara permanen, --deviceopsinya adalah cara terbaik untuk pergi. Jika Anda memiliki perangkat singkat, inilah yang telah saya gunakan:
Secara default, perangkat serial dipasang sehingga hanya pengguna root yang dapat mengakses perangkat. Kita perlu menambahkan aturan udev agar dapat dibaca oleh pengguna non-root.
Buat file bernama /etc/udev/rules.d/99-serial.rules. Tambahkan baris berikut ke file itu:
KERNEL=="ttyUSB[0-9]*",MODE="0666"
MODE = "0666" akan memberikan izin baca / tulis (tetapi tidak mengeksekusi) ke perangkat ttyUSB Anda kepada semua pengguna. Ini adalah opsi yang paling permisif, dan Anda mungkin ingin membatasinya lebih lanjut tergantung pada persyaratan keamanan Anda. Anda dapat membaca di udev untuk mempelajari lebih lanjut tentang mengontrol apa yang terjadi ketika perangkat dicolokkan ke gateway Linux.
Perangkat serial sering kali bersifat sementara (dapat dicolokkan dan dicabut setiap saat). Karena itu, kami tidak dapat memasang di perangkat langsung atau bahkan folder / dev / serial, karena folder tersebut dapat hilang ketika ada yang dicabut. Bahkan jika Anda menyambungkannya kembali dan perangkat muncul lagi, secara teknis itu adalah file yang berbeda dari yang dipasang, jadi Docker tidak akan melihatnya. Untuk alasan ini, kami memasang seluruh folder / dev dari host ke container. Anda dapat melakukan ini dengan menambahkan perintah volume berikut ke perintah jalankan Docker Anda:
-v /dev:/dev
Jika perangkat Anda terpasang secara permanen, menggunakan opsi --device atau pemasangan volume yang lebih spesifik kemungkinan merupakan opsi yang lebih baik dari perspektif keamanan.
Jika Anda tidak menggunakan opsi --device dan dipasang di seluruh / dev folder, Anda akan diminta untuk menjalankan kontainer dalam mode privileged (saya akan memeriksa hal-hal cgroup yang disebutkan di atas untuk melihat apakah ini dapat dihapus ). Anda dapat melakukan ini dengan menambahkan yang berikut ini ke perintah jalankan Docker Anda:
--privileged
Jika perangkat Anda dapat dicolokkan dan dicabut, Linux tidak menjamin perangkat akan selalu dipasang di lokasi ttyUSBxxx yang sama (terutama jika Anda memiliki banyak perangkat). Untungnya, Linux akan membuat symlink secara otomatis ke perangkat di folder / dev / serial / by-id. File dalam folder ini akan selalu diberi nama yang sama.
Ini adalah ikhtisar singkat, saya memiliki artikel blog yang menjelaskan lebih detail.
Sulit bagi kami untuk mengikat perangkat USB tertentu ke wadah buruh pelabuhan yang juga spesifik. Seperti yang Anda lihat, cara yang disarankan untuk mencapainya adalah:
docker run -t -i --privileged -v /dev/bus/usb:/dev/bus/usb ubuntu bash
Ini akan mengikat semua perangkat ke wadah ini. Tidak aman. Setiap kontainer diberikan untuk mengoperasikan semuanya.
Cara lain adalah mengikat perangkat dengan devpath. Ini mungkin terlihat seperti:
docker run -t -i --privileged -v /dev/bus/usb/001/002:/dev/bus/usb/001/002 ubuntu bash
atau --device(lebih baik, tidak privileged):
docker run -t -i --device /dev/bus/usb/001/002 ubuntu bash
Jauh lebih aman. Tetapi sebenarnya sulit untuk mengetahui apa itu devpath perangkat tertentu.
Saya telah menulis repo ini untuk mengatasi masalah ini.
https://github.com/williamfzc/usb2container
Setelah menerapkan server ini, Anda dapat dengan mudah mendapatkan semua informasi perangkat yang terhubung melalui permintaan HTTP:
curl 127.0.0.1:9410/api/device
dan dapatkan:
{
"/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"
},
...
}
dan mengikatnya ke wadah Anda. Misalnya, Anda dapat melihat DEVNAME perangkat ini adalah /dev/bus/usb/001/120:
docker run -t -i --device /dev/bus/usb/001/120 ubuntu bash
Mungkin itu akan membantu.
Dengan versi buruh pelabuhan terbaru, ini sudah cukup:
docker run -ti --privileged ubuntu bash
Ini akan memberikan akses ke semua sumber daya sistem (dalam / dev misalnya)
Menambah jawaban di atas, bagi yang ingin cara cepat menggunakan perangkat USB eksternal (HDD, flash drive) yang berfungsi di dalam buruh pelabuhan, dan tidak menggunakan mode priviledged:
Temukan devpath ke perangkat Anda di host:
sudo fdisk -l
Anda dapat mengenali drive Anda berdasarkan kapasitasnya dengan mudah dari daftar. Salin jalur ini (untuk contoh berikut /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
Pasang jalur dev ini (lebih disukai /media):
sudo mount <drive path> /media/<mount folder name>
Anda kemudian dapat menggunakan ini sebagai parameter untuk docker runmenyukai:
docker run -it -v /media/<mount folder name>:/media/<mount folder name>
atau di buruh pelabuhan menulis di bawah volume:
services:
whatevermyserviceis:
volumes:
- /media/<mount folder name>:/media/<mount folder name>
Dan sekarang ketika Anda menjalankan dan memasuki penampung Anda, Anda harus dapat mengakses drive di dalam penampung di /media/<mount folder name>
PENOLAKAN: